-
Notifications
You must be signed in to change notification settings - Fork 346
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
[JTC] conceptual issues #697
Comments
Sounds reasonable to me. Let's start with simple fixes, e.g., Many this are much better to understand if you see it in the code and their consequence in the tests. |
Okay for the |
Thanks to the detailed and verbose description.
You mean after activation of the controller? This is a known issue, see the My thoughts about trajectory sampling:
|
@christophfroehlich thanks for looking at my description. I used the wrong term, I did not mean controller activated (because I did not look at the states and output at activation, I looked during update call (logging within update). So I mean after/during first update after the goal was already processed, so when there is a valid trajectory, but it generated no motion (See the example). I was expecting a desired state in the future, exactly like a time+dt would do. for the sampling.
So in the case of a perfect robot, I think one should plan ahead one step AND use that plan-ahead value to compute the PID error as if it was external. A perfect robot should be able to reach the goal in time and have zero tracking error. |
That is not true btw, waitAndCompareState uses the state_msg and is used throughout test_trajectory_controller.cpp |
Hum. My point is not where it is currently used, but to what purpose it is used in the tests. |
I did it partially already, just need more time that I don't have before tonight at best. |
I'm sorry, I haven't read your statement properly. I agree 🙈 |
I discussed this with some colleagues today, and the common opinion is: it depends 😆
Summarized: It is a design decision, and both methods are fine for me if implemented consistently. |
@christophfroehlich Thanks for the time investigating and discussing. You are right I over simplified the problem of tracking error and P/ PI to the academic typical example I remembered. I could have spared myself some ridicule by not talking about PID possibilities as it does not help my point. I wanted mostly to say that a PID that can compensate for the tracking error will result in having a state_if = sampled point at the time of reading the state_if, so also a zero tracking error although it received a reference from sample at time+dt. Your explanation of real life scenario is known to me, and there are delays everywhere. I think in real life there will be little consequences if dt is small indeed. I would like to focus on one of your remark that actually led me here.
The whole problem is there. With sufficiently small deltas dt the CI will pass all the test. But dt had to be 1e-6 to pass the allowed_delta of 0.0011. I tried realistic dt, for instance 1e-3 and tests would fail. Digging deeper with LARGER dt to see stuff happening without too long prints, I obviously uncovered that problem of "final desired point = target point" of the controller sent at final time and hence never reached in time, even in the ideal case. Now I think that the design decision will lead to have to require unrealistic dt update to reach goals within allowed_deltas. This is where consistency is broken in the implementation of JTC + its tests. I really hope to provide a PR with tests modified then (simpler than risking changing the design decision), and that pass with a realistic dt (but should also then work for non realistically large dt because all is perfect in the test.) |
After your discussion here, I am just more convinced that we need T+dt. It was like this in ros_control and everybody were happy. Currently, we try to do work around something that complicates so many things. It is obvious that T+dt will simplify many things, and I am quite certain that some strange issues we are currently encountering with industrial robots may be caused by the current way of calculation. It would be good to have a PR with "T+dt" implementation, so one can actually test this on HW. |
While implementing #696 I faced numerous issues that led me to dig deep into the implementation of JTC to understand why some "intuitive" or let say theoretical expectations I had for a JTC were not met. I did not want to create tons of separate issues as they are mostly linked together.
Disclaimer :
I might have some rusted theoretical knowledge in controllers, so please just point at my mistakes if any and close the issue if this is not an issue.
Problems
dt in update Controller
traj sampling
update()
called at thetime_from_start
of a single trajectory point will generate a desired output that matches the trajectory point.update()
is done , the current read from hardware state (or state_msgs.feedback) that gets evaluated will ALWAYS be the last state read from hardware and so will always be the state before the last update call (even with mirrored cmd/state ifs) and so will never be the desired state when evaluated.allowed deltas
to compensate for the situation and highly depend on how tiny the delay (dt) between 2 calls of update loop (inupdateController
) is, hence variability in CI. Currently the dt is as small as a few microseconds which is unrealistic to a real robot and is variable depending on CPU load.one sees that the test is with the desired state, and not with the current state. Correct. My implementation of the dt and the
clock.now() < end_time
led to no call 6 at 0.25With a call 6 at time 0.25 the
joint_pos_[0]
will be correct, and match0.1
BUT only the previous state of call 5 will be read from hardware and does not match 1.0 awaited at the 0.250 time. So the JTC with a perfect robot did not manage to reach the position on time.
Calling update once more at the exact last point (call 6) lead to other issues probably due to hold position nullifying effort interfaces etc..., did not dig more yet)
The first update of the controller after it was activated does not generate any command, this is also weird.
The desired output at call 4 should be the point to be reached so that at the exact
time_from_start
, with an ideal robot (cmd/state ifs mirrored) the state is reached.How to solve :
The test should work for any dt, and so I dug deeper and found that JTC in ros_controllers samples the trajectory spline for the desired command at time+period when the ROS 2 implementation samples at current time. This means in ROS 2 JTC the desired state is not a "planed-ahead" command but the command that should have occurred at the time of update (so too late already). I think this is theoretically wrong and leads to all sorts of checks that require
allowed-deltas
where the delta in a mirrored robot should be at most coming from float approximation errors.I think the correct way is to sample at time T + period dt to always plan one step ahead. Early test showed good results but not yet fully tested with reduced allowed-delta, and maybe there other consequences of planning ahead.
Tolerance checks
I suppose a solution is to do a mix of the 2 (ROS) worlds. sample at T for the tracking error, sample at T+dt for the desired state to send to the output (and compute the planned error to also generate a command in the PID adapters)
state_msg
used to evaluate internal state of JTCstate_msgs
started to get lost (not transmitted) due to too fast call toupdate
, andpublisher try_lock
failing.state_msg
access that could be null) and alsostate_msgs
is not necessarily the last state (what ever the amount of wait and sping AFTERupdateController
because problem is inupdateController
spin_some
in theupdateController
, etc does not solve the problem, only very very tiny calls toupdateController
might permit to have luckily astate_msg
close enough (because in so many calls to update one of thestate_msg
will go through) to the goals/expected values.state_msg
has expected values, other test seem to use it to read the internal state/last state.@destogl suggested to used
FRIEND_TEST
to access the protected variables and evaluate the expected values with those.Remains the case what to do with state consistency check. Denis suggested to use a
try_lock
andunlock
to check if the publisher is ready for a next call toupdate
, and thenthread sleep
in between. Might work (first trials look promising)time from start of
state_current
Conclusion
I think JTC and its tests can be improved, especially speed and stability of the tests in CI.
I know the code base well now, and did many trials, I am ready to create separate issues and corresponding PR once problems are confirmed and directions to go are known.
The text was updated successfully, but these errors were encountered: