-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
enabling closed-loop control in spinning #723
Conversation
Codecov Report
@@ Coverage Diff @@
## master #723 +/- ##
==========================================
+ Coverage 24% 30.42% +6.41%
==========================================
Files 233 235 +2
Lines 9359 9426 +67
Branches 2598 3105 +507
==========================================
+ Hits 2247 2868 +621
+ Misses 5481 4576 -905
- Partials 1631 1982 +351
Continue to review full report at Codecov.
|
@SteveMacenski For controlled spin task, I think we want to be able to either spin the robot CW or CCW by some angles based on the user input. For example: spin(-pi) should rotate the robot CCW by 180 degree whereas spin(pi) should rotate the robot CW by 180 degree. |
@mhpanah Agreed, I'd rather not include this in this particular PR since it wasn't able to before. My next steps here were actually going to be to change the |
@SteveMacenski I think we can make this PR similar to the backup one. What do you think of this code snippet below. nav2_tasks::TaskStatus Spin::onRun(const nav2_tasks::SpinCommand::SharedPtr command)
{
double pitch, roll;
tf2::getEulerYPR(command->quaternion, command_yaw_, pitch, roll);
if (!robot_->getOdometry(initial_pose_)) {
RCLCPP_ERROR(node_->get_logger(), "initial robot odom pose is not available.");
return nav2_tasks::TaskStatus::FAILED;
}
tf2::getEulerYPR(initial_pose_, start_yaw_, pitch, roll);
return nav2_tasks::TaskStatus::SUCCEEDED;
}
nav2_tasks::TaskStatus Spin::onCycleUpdate(nav2_tasks::SpinResult & result)
{
TaskStatus status = controlledSpin();
nav2_tasks::SpinResult empty_result;
result = empty_result;
return status;
}
nav2_tasks::TaskStatus Spin::controlledSpin()
{
// Get current robot orientation
auto current_pose = std::make_shared<geometry_msgs::msg::PoseWithCovarianceStamped>();
if (!robot_->getCurrentPose(current_pose)) {
RCLCPP_ERROR(node_->get_logger(), "Current robot pose is not available.");
return TaskStatus::FAILED;
}
const double current_yaw = tf2::getYaw(current_pose->pose.pose.orientation);
const double yaw_diff = start_yaw - current yaw;
geometry_msgs::msg::Twist cmd_vel;
cmd_vel.linear.x = 0.0;
cmd_vel.linear.y = 0.0;
if (yaw_diff >= abs(command_yaw_)) {
cmd_vel.angular.z = 0.0;
robot_->sendVelocity(cmd_vel);
return TaskStatus::SUCCEEDED;
}
// We can send this cmd_vel
// command_yaw_ < 0 ? cmd_vel.angular.z = -0.025 : cmd_vel.angular.z = 0.025;
// But
// In your PR I like it that you dynamically decrease the rotational velocity as it get's closer
// To the goal. So lets try:
double vel = sqrt(2 * rotational_acc_lim_ * yaw_diff);
vel = std::min(std::max(vel, min_rotational_vel_), max_rotational_vel_);
command_yaw_ < 0 ? cmd_vel.angular.z = -vel : cmd_vel.angular.z = vel;
robot_->sendVelocity(cmd_vel);
return TaskStatus::RUNNING;
} This would be a BT for wiggle <SequenceStar name="wiggle">
<Spin theta="180" />
<Spin theta="-360" />
<Spin theta="180" />
</SequenceStar> |
nav2_motion_primitives/include/nav2_motion_primitives/back_up.hpp
Outdated
Show resolved
Hide resolved
@mhpanah I like your snippet, but then aren't you changing the definition of the input Fixed the squared issue. |
@SteveMacenski The command is not current pose. For backup, command is defined in |
Ok, I can handle this then tomorrow 👍 |
Some things to consider (for this or future PRs):
I have other comments about the implementation of the controller but will add those next to the code. In addition, I was also working on a spin controller #599, but put that on-hold before my leave. |
I don't know if sub-trees are a thing in the BT library (e.i. rather than defining a wiggle recovery, we have a spin recovery, and a wiggle tree, that is used by the larger tree). Given the similar overlaps, we could use the spin recovery in the wiggle recovery, but that would not look very clean. @mhpanah recommendation for the tree implementation of a wiggle I thought was very clever |
Yeah, I agree it is clever, however, each BT node involves some ROS action call which I'm not sure if it's good. On the code, the only issue I see here is handling the pi,-pi discontinuity. Not sure what the code will do if the starting orientation is pi and is requested a delta rotation of pi. I think it just stops at the discontinuity. The code is based on ROS1 spin recovery, which always rotates pi, I believe. #599 does some angle wrapping there, also handles both CW & CCW movements. |
Ok, well we can deal with the "wiggle" if we feel its necessary in another PR, nothing about this really covers that, just leaves the opportunity. Let me think about the angle bit and put something together |
@orduno For the requirements, I agree with CW, CCW and speed, multiple turns can be handled with for example @SteveMacenski We are actually still figuring out on how to include simpler BT's into a larger one. But for now within the larger BT that we have, you can add the wiggle by a sequence star node with three children. <SequenceStar name="wiggle">
<Spin theta="180" />
<Spin theta="-360" />
<Spin theta="180" />
</SequenceStar> In the If you like I can add the wiggle later. |
@SteveMacenski - I just noticed you're creating a lot of branches in the repo. Please create branches in your fork instead and do a PR from there. We are trying to keep branches to a minimum. The only ones we should have right now are master, crystal-devel and lifecycle. lifecycle is being used as a temporary staging branch and the plan is to rebase, merge and delete it ASAP. |
@mkhansen-intel will do |
@orduno @mhpanah please review again - added handling of directions and true distances vs. normalized distances. This handles all sets of signed angles 0->180 where the sign of the quaternion rotation defines if its CW or CCW. This limitation does also make it so that then the maximum valid rotation is 180 deg, else it will rotate the complementary angle in the opposite direction, but that's a limitation imposed from the inputs as only a quaternion, not something I can pull out in math without more information given. The quaternion getYaw's are all normalized (-pi, pi]. |
3197142
to
973eab1
Compare
There's a bunch of problems here now that i think about it. I would like to generally just redo this plugin, I'm closing this PR. I'm going to wait until the lifecycle branch lands so that we can merge in the recovery stuff before its worth the refactor necessary. I dont think a quaternion is the right input and more information should be added |
Basic Info
Description of contribution in a few bullet points
Future work that may be required in bullet points