Skip to content

Commit d2903dd

Browse files
committed
pbio/control: Reset completion state between program runs.
The smart coast option introduces a dependency between sequential maneuvers, since the next starting point depends on the previous endpoint. We don't want this dependency to persist when starting a new program or reinitializing the device. This is accomplished by resetting the relevant state when initializing the controller when setting up a servo or drivebase.
1 parent 63e72da commit d2903dd

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

lib/pbio/include/pbio/control.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,18 @@ pbio_error_t pbio_control_settings_set_stall_tolerances(pbio_control_settings_t
102102
int32_t pbio_control_settings_get_max_integrator(pbio_control_settings_t *s);
103103
int32_t pbio_control_get_ref_time(pbio_control_t *ctl, int32_t time_now);
104104

105+
/**
106+
* Resets and initializes the control state. This is called when a device that
107+
* uses this controller is first initialized or when it is disconnected.
108+
*/
109+
void pbio_control_reset(pbio_control_t *ctl);
110+
111+
/**
112+
* Stops (but not resets) the update loop from updating this controller. This
113+
* is normally called when a motor coasts or brakes.
114+
*/
105115
void pbio_control_stop(pbio_control_t *ctl);
116+
106117
pbio_error_t pbio_control_start_angle_control(pbio_control_t *ctl, int32_t time_now, pbio_control_state_t *state, int32_t target_count, int32_t target_rate, pbio_control_on_completion_t on_completion);
107118
pbio_error_t pbio_control_start_relative_angle_control(pbio_control_t *ctl, int32_t time_now, pbio_control_state_t *state, int32_t relative_target_count, int32_t target_rate, pbio_control_on_completion_t on_completion);
108119
pbio_error_t pbio_control_start_timed_control(pbio_control_t *ctl, int32_t time_now, pbio_control_state_t *state, int32_t duration, int32_t target_rate, pbio_control_on_completion_t on_completion);

lib/pbio/src/control.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,26 @@ void pbio_control_update(pbio_control_t *ctl, int32_t time_now, pbio_control_sta
217217
pbio_logger_update(&ctl->log, log_data);
218218
}
219219

220-
220+
// Stops the update loop from updating this controller.
221221
void pbio_control_stop(pbio_control_t *ctl) {
222222
ctl->type = PBIO_CONTROL_NONE;
223223
ctl->on_target = true;
224224
ctl->stalled = false;
225225
}
226226

227+
// Initializes the control state when creating the control object.
228+
void pbio_control_reset(pbio_control_t *ctl) {
229+
230+
// Stop the control loop update.
231+
pbio_control_stop(ctl);
232+
233+
// Reset the previous on-completion state.
234+
ctl->on_completion = PBIO_CONTROL_ON_COMPLETION_COAST;
235+
236+
// The on_completion state is the only persistent setting between
237+
// subsequent maneuvers, so nothing else needs to be reset explicitly.
238+
}
239+
227240
pbio_error_t pbio_control_start_angle_control(pbio_control_t *ctl, int32_t time_now, pbio_control_state_t *state, int32_t target_count, int32_t target_rate, pbio_control_on_completion_t on_completion) {
228241

229242
pbio_error_t err;
@@ -334,10 +347,6 @@ pbio_error_t pbio_control_start_relative_angle_control(pbio_control_t *ctl, int3
334347
// We're close enough, so make the new target relative to the
335348
// endpoint of the last one.
336349
count_start = ctl->trajectory.th3;
337-
338-
// FIXME: We need to clear the on-completion state between program
339-
// to make each program run independent.
340-
341350
} else {
342351
// No special cases apply, so the best we can do is just start from
343352
// the current state.

lib/pbio/src/drivebase.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ pbio_error_t pbio_drivebase_get_drivebase(pbio_drivebase_t **db_address, pbio_se
188188
pbio_parent_set(&right->parent, db, pbio_drivebase_stop_from_servo);
189189

190190
// Stop any existing drivebase controls
191-
pbio_drivebase_stop_drivebase_control(db);
191+
pbio_control_reset(&db->control_distance);
192+
pbio_control_reset(&db->control_heading);
192193

193194
// Drivebase geometry
194195
if (wheel_diameter <= 0 || axle_track <= 0) {

lib/pbio/src/servo.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ void pbio_servo_update_all(void) {
113113
pbio_dcmotor_coast(srv->dcmotor);
114114

115115
// Stop the control state.
116-
pbio_control_stop(&srv->control);
116+
pbio_control_reset(&srv->control);
117117

118118
// Stop higher level controls, such as drive bases.
119119
pbio_parent_stop(&srv->parent, false);
@@ -148,7 +148,7 @@ static pbio_error_t pbio_servo_stop_from_dcmotor(void *servo, bool clear_parent)
148148
// electrically. All we have to do here is stop the control loop,
149149
// so it won't override the dcmotor to do something else.
150150
if (pbio_control_is_active(&srv->control)) {
151-
pbio_control_stop(&srv->control);
151+
pbio_control_reset(&srv->control);
152152

153153
// If we're not clearing the parent, we are done here. We don't want
154154
// to keep calling the drive base stop over and over.
@@ -192,7 +192,7 @@ pbio_error_t pbio_servo_setup(pbio_servo_t *srv, pbio_direction_t direction, fix
192192
pbio_parent_set(&srv->dcmotor->parent, srv, pbio_servo_stop_from_dcmotor);
193193

194194
// Reset state
195-
pbio_control_stop(&srv->control);
195+
pbio_control_reset(&srv->control);
196196

197197
// Get the device type to load relevant settings.
198198
pbio_iodev_type_id_t type_id;

0 commit comments

Comments
 (0)