RSDK-13382: Velocity Switching Point Search Updates#175
Conversation
tests; refinment of continuos switching point search wip maybe slightly better wipwipwip wip wip more correct continuous switching point search better testing
…20260209-RSDK-13382-velocity-switching-point-search
|
|
||
| // No velocity switching point expected — velocity curve rises, not drops. | ||
| fixture.expectation_observer_->expect_forward_start(arc_length{0.0}, arc_velocity{0.0}) | ||
| .expect_backward_start(std::nullopt, arc_velocity{0.0}, trajectory::switching_point_kind::k_path_end) |
There was a problem hiding this comment.
Should investigate if testing of integration would be improved by a limit hit event when you start start following the vel limit curve.
|
|
||
| fixture.set_waypoints_rad({{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}}); | ||
|
|
||
| fixture.expectation_observer_->expect_forward_start(arc_length{0.0}, arc_velocity{0.0}) |
There was a problem hiding this comment.
how do we know that any bisection happened here? How do we know that the test is giving us the result that we expect?
|
|
||
| // Two velocity escape switching points (one at each joint-1-to-joint-2 turn). | ||
| fixture.expectation_observer_->expect_forward_start(arc_length{0.0}, arc_velocity{0.0}) | ||
| .expect_hit_limit() |
There was a problem hiding this comment.
we should put in the numbers for this test.
as event observations for all these tests.
| // Case 6: Constant velocity curve → no velocity switching point. | ||
| // | ||
| // Straight-line path with uniform velocity limits. The velocity curve is flat, | ||
| // so there is no sign change in Δ(s). Only path-end switching point occurs. |
There was a problem hiding this comment.
remove all unicode.
explain this in claude.md to not use unicode.
| // Evaluate condition 41 (before-side only) first to avoid computing after-side | ||
| // derivatives and acceleration bounds when the before-side already disqualifies. | ||
| phase_plane_slope curve_slope_before{0.0}; | ||
| try { |
There was a problem hiding this comment.
do not use exceptions to try and control flow of control in the functions.
should it return an optional?
| } | ||
| const auto& [s_ddot_min_after, s_ddot_max_after] = *accel_after; | ||
| const auto trajectory_slope_after = s_ddot_min_after / s_dot_max_vel_after; | ||
| const bool condition_42 = opt.epsilon.wrap(trajectory_slope_after) <= opt.epsilon.wrap(curve_slope_after); |
There was a problem hiding this comment.
investigate if it is wise to wrap in epsilon for comparison.
it is not used for acceleration limit curve derivations.
…20260209-RSDK-13382-velocity-switching-point-search
Andrew C. Morrow (acmorrow)
left a comment
There was a problem hiding this comment.
I'm approving this: there are comments, but they are all quite minor. The majority are me pushing back on places where you are doing epsilon wrapped comparisons, so, please do think about those cases.
Please change things as you see fit per these comments. If you want me to take another look I'm happy to do so, and then we should be able to merge today.
| // Returns std::nullopt when Eq. 40 is not evaluable at this geometry (degenerate | ||
| // velocity limit, acceleration limit below velocity limit, singular derivative, | ||
| // or infeasible acceleration bounds). | ||
| [[nodiscard]] std::optional<eq40_result> try_compute_eq40_delta(path::cursor& cursor, arc_length s, const trajectory::options& opt) { |
There was a problem hiding this comment.
I don't think you alter the cursor so it can probably be const&
There was a problem hiding this comment.
How did I miss the seek? Fine as is.
| const auto accel_bounds = compute_acceleration_bounds(q_prime, q_double_prime, s_dot_max_vel, opt.max_acceleration, opt.epsilon); | ||
|
|
||
| const auto trajectory_slope = accel_bounds.s_ddot_min / s_dot_max_vel; | ||
| return eq40_result{.delta = trajectory_slope - curve_slope, .s_dot_max_vel = s_dot_max_vel}; |
There was a problem hiding this comment.
Can probably omit eq40_result here and just return { .delta = but I'm not 100%
There was a problem hiding this comment.
our return type is std::optional<eq40_result>, not re40_result
return {.delta = ... would try to construct a std::optional which does not compile.
| // We can't call `compute_acceleration_bounds` unless this holds; this is a `Divergence 2` | ||
| // type check. | ||
| if (opt.epsilon.wrap(s_dot_max_accel_before) <= opt.epsilon.wrap(s_dot_max_vel_before)) { | ||
| // We can't call compute_acceleration_bounds at s_dot_max_vel if it exceeds s_dot_max_accel, |
There was a problem hiding this comment.
Is it no longer true that this is a "Divergence 2" type check? If it is, I think we should keep the comment.
There was a problem hiding this comment.
updated comment.
| if (condition_41 && condition_42) { | ||
| // Valid discontinuous switching point found | ||
| // Switching velocity is the minimum of velocity limits on both sides | ||
| if (condition_42) { |
There was a problem hiding this comment.
If you have an !if (!condition_41) continue; style above, it'd be maybe more graceful to do the same thing here and then you could reduce the indent of the "valid" case too.
| // Switching velocity is the minimum of velocity limits on both sides | ||
| if (condition_42) { | ||
| // Valid discontinuous switching point found. | ||
| // Switching velocity is the minimum of velocity limits on both sides. |
There was a problem hiding this comment.
Has your work here given you any further clarity on the indicated TODO(RSDK-12848)?
There was a problem hiding this comment.
I think so.
Taking the min is correct in my opinion since the switching point is always the at the smaller of one two since the trajectory needs to be feasible on both sides of the boundary.
I will remove the todo.
| .after_s_dot_max_vel = result->s_dot_max_vel}; | ||
| } | ||
| } | ||
| // When has_previous_delta is false (first evaluable point or after a non-evaluable gap), |
There was a problem hiding this comment.
Recommend a blank line before starting a block comment.
| // not a distance. However, `opt.delta` is configurable and works as a practical | ||
| // starting point for now. | ||
| const auto next_position = std::min(current_position + arc_length{opt.delta.count()}, search_limit); | ||
| if (opt.epsilon.wrap(next_position) == opt.epsilon.wrap(current_position)) { |
There was a problem hiding this comment.
Do you actually need/want the epsilon wrap here? I feel like you want to go all the way out to the limit, not just close to it.
There was a problem hiding this comment.
removed.
| // instance of `Divergence 2` type behavior. | ||
| if (opt.epsilon.wrap(s_dot_max_acc) < opt.epsilon.wrap(s_dot_max_vel)) { | ||
| previous_position = search_cursor.position(); | ||
| const auto mid = positive_side + ((nonpositive_side - positive_side) / 2.0); |
There was a problem hiding this comment.
We have a midpoint function!
|
|
||
| // Update previous position for next iteration | ||
| previous_position = search_cursor.position(); | ||
| if (opt.epsilon.wrap(mid_result->delta) < opt.epsilon.wrap(k_zero_delta)) { |
There was a problem hiding this comment.
Same q re epsilon comparison of slopes.
There was a problem hiding this comment.
no errors detected when epsillon wrapped is removed.
| arc_length search_limit, | ||
| const trajectory::options& opt) { | ||
| auto search_position = cursor.position(); | ||
| while (opt.epsilon.wrap(search_position) < opt.epsilon.wrap(search_limit)) { |
There was a problem hiding this comment.
Another place I'm not sure about epsilon'ing because I think you really do want to go all the way to the limit, not just near it.
There was a problem hiding this comment.
removed epsilon.
i kept them in since it did not break tests and i having them seems more rigourous to me
but now they are removed.
Andrew C. Morrow (acmorrow)
left a comment
There was a problem hiding this comment.
Ship it!
Refactored the original
find_velocity_switching_pointsince it was rather large into sub-functions.Previously it seems that wrt equation 40 we were blatantly looking for when LHS = RHS.
This does not consider two things.
The method of searching for the fulfillment of equations 41 and 42 is largely not changed.
We also had Claude add plenty of tests and asked Claude to validate that the changes made to
trajectory.cppare sane.