-
Notifications
You must be signed in to change notification settings - Fork 485
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
Various Servo fixes, optional latency compensation parameter #886
Conversation
*/ | ||
Eigen::VectorXd scaleCartesianCommand(const geometry_msgs::msg::TwistStamped& command); | ||
Eigen::VectorXd scaleCartesianTwistToCartesianPositionDelta(const geometry_msgs::msg::TwistStamped& command); |
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.
Renamed this function to be a bit more specific about what it does
moveit_ros/moveit_servo/config/panda_simulated_config_pose_tracking.yaml
Show resolved
Hide resolved
# This is a fudge factor to account for any latency in the system, e.g. network latency or poor low-level | ||
# controller performance. It essentially increases the timestep when calculating the target pose, to move the target | ||
# pose farther away. [seconds] | ||
system_latency_compensation: 0.05 |
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 sorry, but I really dont like "fudge factors". Is there any way the software could compensate for this on its own? Cant we measure/know the publish rate of the arms joint_states?
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 think it's a little more complicated than the publication rate of the arm's joint states, Marq.
Yes, I can probably make this adaptive.
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 sources of latency I can think of are:
- joint_states publication rate
- ROS message transmission. I believe there are 2 message hops
- network latency
- a little bit of processing time
- whatever happens in the ros_control interface
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 changed this comment to be more professional and the parameter was renamed. Now it says:
# This is an optional factor to account for any latency or low-level controller ramp up/ramp down in the system.
# It increases the timestep when calculating the target pose, to move the target pose farther away. [seconds]
target_pose_lookahead_time: 0.05
Re. naming, I looked around to see if there is any name for this technique but I did not find an exact match. A Smith Predictor is similar but not exactly the same. That is strange there's not a better name for it already; I know the UR robots do something like this internally.
I have a branch where I tried to calculate the system latency automatically but TBH it did not work very well yet, so I won't put it in this PR.
@@ -703,9 +693,6 @@ bool ServoCalcs::applyJointUpdate(const Eigen::ArrayXd& delta_theta, sensor_msgs | |||
// Calculate joint velocity | |||
joint_state.velocity[i] = |
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.
Can you please add some debug prints that I can use to prove the velocity calculation we have here is correct (i.e. print this calculation, the actual joint velocity, and the difference between the two)? This still looks wrong because the arm is not moving this entire distance commanded in the amount of time we are giving it. If it did then Servo would cause the arm to jerk from a start/stop state every update.
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.
please see the diagram in the PR description.
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'll work on actually tracking the Cartesian position and using that feedback to suggest a latency parameter.
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 started a branch called "latency monitor" here. It's not ready to merge yet, though.
https://github.com/AndyZe/moveit2/tree/andyz/latency_monitor
50a2424
to
3684cc2
Compare
If you want to publish numbers simply for debugging would it make sense it add https://github.com/pal-robotics/pal_statistics to servo. It has a way of sampling and publishing internal state in a way that should not affect the performance of servo and wouldn't require a separate node. @facontidavide showed me it when I asked about how he would go about plotting something like this. |
2bc5fb5
to
3684cc2
Compare
@AndyZe if the robot were to perform like you are showing with I assume the latency in this system is constant and is included in the update rate. That is if we are running this loop at 500 Hz then it will send 500 commands per second to the robot, not 500 + some offset (i.e. |
@tylerjw I like this suggestion but was thinking it would only be a debugging print statement, meaning you only take the performance hit when you enable it without adding dependencies. |
I think you'd only take a performance hit from pal_statistics if you subscribe to its topic. The real downside is adding yet another dependency. |
We don't need to publish any extra data, though. Everything we need is already published. |
455e979
to
9378a93
Compare
a782e89
to
7d3c71d
Compare
I'm mostly not convinced that adding some fixed value from the parameters is a good long-term solution. I would like to find some way to measure and quantify what this delay is so instead of having a number you can tweak it to try to get the result closer to the velocity you expect you would actually set it from a measured value and achieve the velocities you are requesting. |
I attempted that here. It does not work very well yet and I don't have time/hardware to debug further at the moment. Let me know if you see any issues. https://github.com/AndyZe/moveit2/tree/andyz/latency_monitor At least it is only one parameter to adjust, right? |
Just an observation: many "tracking" systems provided by the big OEMs actually include exactly the kind of twiddle factor @AndyZe proposes here. Line-tracking systems or general IO interfacing with external "triggering devices" would be examples of this. Sometimes even multiple (ie: one for "io delay", another for "processing delay" and yet another for "misc delay"). There can be many possible contributing factors to these kinds of delays, and their combination doesn't always make it possible to express them in a single unit, hence the "twiddle factor" naming. Whether you'd want to implement this by scaling control outputs or in some other way is another discussion of course. |
It is, but it seems like the sort of thing that a user will have to tune and is only valid for their setup (assuming this value can change between computers/setups/network environment). It might even change while executing. |
Have you considered creating feedback from observing changes in joint states from previous commands adjusting the delay to achieve velocities closer to what the user requested? Ideally, this doesn't change that quickly and you could observe the behavior of the robot to determine how much time offset to add in order to achieve the requested velocity (that is assuming it is actually modeled well enough by a single number). |
d6ab8d0
to
49cf72a
Compare
Tyler, I already posted a link a couple message up where I tried something very similar to that on hardware. I only had about an hour to test on hardware but it was not working well at that time so I won't add it to this MR. I think you have lost focus on the bigger picture here. |
The bigger picture is that I'd like to move moveit in the direction of fewer nobs and dials, not more. It is already hard enough to use. User interfaces should express the output intent, not expose nobs like this that have to be tuned. When you expose a nob that has to be tuned your users end up depending on the specific behavior in your library and that makes it much harder to change the behavior for the better without breaking users who have optimized their setups around your nob. It also makes it much more likely someone will misunderstand how to use your nob and create poorer results than if it didn't exist. |
I generally disagree with exposing a nob to tune in the parameters if at all possible. At the same time, this PR is crashing and generating a stack trace in a test on rolling. |
More professional comments.
fb7f097
to
2aea5ea
Compare
c45c426
to
9409d1d
Compare
9409d1d
to
f285c02
Compare
Codecov Report
@@ Coverage Diff @@
## main #886 +/- ##
==========================================
+ Coverage 57.90% 57.93% +0.03%
==========================================
Files 310 310
Lines 26067 26072 +5
==========================================
+ Hits 15092 15102 +10
+ Misses 10975 10970 -5
Continue to review full report at Codecov.
|
Sorry about the crash. It was a silly mistake that's fixed now. You want an auto-tuner that runs in the background and just works perfectly. It sounds nice but here are some reasons that may be more difficult than you realized:
I did set the parameter to zero by default and added validation, making it a bit harder for the user to screw up. |
This pull request is in conflict. Could you fix it @AndyZe? |
Closing in favor of #956 |
These are all relatively minor bug fixes or documentation improvement except "Add optional latency compensation parameter".
The latency comp parameter was very useful in improving a UR5e's path tracking accuracy. @MarqRazz can attest to that.
If the latency comp parameter is not specified, it doesn't change the behavior at all.
Closes #696
Should be merged with #886 so that the changes in motion speed make sense with the tutorial.
I lumped the latency parameter into one number because there are quite a few sources of latency that can be hard to quantify:
@MarqRazz here is a diagram to help understand (one case) where this helps. If there is a net latency of 30 ms (from when the Servo message is published to when the low-level controller executes), it can reduce the path-tracking error quite a bit. Thus the robot's low-level PID output is small --> the robot does not move very fast. In the perfect world where the latency is 0, the path-tracking accuracy will be much larger and the robot would move with the expected speed.
The first green circle is when Servo publishes. The dashed green line represents 30ms of latency. Red is when the low-level controller starts executing. The final purple dot is the end of the control period.
You can see that when latency is present, the difference between (purple-red) is much less.