-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is done planners #1911
Is done planners #1911
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great! I left some small comments that should mostly be quick to address.
@@ -18,5 +18,7 @@ class InterceptPlanner : public PlannerForCommandType<InterceptCommand> { | |||
: PlannerForCommandType<InterceptCommand>("InterceptPlanner"){}; | |||
|
|||
Trajectory plan(const PlanRequest& request) override; | |||
|
|||
[[nodiscard]] bool is_done() const override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should make all of these is_done methods also constexpr. You cannot make virtual functions constexpr in cpp17 which we use right now, but when I switched to cpp20, this change worked. Marking as constexpr offloads all the work to compile time. Since doing this requires changing our cpp version, we can do it in a different pr if you want. I still think it should be done at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little hesitant to introduce large changes to our build system at the moment. I think we should focus on functionality rather than staying on top of the latest C++/ROS/Ubuntu version. Obviously we will have to move at some point but right now a move would prevent us from building a working product. Maybe a GH issue # for later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
referenced in issue #1920
// Dampen is done when the ball is slow-ish, let collect handle actually | ||
// taking possession | ||
// TODO(Kevin): consider making settle + collect one planner | ||
double SETTLE_BALL_SPEED_THRESHOLD = 0.75; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
github actions is complaining about the case style, even though it eventually will be a param.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm. I can fix all the style issues or let the warnings persist. what do you think?
the reason I didn't make any of them into ROS params already is because I don't love our existing custom param server and wanted to experiment with using default ROS params first. but that seemed like its own PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
referenced in clickup card https://app.clickup.com/t/31g2yfy
@@ -22,7 +22,7 @@ PlannerNode::PlannerNode() | |||
robots_planners_.reserve(kNumShells); | |||
for (int i = 0; i < kNumShells; i++) { | |||
auto planner = | |||
std::make_unique<PlannerForRobot>(i, this, &robot_trajectories_, &shared_state_); | |||
std::make_shared<PlannerForRobot>(i, this, &robot_trajectories_, &shared_state_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this need to be a shared pointer now? My understanding is that shared pointers have a lot more overhead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If my understanding is correct, this needed to be shared so I could assign the current_planner_
field to whichever planner is the current planner (see line 128). Let me know if that's incorrect usage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes that's correct. and looking into it a little more, it's not a big deal actually, since these pointers are only created at startup and destroyed on shutdown. And the overhead comes from those activities primarily.
@@ -158,11 +163,26 @@ Trajectory PlannerForRobot::plan_for_robot(const planning::PlanRequest& request) | |||
|
|||
debug_draw_.publish(); | |||
|
|||
// TODO(Kevin): delete this debug print | |||
if (this->is_done()) { | |||
SPDLOG_ERROR("robot {}'s {} is_done", robot_id_, current_planner_->name()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was helpful for reviewing 👍🏽
Co-authored-by: Kasra Alexander Sohrab <[email protected]>
Co-authored-by: Kasra Alexander Sohrab <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I would still make ClickUp cards/issues for the commented todos and small things I mentioned when reviewing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a couple comments about issues that I noticed while testing. They aren't major issues; however, if the suggestions help, it would avoid future problems. Overall, planners are working much better. Steady progress being made :)
@@ -32,7 +32,9 @@ def get_open_point(self, world_state, region: List, centroid) -> np.ndarray: | |||
# line-of-sight calculations | |||
# (LOS is maximized by making dot product of angle between unit vectors as close to 0 as possible) | |||
ball_dir = lambda pos: pos - world_state.ball.pos | |||
ball_dir_norm = lambda pos: ball_dir(pos) / np.linalg.norm(ball_dir(pos)) | |||
ball_dir_norm = lambda pos: ball_dir(pos) / ( | |||
1e-9 + np.linalg.norm(ball_dir(pos)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What difference did this addition make?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the norm of the ball dir vector is exactly 0, this causes a div by 0 error without the + tiny value
trajectory = planner->plan(request); | ||
} | ||
|
||
// If it fails, or if the planner was not used, the trajectory will | ||
// still be empty. Reset the planner. | ||
if (trajectory.empty()) { | ||
current_planner_ = nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that while running sim2play, either blue or yellow would often not move until the last minute. I am assuming that this could be stemming from this section right here. Could you reduce the number of resets from every tick to a range of ticks similar to how seeker is given a new target point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this would work, but it could at least let the robots being the trajectory and let the replanner do its purpose rather than resetting the whole trajectory from null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the current_planner_
var doesn't actually do anything other than store a ptr to the planner selected in the for-loop above (lines 127-130). Notice there that the trajectory is taken directly from one of the planners in the for-loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the replanner resetting from null is because it gets a fresh RobotIntent from gameplay every tick. another reason why we need to overhaul gameplay to use actions instead of a blind gameplay->RobotIntent->planning pipeline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(for clarification, the ptr is only necessary here for the debug prints below, where I need to get the name of whatever planner is saying it's done)
@@ -62,7 +62,7 @@ DEFINE_NS_FLOAT64( | |||
// | |||
// High number indicates that it will always try to choose a point nearest | |||
// to the current robot position | |||
DEFINE_NS_FLOAT64(kPlanningParamModule, collect, ball_speed_approach_direction_cutoff, 0.1, | |||
DEFINE_NS_FLOAT64(kPlanningParamModule, collect, ball_speed_approach_direction_cutoff, 1.0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there a higher chance of us bouncing into the ball if we increase the speed at which we approach for capture?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the relevant lines of code in the collect planner are here. you can see that when the ball speed is < this thresh, the robot will try to go directly at it, while if the speed is > this thresh, the robot will try to serve as a backstop.
what I noticed in my testing is that the robot didn't backstop successfully very often, so I tuned a bunch of params including this and the accel_scale ones below. those changes combined actually led to less bouncing, but it's hard to isolate any of them. if you want, you can make a card that's like "tune capture" but I think a) that's not in the scope of this PR and b) that's not easy to do when gameplay-controlled passing has some timing bugs. I think once ball placement is up (with passing) it will be easier to see, so I decided to wait on tuning this and any other skills
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your explanations make sense. LGTM
Description
Adds is_done methods to each planner, which return true if the planner is done with its job and false otherwise. This sets the groundwork for more advanced planner behavior (e.g. ball placement #1904 ) on the C++ side.
Also tuned the capture skill for ER-force simulator. Did not tune other skills as that would have taken too long.
Associated / Resolved Issue
Resolves # or ClickUp card
Design Documents
None, based the new is_done() methods off of the existing planner logic + gameplay Skill equivalents.
Steps to test
Test Case 1
test_motion_planning.AllBots
(second test_motion_planning play).Expected result: Debug msgs say "robot x's PathTargetPlanner is_done"
Note: other planners have is_done, but are annoying to test because gameplay Skill is_dones override the planner is_dones. (Ask Kevin to provide more clarification if that doesn't make sense.)
Key Files to Review
Gameplay Changes
rj_gameplay/skill/*
- simple tweaks to existing is_dones for better performancerj_gameplay/*
andconfig/
- bugfixes or new motion planning test playnew nearly_equals()
rj_common/*
rj_geometry/*
soccer/src/soccer/planning/instant.hpp
Main Planning is_done changes
soccer/src/soccer/planning/*
Review Checklist
*intentionally left some debug prints to illustrate working behavior, can delete after