Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
4f569f1
add handling for missing ML model files
Jul 20, 2025
8a3494a
Fix ensure_at_home() holding down the Home button.
Mysticial Jul 20, 2025
83419c5
Improve reliability of the Tera Roller.
Mysticial Jul 20, 2025
a6d0dae
Fix Switch 2 type detector again.
Mysticial Jul 21, 2025
a108f84
Suppress date-spam logging.
Mysticial Jul 21, 2025
724a720
Tera Roller: Do extra skips if fresh out of reset.
Mysticial Jul 21, 2025
2990239
Improve fault tolerance of TeraRoller.
Mysticial Jul 22, 2025
dd7f178
add shortcut support to label image program
Jul 22, 2025
d0f8707
add feature to select and delete selected annotation
Jul 22, 2025
fdd8458
Fix logger
pifopi Jul 22, 2025
73f1b57
Merge pull request #645 from pifopi/logger-fix
Mysticial Jul 23, 2025
ba40ebf
BoxFloatOption
Mysticial Jul 23, 2025
5763090
Missed a file.
Mysticial Jul 23, 2025
e97f3a2
fix compile error
Jul 24, 2025
59d73f2
Fix FCE on Switch 2.
Mysticial Jul 24, 2025
68332b0
Merge branch 'main' of https://github.com/PokemonAutomation/Arduino-S…
Mysticial Jul 24, 2025
dd6c20d
Closing update nag shouldn't count as skip version.
Mysticial Jul 24, 2025
4aeccaa
Lots of fixes for Tera Multi-Farmer.
Mysticial Jul 24, 2025
559c349
add prev/next selection buttons
Jul 23, 2025
40c6c0a
fixing UI layout
Jul 24, 2025
e5ef7bf
add custom labels
Jul 24, 2025
eabc444
Preliminary rewrite of Tera Multi-Farmer state machine.
Mysticial Jul 25, 2025
3e04ec3
Fix build.
Mysticial Jul 25, 2025
e2ebfdf
Misc. profiling to help debug poor UI perf with 4 videos.
Mysticial Jul 25, 2025
b58610a
Fix crash when hiding Mask checkbox.
Mysticial Jul 25, 2025
7fcbff3
Cleanup.
Mysticial Jul 25, 2025
e774811
More Tera Multi-Farmer fixes.
Mysticial Jul 25, 2025
32c1ad2
Move stats gathering off the UI thread. Throttle it 10/second.
Mysticial Jul 25, 2025
eb8fffa
Fix the stats order.
Mysticial Jul 25, 2025
0df76da
Add clang on the CI for windows and linux (#625)
pifopi Jul 25, 2025
0a00664
Refactor VideoOverlaySession to use ListenerSet and fix hang on stats.
Mysticial Jul 25, 2025
229c057
Merge branch 'main' of https://github.com/PokemonAutomation/Arduino-S…
Mysticial Jul 25, 2025
164fe16
reorder arguments (#650)
pifopi Jul 25, 2025
6ddb1e6
Fix Tera Multi-Farmer reset recovery.
Mysticial Jul 26, 2025
2c745b8
add dropdown to choose label type
Jul 25, 2025
8106938
move more logic from widget to program
Jul 25, 2025
874590e
add manual input label field
Jul 26, 2025
454c1c0
fix string widget visibility changes
Jul 27, 2025
742119b
fix READ_ONLY for real
Jul 28, 2025
b8fb744
add button to load custom label set, add signal_all_text_changes to s…
Jul 28, 2025
1caa1b5
Fix build.
Mysticial Jul 28, 2025
db6505c
better box selection
Jul 29, 2025
d70725b
Move QCamera off the UI thread.
Mysticial Jul 29, 2025
9494465
writing control points for SAM
Jul 29, 2025
ed2334c
fix box center distance
Jul 29, 2025
9849a42
Fix build.
Mysticial Jul 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions .github/workflows/cpp-ci-serial-programs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,25 @@ jobs:
fail-fast: false
matrix:
os: [windows-2025, macos-13, ubuntu-24.04]
compiler: ['default', 'clang']
qt_version: ['6.9.1']
include:
- qt_version: '6.9.1'
qt_version_major: '6'
qt_modules: 'qtmultimedia qtserialport'
- qt_version: '6.9.1'
qt_version_major: '6'
qt_modules: 'qtmultimedia qtserialport'

- os: 'windows-2025'
compiler: 'clang'
cmake_additional_param: '-T ClangCL'

- os: 'ubuntu-24.04'
compiler: 'clang'
cmake_additional_param: '-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++'

exclude:
- os: 'macos-13'
compiler: 'clang'
# Excluded because macos default toolset is already clang

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -44,7 +58,7 @@ jobs:
cd Arduino-Source/SerialPrograms
mkdir bin
cd bin
cmake .. -DQT_MAJOR:STRING=${{ matrix.qt_version_major }}
cmake .. -DQT_MAJOR:STRING=${{ matrix.qt_version_major }} ${{ matrix.cmake_additional_param }}
cmake --build . --config Release --parallel 10
- name: Copy resources
if: startsWith(matrix.os, 'windows')
Expand All @@ -66,5 +80,5 @@ jobs:
- uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows')
with:
name: Serial Programs for windows (${{ matrix.qt_version }})
name: Serial Programs (os=${{ matrix.os }} - compiler=${{ matrix.compiler }} - qt_version=${{ matrix.qt_version }})
path: Output
5 changes: 0 additions & 5 deletions ClientSource/Connection/MessageLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ void SerialLogger::log(const std::string& msg, Color color){
m_logger.log(msg, color);
}
}
void SerialLogger::log(std::string msg){
if (ok_to_log()){
m_logger.log(msg, COLOR_DARKGREEN);
}
}

bool SerialLogger::ok_to_log(){
WallClock now = current_time();
Expand Down
10 changes: 4 additions & 6 deletions ClientSource/Connection/MessageLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
namespace PokemonAutomation{


class MessageLogger : public MessageSniffer{
class MessageLogger : public Logger, public MessageSniffer{
public:
MessageLogger(bool log_everything = false)
: m_log_everything_owner(log_everything)
Expand All @@ -29,7 +29,6 @@ class MessageLogger : public MessageSniffer{
{}


// virtual void log(std::string msg) override;
virtual void on_send(const BotBaseMessage& message, bool is_retransmit) override;
virtual void on_recv(const BotBaseMessage& message) override;

Expand All @@ -40,13 +39,12 @@ class MessageLogger : public MessageSniffer{



class SerialLogger : public Logger, public MessageLogger{
class SerialLogger : public MessageLogger{
public:
SerialLogger(Logger& logger, bool log_everything);

virtual void log(const char* msg, Color color = Color()) override;
virtual void log(const std::string& msg, Color color = Color()) override;
virtual void log(std::string msg) override;
virtual void log(const char* msg, Color color = COLOR_DARKGREEN) override;
virtual void log(const std::string& msg, Color color = COLOR_DARKGREEN) override;

private:
bool ok_to_log();
Expand Down
1 change: 0 additions & 1 deletion ClientSource/Connection/MessageSniffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ struct BotBaseMessage;

class MessageSniffer{
public:
virtual void log(std::string msg){}
virtual void on_send(const BotBaseMessage& message, bool is_retransmit){}
virtual void on_recv(const BotBaseMessage& message){}
};
Expand Down
32 changes: 16 additions & 16 deletions ClientSource/Connection/PABotBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ void PABotBase::process_ack_request(BotBaseMessage message){

if constexpr (!variable_length){
if (message.body.size() != sizeof(Params)){
m_sniffer->log("Ignoring message with invalid size.");
m_logger.log("Ignoring message with invalid size.");
return;
}
}
Expand All @@ -324,14 +324,14 @@ void PABotBase::process_ack_request(BotBaseMessage message){
WriteSpinLock lg(m_state_lock, "PABotBase::process_ack_request()");

if (m_pending_requests.empty()){
m_sniffer->log("Unexpected request ack message: seqnum = " + std::to_string(seqnum));
m_logger.log("Unexpected request ack message: seqnum = " + std::to_string(seqnum));
return;
}

uint64_t full_seqnum = infer_full_seqnum(m_pending_requests, seqnum);
std::map<uint64_t, PendingRequest>::iterator iter = m_pending_requests.find(full_seqnum);
if (iter == m_pending_requests.end()){
m_sniffer->log("Unexpected request ack message: seqnum = " + std::to_string(seqnum));
m_logger.log("Unexpected request ack message: seqnum = " + std::to_string(seqnum));
return;
}
iter->second.sanitizer.check_usage();
Expand All @@ -357,10 +357,10 @@ void PABotBase::process_ack_request(BotBaseMessage message){
}
return;
case AckState::ACKED:
m_sniffer->log("Duplicate request ack message: seqnum = " + std::to_string(seqnum));
m_logger.log("Duplicate request ack message: seqnum = " + std::to_string(seqnum));
return;
case AckState::FINISHED:
m_sniffer->log("Request ack on command finish: seqnum = " + std::to_string(seqnum));
m_logger.log("Request ack on command finish: seqnum = " + std::to_string(seqnum));
return;
}
}
Expand All @@ -369,7 +369,7 @@ void PABotBase::process_ack_command(BotBaseMessage message){
auto scope_check = m_sanitizer.check_scope();

if (message.body.size() != sizeof(Params)){
m_sniffer->log("Ignoring message with invalid size.");
m_logger.log("Ignoring message with invalid size.");
return;
}
const Params* params = (const Params*)message.body.c_str();
Expand All @@ -378,14 +378,14 @@ void PABotBase::process_ack_command(BotBaseMessage message){
WriteSpinLock lg(m_state_lock, "PABotBase::process_ack_command()");

if (m_pending_commands.empty()){
m_sniffer->log("Unexpected command ack message: seqnum = " + std::to_string(seqnum));
m_logger.log("Unexpected command ack message: seqnum = " + std::to_string(seqnum));
return;
}

uint64_t full_seqnum = infer_full_seqnum(m_pending_commands, seqnum);
auto iter = m_pending_commands.find(full_seqnum);
if (iter == m_pending_commands.end()){
m_sniffer->log("Unexpected command ack message: seqnum = " + std::to_string(seqnum));
m_logger.log("Unexpected command ack message: seqnum = " + std::to_string(seqnum));
return;
}
iter->second.sanitizer.check_usage();
Expand All @@ -399,10 +399,10 @@ void PABotBase::process_ack_command(BotBaseMessage message){
iter->second.ack = std::move(message);
return;
case AckState::ACKED:
m_sniffer->log("Duplicate command ack message: seqnum = " + std::to_string(seqnum));
m_logger.log("Duplicate command ack message: seqnum = " + std::to_string(seqnum));
return;
case AckState::FINISHED:
m_sniffer->log("Command ack on finished command: seqnum = " + std::to_string(seqnum));
m_logger.log("Command ack on finished command: seqnum = " + std::to_string(seqnum));
return;
}
}
Expand All @@ -411,7 +411,7 @@ void PABotBase::process_command_finished(BotBaseMessage message){
auto scope_check = m_sanitizer.check_scope();

if (message.body.size() != sizeof(Params)){
m_sniffer->log("Ignoring message with invalid size.");
m_logger.log("Ignoring message with invalid size.");
return;
}
const Params* params = (const Params*)message.body.c_str();
Expand All @@ -437,7 +437,7 @@ void PABotBase::process_command_finished(BotBaseMessage message){
#endif

if (m_pending_commands.empty()){
m_sniffer->log(
m_logger.log(
"Unexpected command finished message: seqnum = " + std::to_string(seqnum) +
", command_seqnum = " + std::to_string(command_seqnum)
);
Expand All @@ -447,7 +447,7 @@ void PABotBase::process_command_finished(BotBaseMessage message){
uint64_t full_seqnum = infer_full_seqnum(m_pending_commands, command_seqnum);
auto iter = m_pending_commands.find(full_seqnum);
if (iter == m_pending_commands.end()){
m_sniffer->log(
m_logger.log(
"Unexpected command finished message: seqnum = " + std::to_string(seqnum) +
", command_seqnum = " + std::to_string(command_seqnum)
);
Expand All @@ -466,7 +466,7 @@ void PABotBase::process_command_finished(BotBaseMessage message){
m_cv.notify_all();
return;
case AckState::FINISHED:
m_sniffer->log("Duplicate command finish: seqnum = " + std::to_string(seqnum));
m_logger.log("Duplicate command finish: seqnum = " + std::to_string(seqnum));
return;
}
}
Expand Down Expand Up @@ -494,7 +494,7 @@ void PABotBase::on_recv_message(BotBaseMessage message){
return;
case PABB_MSG_ERROR_INVALID_TYPE:{
if (message.body.size() != sizeof(pabb_MsgInfoInvalidType)){
m_sniffer->log("Ignoring message with invalid size.");
m_logger.log("Ignoring message with invalid size.");
return;
}
const pabb_MsgInfoInvalidType* params = (const pabb_MsgInfoInvalidType*)message.body.c_str();
Expand All @@ -509,7 +509,7 @@ void PABotBase::on_recv_message(BotBaseMessage message){
}
case PABB_MSG_ERROR_MISSED_REQUEST:{
if (message.body.size() != sizeof(pabb_MsgInfoMissedRequest)){
m_sniffer->log("Ignoring message with invalid size.");
m_logger.log("Ignoring message with invalid size.");
return;
}
const pabb_MsgInfoMissedRequest* params = (const pabb_MsgInfoMissedRequest*)message.body.c_str();
Expand Down
16 changes: 8 additions & 8 deletions ClientSource/Connection/PABotBaseConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,16 @@ void PABotBaseConnection::push_error_byte(ErrorBatchType type, char byte){
case ErrorBatchType::NO_ERROR_:
break;
case ErrorBatchType::ZERO_BYTES:
m_sniffer->log("Skipped " + std::to_string(m_current_error_batch.size()) + " zero byte(s).");
m_logger.log("Skipped " + std::to_string(m_current_error_batch.size()) + " zero byte(s).");
break;
case ErrorBatchType::FF_BYTES:
m_sniffer->log("Skipped " + std::to_string(m_current_error_batch.size()) + " 0xff byte(s).");
m_logger.log("Skipped " + std::to_string(m_current_error_batch.size()) + " 0xff byte(s).");
break;
case ErrorBatchType::ASCII_BYTES:
m_sniffer->log("Received possible ASCII: " + m_current_error_batch);
m_logger.log("Received possible ASCII: " + m_current_error_batch);
break;
case ErrorBatchType::OTHER:
// m_sniffer->log("Skipped " + std::to_string(m_current_error_batch.size()) + " invalid length byte(s).");
// m_logger.log("Skipped " + std::to_string(m_current_error_batch.size()) + " invalid length byte(s).");
break;
}

Expand All @@ -119,7 +119,7 @@ void PABotBaseConnection::on_recv(const void* data, size_t bytes){
uint8_t length = ~m_recv_buffer[0];

if (m_recv_buffer[0] == 0){
// m_sniffer->log("Skipping zero byte.");
// m_logger.log("Skipping zero byte.");
push_error_byte(ErrorBatchType::ZERO_BYTES, 0);
m_recv_buffer.pop_front();
continue;
Expand All @@ -130,7 +130,7 @@ void PABotBaseConnection::on_recv(const void* data, size_t bytes){
if (length == 0){
push_error_byte(ErrorBatchType::FF_BYTES, ~length);
}else{
m_sniffer->log("Message is too short: bytes = " + std::to_string(length));
m_logger.log("Message is too short: bytes = " + std::to_string(length));
push_error_byte(ErrorBatchType::OTHER, ~length);
}
m_recv_buffer.pop_front();
Expand All @@ -143,7 +143,7 @@ void PABotBaseConnection::on_recv(const void* data, size_t bytes){
// std::string text = ascii < 32
// ? ", ascii = " + std::to_string(ascii)
// : std::string(", char = ") + ascii;
// m_sniffer->log("Message is too long: bytes = " + std::to_string(length) + text);
// m_logger.log("Message is too long: bytes = " + std::to_string(length) + text);
push_error_byte(ErrorBatchType::ASCII_BYTES, ~length);
m_recv_buffer.pop_front();
continue;
Expand All @@ -170,7 +170,7 @@ void PABotBaseConnection::on_recv(const void* data, size_t bytes){
// Compare
// std::cout << checksumA << " / " << checksumE << std::endl;
if (checksumA != checksumE){
m_sniffer->log("Invalid Checksum: bytes = " + std::to_string(length));
m_logger.log("Invalid Checksum: bytes = " + std::to_string(length));
// std::cout << checksumA << " / " << checksumE << std::endl;
// log(message_to_string(message[1], &message[2], length - PABB_PROTOCOL_OVERHEAD));
m_recv_buffer.pop_front();
Expand Down
4 changes: 2 additions & 2 deletions ClientSource/Connection/SerialConnectionWinAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class SerialConnection : public StreamConnection{
throw ConnectionException(nullptr, "Unable to open serial connection (" + name + "). Error = " + std::to_string(error));
}

DCB serial_params{0};
DCB serial_params{};
serial_params.DCBlength = sizeof(serial_params);

if (!GetCommState(m_handle, &serial_params)){
Expand All @@ -67,7 +67,7 @@ class SerialConnection : public StreamConnection{
}

#if 1
COMMTIMEOUTS timeouts{0};
COMMTIMEOUTS timeouts{};
if (!GetCommTimeouts(m_handle, &timeouts)){
DWORD error = GetLastError();
CloseHandle(m_handle);
Expand Down
2 changes: 1 addition & 1 deletion Common/Cpp/CancellableScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CancellableScope : public Cancellable{
public:
virtual ~CancellableScope() override;

virtual bool cancel(std::exception_ptr exception) noexcept override;
virtual bool cancel(std::exception_ptr exception = nullptr) noexcept override;

void wait_for(std::chrono::milliseconds duration);
void wait_until(WallClock stop);
Expand Down
Loading