Skip to content

Commit a0a7760

Browse files
committed
pbio/trajectory: Fix evaluation at t=0 if t1=0.
For short maneuvers, t1 can be 0. If time is also 0, it wouldn't get into the first segment of the trajectory. See pybricks/support#786
1 parent 2454560 commit a0a7760

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

lib/pbio/src/trajectory.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
#define ACCELERATION_MAX (20000)
3535
#define ACCELERATION_MIN (50)
3636
#define ANGLE_ACCEL_MAX (SPEED_MAX * SPEED_MAX / ACCELERATION_MIN * (10 / 2))
37-
#define assert_accel(a) (assert(pbio_int_math_abs((a)) <= ACCELERATION_MAX && pbio_int_math_abs((a)) >= ACCELERATION_MIN))
37+
#define assert_accel_small(a) (assert(pbio_int_math_abs((a)) <= ACCELERATION_MAX))
38+
#define assert_accel_numerator(a) (assert(pbio_int_math_abs((a)) <= ACCELERATION_MAX && pbio_int_math_abs((a)) >= ACCELERATION_MIN))
3839
#define assert_accel_angle(th) (assert(pbio_int_math_abs((th)) <= ANGLE_ACCEL_MAX))
3940

4041
/**
@@ -126,7 +127,7 @@ void pbio_trajectory_make_constant(pbio_trajectory_t *trj, const pbio_trajectory
126127
// Divides speed^2 (ddeg/s)^2 by acceleration (deg/s^2)*2, giving angle (mdeg).
127128
static int32_t div_w2_by_a(int32_t w_end, int32_t w_start, int32_t a) {
128129

129-
assert_accel(a);
130+
assert_accel_numerator(a);
130131
assert_speed(w_end);
131132
assert_speed(w_start);
132133

@@ -136,7 +137,7 @@ static int32_t div_w2_by_a(int32_t w_end, int32_t w_start, int32_t a) {
136137
// Divides speed (ddeg/s) by acceleration (deg/s^2), giving time (s e-4).
137138
static int32_t div_w_by_a(int32_t w, int32_t a) {
138139

139-
assert_accel(a);
140+
assert_accel_numerator(a);
140141
assert_speed_rel(w);
141142

142143
return w * 1000 / a;
@@ -185,7 +186,7 @@ static int32_t mul_w_by_t(int32_t w, int32_t t) {
185186
static int32_t mul_a_by_t(int32_t a, int32_t t) {
186187

187188
assert_time(t);
188-
assert_accel(a);
189+
assert_accel_small(a);
189190
assert_accel_time(t);
190191

191192
return pbio_int_math_mult_then_div(a, t, 1000);
@@ -195,7 +196,7 @@ static int32_t mul_a_by_t(int32_t a, int32_t t) {
195196
static int32_t mul_a_by_t2(int32_t a, int32_t t) {
196197

197198
assert_time(t);
198-
assert_accel(a);
199+
assert_accel_small(a);
199200
assert_accel_time(t);
200201

201202
return mul_w_by_t(mul_a_by_t(a, t), t) / 2;
@@ -205,7 +206,7 @@ static int32_t mul_a_by_t2(int32_t a, int32_t t) {
205206
// angle (mdeg) and acceleration (deg/s^2). Inverse of div_w2_by_a.
206207
static int32_t bind_w0(int32_t w_end, int32_t a, int32_t th) {
207208

208-
assert_accel(a);
209+
assert_accel_small(a);
209210
assert_speed(w_end);
210211
assert((int64_t)pbio_int_math_abs(a) * (int64_t)pbio_int_math_abs(th) < INT32_MAX);
211212

@@ -231,8 +232,8 @@ static int32_t intersect_ramp(int32_t th3, int32_t th0, int32_t a0, int32_t a2)
231232
return th0;
232233
}
233234

234-
assert_accel(a0);
235-
assert_accel(a2);
235+
assert_accel_numerator(a0);
236+
assert_accel_numerator(a2);
236237
assert(a0 != a2);
237238

238239
return th0 + pbio_int_math_mult_then_div(th3 - th0, a2, a2 - a0);
@@ -632,7 +633,7 @@ void pbio_trajectory_get_last_vertex(pbio_trajectory_t *trj, uint32_t time_ref,
632633
// Find which section of the ongoing maneuver we were in, and take
633634
// corresponding segment starting point. Acceleration is undefined but not
634635
// used when synchronizing trajectories, so set to zero.
635-
if (time - trj->t1 < 0) {
636+
if (time - trj->t1 < 0 || (trj->t1 == 0 && time == 0)) {
636637
// Acceleration segment.
637638
pbio_trajectory_offset_start(vertex, &trj->start, 0, 0, trj->w0, 0);
638639
} else if (time - trj->t2 < 0) {
@@ -668,7 +669,7 @@ void pbio_trajectory_get_reference(pbio_trajectory_t *trj, uint32_t time_ref, pb
668669
// Get angle, speed, and acceleration along reference
669670
int32_t th, w, a;
670671

671-
if (time - trj->t1 < 0) {
672+
if (time - trj->t1 < 0 || (trj->t1 == 0 && time == 0)) {
672673
// If we are here, then we are still in the acceleration phase.
673674
// Includes conversion from microseconds to seconds, in two steps to
674675
// avoid overflows and round off errors

0 commit comments

Comments
 (0)