Skip to content

Commit

Permalink
pbio/motor_process: catch up timer if behind
Browse files Browse the repository at this point in the history
This adds an extra check to make sure the motor poll timer hasn't
fallen too far behind.

Before this change, if calling the motor process was blocked for too
long, it would cause the motor contiki process to never yield until the
wall clock caught up. This would also cause motor updates to be called
with a time delta of 0 which probably caused unexpected conditions in
some of the calculations.

We can avoid this by checking to see if we have a condition that would
trigger the unwanted behavior and reset the timer to a larger interval.
This could cause a hiccup in the observer calculations but is a
significant improvement over the alternative.

Fixes: pybricks/support#1035
  • Loading branch information
dlech committed May 2, 2023
1 parent 82794f1 commit de5b341
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

### Fixed
- Fixed stdin containing `0x06` command byte ([support#1052]).
- Fixed motor process causing delays on ev3dev ([support#1035]).

[support#1035]: https://github.com/pybricks/support/issues/1035
[support#1052]: https://github.com/pybricks/support/issues/1052

## [3.3.0b4] - 2023-04-21
Expand Down
2 changes: 1 addition & 1 deletion bricks/ev3dev/pbinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static pthread_t task_caller_thread;
static void *task_caller(void *arg) {
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 2000000;
ts.tv_nsec = 1000000;

while (!stopping_thread) {
MP_THREAD_GIL_ENTER();
Expand Down
14 changes: 13 additions & 1 deletion lib/pbio/src/motor_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,19 @@ PROCESS_THREAD(pbio_motor_process, ev, data) {
// Update servos
pbio_servo_update_all();

// Reset timer to wait for next update
clock_time_t now = clock_time();

// If polling was delayed too long, we need to ensure that the next
// poll is a minimum of 1ms in the future. If we don't, the poll loop
// will not yield until and the next update will be called with a 0 time
// diff which causes issues.
if (now - etimer_start_time(&timer) >= 2 * PBIO_CONFIG_CONTROL_LOOP_TIME_MS) {
timer.timer.start = now - (PBIO_CONFIG_CONTROL_LOOP_TIME_MS - 1);
}

// Reset timer to wait for next update. Using etimer_reset() instead
// of etimer_restart() makes average update period closer to the expected
// PBIO_CONFIG_CONTROL_LOOP_TIME_MS when occasional delays occur.
etimer_reset(&timer);
}

Expand Down

0 comments on commit de5b341

Please sign in to comment.