-
Notifications
You must be signed in to change notification settings - Fork 111
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.
@nnmm The changes look good to me.
Note I have only checked this for correct usage of ROS 2 constructs, namely:
- Publishers
- Subscriptions and callbacks
- Timers
- Parameters
- Spinning/executor
All of the constructs are being used correctly as far as I can see. I have not checked for style, or other forms of code correctness.
: Node("vehicle_cmd_gate"), is_engaged_(false), is_emergency_(false) | ||
{ | ||
rclcpp::QoS durable_qos{1}; | ||
durable_qos.transient_local(); |
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.
Just to be 100% clear, you do want to have a history depth of 1, and you do want to have transient_local
, correct?
A transient_local
subscriber can only match with a transient_local
publisher, and AFAIK the default QoS settings are volatile
, which could lead to some hard to trace issues during integration.
E: I just noticed that only the publishers are set up as transient_local.
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, I think this corresponds to the earlier behavior of queue size 1 and latch = true
.
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.
Additionally, regarding your questions:
Reviewer: please confirm whether this is fine given your use case. I found a ROS Answers post that recommends using public NodeHandles anyway for topics.
Again, all of the changes look fine and appear to be more or less idiomatic ROS 2. So the use of only an implicitly public NodeHandle
equivalent seems fine.
Can you let me know whether a rclcpp::WallTimer fulfills your use case or whether the timer should stop when simulation time stops?
I cannot answer this, so I will defer to the original author/code maintainer.
@nnmm I came to the point at which I could start the launch file but then it segfaults: [INFO] [launch]: All log files can be found below /home/dejan.pangercic/.ros/log/2020-10-06-16-54-27-815049-ade-18178
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [vehicle_cmd_gate-1]: process started with pid [18180]
[vehicle_cmd_gate-1] free(): double free detected in tcache 2
[ERROR] [vehicle_cmd_gate-1]: process has died [pid 18180, exit code -6, cmd '/home/dejan.pangercic/aap_ws/install/vehicle_cmd_gate/lib/vehicle_cmd_gate/vehicle_cmd_gate --ros-args -r __node:=vehicle_cmd_gate --params-file /home/dejan.pangercic/aap_ws/install/vehicle_cmd_gate/share/vehicle_cmd_gate/config/vehicle_cmd_gate.yaml -r input/engage:=/autoware/engage -r input/emergency:=/system/emergency/is_emergency -r input/gate_mode:=/remote/gate_mode_cmd -r input/auto/control_cmd:=trajectory_follower/control_cmd -r input/auto/turn_signal_cmd:=/planning/turn_signal_decider/turn_signal_cmd -r input/auto/shift_cmd:=/control/shift_decider/shift_cmd -r input/remote/control_cmd:=/remote/control_cmd -r input/remote/turn_signal_cmd:=/remote/turn_signal_cmd -r input/remote/shift_cmd:=/remote/shift_cmd -r input/emergency/control_cmd:=/system/emergency/control_cmd -r input/emergency/turn_signal_cmd:=/system/emergency/turn_signal_cmd -r input/emergency/shift_cmd:=/system/emergency/shift_cmd -r output/vehicle_cmd:=vehicle_cmd -r output/control_cmd:=/control/control_cmd -r output/shift_cmd:=/control/shift_cmd -r output/turn_signal_cmd:=/control/turn_signal_cmd -r output/gate_mode:=/control/current_gate_mode']. I then ran out of time but I think that you will be able to quickly debug this. |
@nnmm regarding this comment: #3 (review) @sumanth-nirmal thinks that the following will also work (from https://github.com/ros2/rclcpp/blob/master/rclcpp/include/rclcpp/create_timer.hpp#L57):
To test this do the following:
If everything works the callback should be triggered. If above does not work - talk to us and we will surrender to the alternative explanation that William offered (currently still in my chat). |
Putting my fully question into open to others can see it too: We are trying to port https://github.com/tier4/autoware.iv.universe/blob/master/control/vehicle_cmd_gate/src/vehicle_cmd_gate.cpp#L117 as https://github.com/tier4/autoware.iv.universe/pull/3/files (ctrl+f for timer_ ) Now William says this:
|
Recap:
|
This is definitely something people need to do a good port.
An example is here: https://github.com/ros2/rclcpp/blob/c88cc649d32cb3a0ca7eb3c2b92d678303adb0d5/rclcpp/test/rclcpp/test_time.cpp#L65-L69 set the thresholds to zero. For the short term, I think that you could make a small helper class leveraging the jump callbacks and some signaling to wake the sleep or at worst have the sleep polling based on the clock. And then we should try to make sure to push the priority up of the time implementation improvements. |
@mitsudome-r, could you review? |
The handling of timer needs to be discussed. Just report that
|
@sumanth-nirmal It seems your suggestions regarding the timer doesn't work unfortunately. When I replace
with
in the minimal_timer example (lambda version), the node exits immediately, without any simulation running. Is that a bug? |
@cho3 recommendation: Timers in ROS 1 vs ROS 2Caveat: I am not an expert in the full breadth of ROS 1, ROS 2, or clocks. I have decent working knowledge of a subset of ROS 1 and 2, and working knowledge of clocks. tl;dr
ROS 1 vs ROS 2The The ROS 2 Unfortunately, one additional problem remains.
The Problem with Timer-Driven PatternsIt is well understood that a polling or timer-driven pattern increases jitter (i.e. variance of latency). (Consider, for example: if every data processing node in a chain operates on a timer what is the best and worst case latency?) As a consequence for more timing-sensitive applications, it is generally not preferred to use a timer-driven pattern. On top of this, it is also reasonably well known that use of the clock is nondeterministic and internally this has been a large source of frustration with bad, or timing sensitive tests. Such tests typically require specific timing and/or implicitly require a certain execution order (loosely enforced by timing assumptions rather than explicitly via the code). As a whole, introducing the clock explicitly (or implicitly via timers) is problematic because it introduces additional state, and thus assumptions on the requirements for the operation of the component. Consider also leap seconds and how that might ruin the operation and/or assumptions needed for the proper operation of the component. Preferred PatternsIn general, a data-driven pattern should be preferred to a timer-driven pattern. One reasonable exception to this guideline is the state estimator/filter at the end of localization. A timer-driven pattern in this context is useful to provide smooth behavior and promote looser coupling between the planning stack and the remainder of the stack. The core idea behind a data-driven pattern is that as soon as data arrives, it should be appropriately processed. Furthermore, the system clock (or any other source of time) should not be used to manipulate data or the timestamps. This pattern is valuable since it implicitly cuts down on hidden state (being the clock), and thus simplifies assumptions needed for the node to work. For examples of this kind of pattern, see the lidar object detection stack in Autoware.Auto. By not using any mention of the clock save for in the drivers, the stack can run equivalently on bag data, simulation data, or live data. A similar pattern with multiple inputs can be seen in the MPC implementation both internally and externally. |
9adf5ee
to
0d9da63
Compare
auto timer_callback = std::bind(&VehicleCmdGate::onTimer, this); | ||
auto period = std::chrono::duration_cast<std::chrono::nanoseconds>( | ||
std::chrono::duration<double>(update_period_)); | ||
timer_ = std::make_shared<rclcpp::GenericTimer<decltype(timer_callback)>>( |
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.
@TakaHoribe @fred-apex-ai This is the timer replacement. I tried it out with a minimal publisher that sends /clock
messages and a timer like this. The timer stops when no messages are sent and sim time is enabled, and goes faster when the published clock goes faster.
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.
Thank you! I'll test with this code in my package.
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.
@nnmm I will try it out, too
@TakaHoribe Could you do the final review and merge? |
@wjwwood see the before mentioned recommendation for It also seems that accelerating or slowing down the timer works: https://github.com/tier4/Pilot.Auto/pull/3#discussion_r503121450. |
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've confirmed it works in my local.The timer callback runs correctly for both real time and sim time.(tested with ros1_bridge to publish clock topic)
The code also looks ok.
* Port vehicle_cmd_gate to ROS2 * Sim-time-respecting timer
rename *.launch files to *.launch.xml
* Port vehicle_cmd_gate to ROS2 * Sim-time-respecting timer
See https://github.com/nnmm/autoware.iv.universe/pull/1/files for a ROS1 <-> ROS2 diff
Tested the build with ROS2 Foxy by
.aderc
taken from here)colcon build --packages-up-to vehicle_cmd_gate
in theros2
branch of the AutowareArchitectureProposal repo (with this branch checked out in theautoware/autoware.iv
sub-repo)build/vehicle_cmd_gate/vehicle_cmd_gate
binary, which doesn't print anythingros2 launch vehicle_cmd_gate vehicle_cmd_gate.launch.xml
I had to create two new messages in
autoware_control_msgs
to replace the bool message typeI decided to make the
VehicleCmdGate
aNode
. It previously had two NodeHandles, a public one and a private one ("~"
). The public one was unused and could be removed. Private nodes are not supported in ROS2, so I simply removed the private namespace. I found a ROS Answers post that recommends using public NodeHandles anyway for topics.Regarding
ros::Timer
: In my understanding,rclcpp::WallTimer
doesn't allow for using the/clock
topic so it's not fully equivalent. Anrclcpp::GenericTimer
works however, with some manual glue code.