Skip to content

Commit d10193e

Browse files
committed
Change ESP32's timing behavior from periodic ticks to cooldown.
1 parent 022f5ba commit d10193e

15 files changed

+295
-80
lines changed

SerialPrograms/Source/Controllers/Controller.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#ifndef PokemonAutomation_Controllers_Controller_H
88
#define PokemonAutomation_Controllers_Controller_H
99

10-
#include <string>
1110
#include "Common/Compiler.h"
1211
#include "Common/Cpp/AbstractLogger.h"
1312
#include "Common/Cpp/Time.h"
@@ -18,6 +17,7 @@ class QKeyEvent;
1817
namespace PokemonAutomation{
1918

2019
enum class ControllerType;
20+
enum class ControllerPerformanceClass;
2121
class ControllerFeatures;
2222

2323

@@ -44,11 +44,16 @@ class AbstractController{
4444

4545
virtual ControllerType controller_type() const = 0;
4646
virtual const ControllerFeatures& controller_features() const = 0;
47+
virtual ControllerPerformanceClass performance_class() const = 0;
4748

4849
// If the controller is polled at a fixed interval, this is that interval.
4950
// Otherwise, returns zero.
5051
virtual Milliseconds ticksize() const = 0;
5152

53+
// The minimum amount of time between two state reports. This effectively
54+
// limits how quickly you can change states.
55+
virtual Milliseconds cooldown() const = 0;
56+
5257
// Some controllers are imprecise. This returns the variation.
5358
// Zero means "tick precise".
5459
virtual Milliseconds timing_variation() const = 0;

SerialPrograms/Source/Controllers/ControllerTypes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ enum class ControllerFeature{
4646
};
4747

4848

49+
enum class ControllerPerformanceClass{
50+
Unknown,
51+
SerialPABotBase_Wired_125Hz,
52+
SerialPABotBase_Wireless_ESP32,
53+
SysbotBase,
54+
};
55+
4956

5057

5158

SerialPrograms/Source/Controllers/SerialPABotBase/SerialPABotBase_Connection.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ SerialPABotBase_Connection::SerialPABotBase_Connection(
6666
std::string error;
6767
try{
6868
set_status_line0("Connecting...", COLOR_DARKGREEN);
69-
7069
std::unique_ptr<SerialConnection> connection(new SerialConnection(port->systemLocation().toStdString(), PABB_BAUD_RATE));
7170
m_botbase.reset(new PABotBase(m_logger, std::move(connection), nullptr));
7271
}catch (const ConnectionException& e){

SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ void ssf_issue_scroll(
125125
delay*8ms, hold*8ms, cool*8ms
126126
);
127127
}
128+
void ssf_issue_scroll(
129+
ProControllerContext& context,
130+
DpadPosition direction,
131+
Milliseconds delay
132+
){
133+
context->issue_system_scroll(&context, direction, delay, 2*delay, delay);
134+
}
128135
void ssf_issue_scroll(
129136
ProControllerContext& context,
130137
DpadPosition direction,

SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void ssf_press_button(
3838
void ssf_press_button(
3939
ProControllerContext& context,
4040
Button button,
41-
Milliseconds delay, Milliseconds hold = 5*8ms, Milliseconds cool = 3*8ms
41+
Milliseconds delay = 24ms, Milliseconds hold = 48ms, Milliseconds cool = 24ms
4242
);
4343

4444
void ssf_press_dpad(
@@ -49,7 +49,7 @@ void ssf_press_dpad(
4949
void ssf_press_dpad(
5050
ProControllerContext& context,
5151
DpadPosition position,
52-
Milliseconds delay, Milliseconds hold = 5*8ms, Milliseconds cool = 3*8ms
52+
Milliseconds delay, Milliseconds hold = 48ms, Milliseconds cool = 24ms
5353
);
5454

5555

@@ -99,7 +99,12 @@ void ssf_issue_scroll(
9999
void ssf_issue_scroll(
100100
ProControllerContext& context,
101101
DpadPosition direction,
102-
Milliseconds delay, Milliseconds hold = 5*8ms, Milliseconds cool = 3*8ms
102+
Milliseconds delay
103+
);
104+
void ssf_issue_scroll(
105+
ProControllerContext& context,
106+
DpadPosition direction,
107+
Milliseconds delay, Milliseconds hold, Milliseconds cool
103108
);
104109

105110

@@ -116,44 +121,40 @@ void ssf_issue_scroll(
116121
inline void ssf_press_button_ptv(
117122
ProControllerContext& context,
118123
Button button,
119-
Milliseconds delay = 3*8ms,
120-
Milliseconds hold = 5*8ms,
121-
Milliseconds cool = 3*8ms
124+
Milliseconds delay = 24ms,
125+
Milliseconds hold = 48ms,
126+
Milliseconds cool = 24ms
122127
){
123-
ssf_press_button(
124-
context, button,
125-
delay + context->timing_variation(),
126-
hold + context->timing_variation(),
127-
cool + context->timing_variation()
128-
);
128+
Milliseconds tv = context->timing_variation();
129+
if (delay > 0ms) delay += tv;
130+
if (hold > 0ms) hold += tv;
131+
if (cool > 0ms) cool += tv;
132+
ssf_press_button(context, button, delay, hold, cool);
129133
}
130134
inline void ssf_press_dpad_ptv(
131135
ProControllerContext& context,
132136
DpadPosition position,
133-
Milliseconds delay = 3*8ms,
134-
Milliseconds hold = 5*8ms,
135-
Milliseconds cool = 3*8ms
137+
Milliseconds delay = 24ms,
138+
Milliseconds hold = 48ms,
139+
Milliseconds cool = 24ms
136140
){
137-
ssf_press_dpad(
138-
context, position,
139-
delay + context->timing_variation(),
140-
hold + context->timing_variation(),
141-
cool + context->timing_variation()
142-
);
141+
Milliseconds tv = context->timing_variation();
142+
if (delay > 0ms) delay += tv;
143+
if (hold > 0ms) hold += tv;
144+
if (cool > 0ms) cool += tv;
145+
ssf_press_dpad(context, position, delay, hold, cool);
143146
}
144147
inline void ssf_issue_scroll_ptv(
145148
ProControllerContext& context,
146149
DpadPosition direction,
147-
Milliseconds delay = 3*8ms,
148-
Milliseconds hold = 5*8ms,
149-
Milliseconds cool = 3*8ms
150+
Milliseconds delay = 24ms,
151+
Milliseconds hold = 48ms,
152+
Milliseconds cool = 24ms
150153
){
151-
ssf_issue_scroll(
152-
context, direction,
153-
delay + context->timing_variation(),
154-
hold + context->timing_variation(),
155-
cool + context->timing_variation()
156-
);
154+
Milliseconds tv = context->timing_variation();
155+
if (delay > 0ms) delay += tv;
156+
if (hold > 0ms) hold += tv;
157+
ssf_issue_scroll(context, direction, delay, hold, cool);
157158
}
158159

159160

@@ -220,7 +221,7 @@ void ssf_do_nothing (JoyconContext& context, Milliseconds duration);
220221
void ssf_press_button(
221222
JoyconContext& context,
222223
Button button,
223-
Milliseconds delay, Milliseconds hold = 3*15ms, Milliseconds cool = 2*15ms
224+
Milliseconds delay, Milliseconds hold = 48ms, Milliseconds cool = 24ms
224225
);
225226
void ssf_press_joystick(
226227
JoyconContext& context,

SerialPrograms/Source/NintendoSwitch/Controllers/SerialPABotBase/NintendoSwitch_SerialPABotBase_PokkenController.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ class SerialPABotBase_PokkenController final :
4646
virtual const ControllerFeatures& controller_features() const override{
4747
return m_supported_features;
4848
}
49+
virtual ControllerPerformanceClass performance_class() const override{
50+
return ControllerPerformanceClass::SerialPABotBase_Wired_125Hz;
51+
}
4952

5053
virtual Milliseconds ticksize() const override{
5154
return Milliseconds(8);
5255
}
56+
virtual Milliseconds cooldown() const override{
57+
return Milliseconds(8);
58+
}
5359
virtual Milliseconds timing_variation() const override{
5460
return Milliseconds::zero();
5561
}

SerialPrograms/Source/NintendoSwitch/Controllers/SerialPABotBase/NintendoSwitch_SerialPABotBase_WirelessController.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,36 @@ void SerialPABotBase_WirelessController::issue_report(
7272
// This loop can block indefinitely if the command queue is full.
7373
ReverseLockGuard<std::mutex> lg(m_state_lock);
7474

75-
// Divide the controller state into smaller chunks of 255 ticks.
75+
// We will not do any throttling or timing adjustments here. We'll defer
76+
// to the microcontroller to do that for us.
77+
78+
// Divide the controller state into smaller chunks of 65535 milliseconds.
7679
Milliseconds time_left = std::chrono::duration_cast<Milliseconds>(duration);
80+
81+
// time_left = (time_left + 14ms) / 15ms * 15ms;
82+
83+
// time_left = std::max(time_left, 15ms);
7784
while (time_left > Milliseconds::zero()){
78-
Milliseconds current_ms = std::min(time_left, 255 * 15ms);
79-
uint8_t current_ticks = (uint8_t)milliseconds_to_ticks_15ms(current_ms.count());
85+
Milliseconds current = std::min(time_left, 65535ms);
86+
time_left -= current;
87+
88+
#if 0
89+
// Make sure the last block isn't too small.
90+
if (0ms < time_left && time_left < 15ms){
91+
time_left += current;
92+
current = time_left / 2;
93+
time_left -= current;
94+
}
95+
#endif
96+
// cout << "current = " << current.count() << endl;
97+
8098
m_serial->issue_request(
81-
SerialPABotBase::MessageControllerStateButtons(current_ticks * 15, buttons),
99+
SerialPABotBase::MessageControllerStateButtons(
100+
(uint16_t)current.count(),
101+
buttons
102+
),
82103
cancellable
83104
);
84-
time_left -= current_ms;
85105
}
86106
}
87107

SerialPrograms/Source/NintendoSwitch/Controllers/SerialPABotBase/NintendoSwitch_SerialPABotBase_WirelessController.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ class SerialPABotBase_WirelessController : public SerialPABotBase_Controller{
3535
Milliseconds ticksize() const{
3636
return Milliseconds(15);
3737
}
38+
Milliseconds cooldown() const{
39+
return Milliseconds(15);
40+
}
3841
Milliseconds timing_variation() const{
39-
return Milliseconds::zero();
42+
return Milliseconds(0);
4043
}
4144

4245

@@ -55,7 +58,8 @@ class SerialPABotBase_WirelessController : public SerialPABotBase_Controller{
5558
// I suspect the need to offset by 151 from 2048 -> 1897 is Nintendo's
5659
// way to alleviate the joycon drift problem.
5760
const uint16_t min = 1897;
58-
const uint16_t max = 320;
61+
// const uint16_t max = 320;
62+
const uint16_t max = 275; // REMOVE: TODO: Fix the clipping for real.
5963

6064
const double lo = 1 - min / 2048.;
6165
const double hi = 1 - max / 2048.;

SerialPrograms/Source/NintendoSwitch/Controllers/SerialPABotBase/NintendoSwitch_SerialPABotBase_WirelessJoycon.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,16 @@ class SerialPABotBase_WirelessJoycon final :
4242
virtual const ControllerFeatures& controller_features() const override{
4343
return m_supported_features;
4444
}
45+
virtual ControllerPerformanceClass performance_class() const override{
46+
return ControllerPerformanceClass::SerialPABotBase_Wireless_ESP32;
47+
}
4548

4649
virtual Milliseconds ticksize() const override{
4750
return SerialPABotBase_WirelessController::ticksize();
4851
}
52+
virtual Milliseconds cooldown() const override{
53+
return SerialPABotBase_WirelessController::cooldown();
54+
}
4955
virtual Milliseconds timing_variation() const override{
5056
return SerialPABotBase_WirelessController::timing_variation();
5157
}

SerialPrograms/Source/NintendoSwitch/Controllers/SerialPABotBase/NintendoSwitch_SerialPABotBase_WirelessProController.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ void SerialPABotBase_WirelessProController::push_state(const Cancellable* cancel
4545
.vibrator = 0x00,
4646
};
4747

48-
48+
Button all_buttons = BUTTON_NONE;
4949
for (size_t c = 0; c < TOTAL_BUTTONS; c++){
5050
if (!m_buttons[c].is_busy()){
5151
continue;
5252
}
5353
Button button = (Button)((ButtonFlagType)1 << c);
54+
all_buttons |= button;
5455
switch (button){
5556
// Right
5657
case BUTTON_Y: report.button3 |= 1 << 0; break;
@@ -103,6 +104,17 @@ void SerialPABotBase_WirelessProController::push_state(const Cancellable* cancel
103104
}
104105

105106
issue_report(cancellable, report, duration);
107+
108+
#if 0
109+
m_logger.log(
110+
"push_state(): (" + button_to_string(all_buttons) +
111+
"), dpad(" + dpad_to_string(m_dpad.position) +
112+
"), LJ(" + std::to_string(m_left_joystick.x) + "," + std::to_string(m_left_joystick.y) +
113+
"), RJ(" + std::to_string(m_right_joystick.x) + "," + std::to_string(m_right_joystick.y) +
114+
"), hold = " + std::to_string(std::chrono::duration_cast<Milliseconds>(duration).count()) + "ms",
115+
COLOR_DARKGREEN
116+
);
117+
#endif
106118
}
107119

108120

0 commit comments

Comments
 (0)