@@ -29,13 +29,14 @@ namespace
2929{
3030/* * @brief Sums the total rotation for joint states that wrap from 2*pi to -2*pi
3131when rotating in the positive direction */
32- void sumRotationFromMinus2PiTo2Pi (const double current_wrapped_rad, double & total_rotation )
32+ double sumRotationFromMinus2PiTo2Pi (const double current_wrapped_rad, double total_rotation_in )
3333{
3434 double delta = 0 ;
35- angles::shortest_angular_distance_with_large_limits (total_rotation, current_wrapped_rad, 2 * M_PI, -2 * M_PI, delta);
35+ angles::shortest_angular_distance_with_large_limits (total_rotation_in, current_wrapped_rad, 2 * M_PI, -2 * M_PI,
36+ delta);
3637
3738 // Add the corrected delta to the total rotation
38- total_rotation += delta;
39+ return total_rotation_in + delta;
3940}
4041} // namespace
4142
@@ -54,64 +55,6 @@ CallbackReturn JointStateTopicSystem::on_init(const hardware_interface::Hardware
5455 return CallbackReturn::ERROR;
5556 }
5657
57- // Initialize storage for all joints' standard interfaces, regardless of their existence and set all values to nan
58- joint_command_values_.resize (standard_interfaces_.size ());
59- joint_state_values_.resize (standard_interfaces_.size ());
60- for (auto i = 0u ; i < standard_interfaces_.size (); i++)
61- {
62- joint_command_values_[i].resize (get_hardware_info ().joints .size (), 0.0 );
63- joint_state_values_[i].resize (get_hardware_info ().joints .size (), 0.0 );
64- }
65-
66- // Initial command values
67- for (auto i = 0u ; i < get_hardware_info ().joints .size (); i++)
68- {
69- const auto & component = get_hardware_info ().joints [i];
70- for (const auto & interface : component.state_interfaces )
71- {
72- auto it = std::find (standard_interfaces_.begin (), standard_interfaces_.end (), interface.name );
73- // If interface name is found in the interfaces list
74- if (it != standard_interfaces_.end ())
75- {
76- auto index = static_cast <std::size_t >(std::distance (standard_interfaces_.begin (), it));
77- // Check the initial_value param is used
78- if (!interface.initial_value .empty ())
79- {
80- joint_state_values_[index][i] = std::stod (interface.initial_value );
81- joint_command_values_[index][i] = std::stod (interface.initial_value );
82- }
83- }
84- }
85- }
86-
87- // Search for mimic joints
88- for (auto i = 0u ; i < get_hardware_info ().joints .size (); ++i)
89- {
90- const auto & joint = get_hardware_info ().joints .at (i);
91- if (joint.parameters .find (" mimic" ) != joint.parameters .cend ())
92- {
93- const auto mimicked_joint_it = std::find_if (
94- get_hardware_info ().joints .begin (), get_hardware_info ().joints .end (),
95- [&mimicked_joint = joint.parameters .at (" mimic" )](const hardware_interface::ComponentInfo& joint_info) {
96- return joint_info.name == mimicked_joint;
97- });
98- if (mimicked_joint_it == get_hardware_info ().joints .cend ())
99- {
100- throw std::runtime_error (std::string (" Mimicked joint '" ) + joint.parameters .at (" mimic" ) + " ' not found" );
101- }
102- MimicJoint mimic_joint;
103- mimic_joint.joint_index = i;
104- mimic_joint.mimicked_joint_index =
105- static_cast <std::size_t >(std::distance (get_hardware_info ().joints .begin (), mimicked_joint_it));
106- auto param_it = joint.parameters .find (" multiplier" );
107- if (param_it != joint.parameters .end ())
108- {
109- mimic_joint.multiplier = std::stod (joint.parameters .at (" multiplier" ));
110- }
111- mimic_joints_.push_back (mimic_joint);
112- }
113- }
114-
11558 const auto get_hardware_parameter = [this ](const std::string& parameter_name, const std::string& default_value) {
11659 if (auto it = get_hardware_info ().hardware_parameters .find (parameter_name);
11760 it != get_hardware_info ().hardware_parameters .end ())
@@ -143,164 +86,130 @@ CallbackReturn JointStateTopicSystem::on_init(const hardware_interface::Hardware
14386 return CallbackReturn::SUCCESS;
14487}
14588
146- std::vector<hardware_interface::StateInterface> JointStateTopicSystem::export_state_interfaces ()
147- {
148- std::vector<hardware_interface::StateInterface> state_interfaces;
149-
150- // Joints' state interfaces
151- for (auto i = 0u ; i < get_hardware_info ().joints .size (); i++)
152- {
153- const auto & joint = get_hardware_info ().joints [i];
154- for (const auto & interface : joint.state_interfaces )
155- {
156- // Add interface: if not in the standard list then use "other" interface list
157- if (!getInterface (joint.name , interface.name , i, joint_state_values_, state_interfaces))
158- {
159- throw std::runtime_error (" Interface is not found in the standard list." );
160- }
161- }
162- }
163-
164- return state_interfaces;
165- }
166-
167- std::vector<hardware_interface::CommandInterface> JointStateTopicSystem::export_command_interfaces ()
168- {
169- std::vector<hardware_interface::CommandInterface> command_interfaces;
170-
171- // Joints' state interfaces
172- for (auto i = 0u ; i < get_hardware_info ().joints .size (); i++)
173- {
174- const auto & joint = get_hardware_info ().joints [i];
175- for (const auto & interface : joint.command_interfaces )
176- {
177- if (!getInterface (joint.name , interface.name , i, joint_command_values_, command_interfaces))
178- {
179- throw std::runtime_error (" Interface is not found in the standard list." );
180- }
181- }
182- }
183-
184- return command_interfaces;
185- }
186-
18789hardware_interface::return_type JointStateTopicSystem::read (const rclcpp::Time& /* time*/ ,
18890 const rclcpp::Duration& /* period*/ )
18991{
92+ const auto & joints = get_hardware_info ().joints ;
19093 for (std::size_t i = 0 ; i < latest_joint_state_.name .size (); ++i)
19194 {
192- const auto & joints = get_hardware_info (). joints ;
193- auto it = std::find_if (joints. begin (), joints. end (),
194- [&joint_name = std::as_const (latest_joint_state_ .name [i])](
195- const hardware_interface::ComponentInfo& info) { return joint_name == info. name ; });
95+ const auto it = std::find_if (joints. begin (), joints. end (),
96+ [name = latest_joint_state_. name [i]]( const hardware_interface::ComponentInfo& joint) {
97+ return joint .name == name;
98+ });
19699 if (it != joints.end ())
197100 {
198- auto j = static_cast <std::size_t >(std::distance (joints.begin (), it));
199- if (sum_wrapped_joint_states_)
101+ if (std::find_if (get_hardware_info ().mimic_joints .begin (), get_hardware_info ().mimic_joints .end (),
102+ [idx = static_cast <std::size_t >(std::distance (joints.begin (), it))](
103+ const hardware_interface::MimicJoint& mimic_joint) {
104+ return idx == mimic_joint.joint_index ;
105+ }) != get_hardware_info ().mimic_joints .end ())
200106 {
201- sumRotationFromMinus2PiTo2Pi (latest_joint_state_.position [i], joint_state_values_[POSITION_INTERFACE_INDEX][j]);
107+ // mimic joints are updated at the end of this function
108+ continue ;
202109 }
203- else
110+
111+ if (!latest_joint_state_.position .empty () && std::isfinite (latest_joint_state_.position .at (i)))
204112 {
205- joint_state_values_[POSITION_INTERFACE_INDEX][j] = latest_joint_state_.position [i];
113+ if (sum_wrapped_joint_states_)
114+ {
115+ auto name = latest_joint_state_.name [i] + " /" + hardware_interface::HW_IF_POSITION;
116+
117+ set_state (name, sumRotationFromMinus2PiTo2Pi (latest_joint_state_.position .at (i), get_state (name)));
118+ }
119+ else
120+ {
121+ set_state (latest_joint_state_.name [i] + " /" + hardware_interface::HW_IF_POSITION,
122+ latest_joint_state_.position .at (i));
123+ }
206124 }
207- if (!latest_joint_state_.velocity .empty ())
125+ if (!latest_joint_state_.velocity .empty () && std::isfinite (latest_joint_state_. velocity . at (i)) )
208126 {
209- joint_state_values_[VELOCITY_INTERFACE_INDEX][j] = latest_joint_state_.velocity [i];
127+ set_state (latest_joint_state_.name [i] + " /" + hardware_interface::HW_IF_VELOCITY,
128+ latest_joint_state_.velocity .at (i));
210129 }
211- if (!latest_joint_state_.effort .empty ())
130+ if (!latest_joint_state_.effort .empty () && std::isfinite (latest_joint_state_. effort . at (i)) )
212131 {
213- joint_state_values_[EFFORT_INTERFACE_INDEX][j] = latest_joint_state_.effort [i];
132+ set_state (latest_joint_state_.name [i] + " /" + hardware_interface::HW_IF_EFFORT,
133+ latest_joint_state_.effort .at (i));
214134 }
215135 }
216136 }
217137
218- for (const auto & mimic_joint : mimic_joints_)
138+ // Update mimic joints
139+ for (const auto & mimic_joint : get_hardware_info ().mimic_joints )
219140 {
220- for (auto & joint_state : joint_state_values_)
141+ const auto & mimic_joint_name = joints.at (mimic_joint.joint_index ).name ;
142+ const auto & mimicked_joint_name = joints.at (mimic_joint.mimicked_joint_index ).name ;
143+ if (has_state (mimic_joint_name + " /" + hardware_interface::HW_IF_POSITION))
221144 {
222- joint_state[mimic_joint.joint_index ] = mimic_joint.multiplier * joint_state[mimic_joint.mimicked_joint_index ];
145+ set_state (mimic_joint_name + " /" + hardware_interface::HW_IF_POSITION,
146+ mimic_joint.offset +
147+ mimic_joint.multiplier * get_state (mimicked_joint_name + " /" + hardware_interface::HW_IF_POSITION));
148+ }
149+ if (has_state (mimic_joint_name + " /" + hardware_interface::HW_IF_VELOCITY))
150+ {
151+ set_state (mimic_joint_name + " /" + hardware_interface::HW_IF_VELOCITY,
152+ mimic_joint.multiplier * get_state (mimicked_joint_name + " /" + hardware_interface::HW_IF_VELOCITY));
153+ }
154+ if (has_state (mimic_joint_name + " /" + hardware_interface::HW_IF_ACCELERATION))
155+ {
156+ set_state (mimic_joint_name + " /" + hardware_interface::HW_IF_ACCELERATION,
157+ mimic_joint.multiplier * get_state (mimicked_joint_name + " /" + hardware_interface::HW_IF_ACCELERATION));
223158 }
224159 }
225160
226161 return hardware_interface::return_type::OK;
227162}
228163
229- template <typename HandleType>
230- bool JointStateTopicSystem::getInterface (const std::string& name, const std::string& interface_name,
231- const size_t vector_index, std::vector<std::vector<double >>& values,
232- std::vector<HandleType>& interfaces)
233- {
234- auto it = std::find (standard_interfaces_.begin (), standard_interfaces_.end (), interface_name);
235- if (it != standard_interfaces_.end ())
236- {
237- auto j = static_cast <std::size_t >(std::distance (standard_interfaces_.begin (), it));
238- interfaces.emplace_back (name, *it, &values[j][vector_index]);
239- return true ;
240- }
241- return false ;
242- }
243-
244164hardware_interface::return_type JointStateTopicSystem::write (const rclcpp::Time& /* time*/ ,
245165 const rclcpp::Duration& /* period*/ )
246166{
167+ const auto & joints = get_hardware_info ().joints ;
247168 // To avoid spamming TopicBased's joint command topic we check the difference between the joint states and
248169 // the current joint commands, if it's smaller than a threshold we don't publish it.
249- const auto diff = std::transform_reduce (
250- joint_state_values_[POSITION_INTERFACE_INDEX].cbegin (), joint_state_values_[POSITION_INTERFACE_INDEX].cend (),
251- joint_command_values_[POSITION_INTERFACE_INDEX].cbegin (), 0.0 ,
252- [](const auto d1, const auto d2) { return std::abs (d1) + std::abs (d2); }, std::minus<double >{});
170+ auto diff = 0.0 ;
171+ for (std::size_t i = 0 ; i < joints.size (); ++i)
172+ {
173+ for (const auto & interface : joints[i].command_interfaces )
174+ {
175+ if (interface.name != hardware_interface::HW_IF_POSITION)
176+ {
177+ continue ;
178+ }
179+ // sum the absolute difference for all joints
180+ diff += std::abs (get_state (joints[i].name + " /" + interface.name ) -
181+ get_command (joints[i].name + " /" + interface.name ));
182+ }
183+ }
253184 if (diff <= trigger_joint_command_threshold_)
254185 {
255186 return hardware_interface::return_type::OK;
256187 }
257188
258189 sensor_msgs::msg::JointState joint_state;
259- for (std::size_t i = 0 ; i < get_hardware_info (). joints .size (); ++i)
190+ for (std::size_t i = 0 ; i < joints.size (); ++i)
260191 {
261- joint_state.name .push_back (get_hardware_info (). joints [i].name );
192+ joint_state.name .push_back (joints[i].name );
262193 joint_state.header .stamp = get_node ()->now ();
263194 // only send commands to the interfaces that are defined for this joint
264- for (const auto & interface : get_hardware_info (). joints [i].command_interfaces )
195+ for (const auto & interface : joints[i].command_interfaces )
265196 {
266197 if (interface.name == hardware_interface::HW_IF_POSITION)
267198 {
268- joint_state.position .push_back (joint_command_values_[POSITION_INTERFACE_INDEX][i] );
199+ joint_state.position .push_back (get_command (joints[i]. name + " / " + interface. name ) );
269200 }
270201 else if (interface.name == hardware_interface::HW_IF_VELOCITY)
271202 {
272- joint_state.velocity .push_back (joint_command_values_[VELOCITY_INTERFACE_INDEX][i] );
203+ joint_state.velocity .push_back (get_command (joints[i]. name + " / " + interface. name ) );
273204 }
274205 else if (interface.name == hardware_interface::HW_IF_EFFORT)
275206 {
276- joint_state.effort .push_back (joint_command_values_[EFFORT_INTERFACE_INDEX][i] );
207+ joint_state.effort .push_back (get_command (joints[i]. name + " / " + interface. name ) );
277208 }
278209 else
279210 {
280211 RCLCPP_WARN_ONCE (get_node ()->get_logger (), " Joint '%s' has unsupported command interfaces found: %s." ,
281- get_hardware_info ().joints [i].name .c_str (), interface.name .c_str ());
282- }
283- }
284- }
285-
286- for (const auto & mimic_joint : mimic_joints_)
287- {
288- for (const auto & interface : get_hardware_info ().joints [mimic_joint.mimicked_joint_index ].command_interfaces )
289- {
290- if (interface.name == hardware_interface::HW_IF_POSITION)
291- {
292- joint_state.position [mimic_joint.joint_index ] =
293- mimic_joint.multiplier * joint_state.position [mimic_joint.mimicked_joint_index ];
294- }
295- else if (interface.name == hardware_interface::HW_IF_VELOCITY)
296- {
297- joint_state.velocity [mimic_joint.joint_index ] =
298- mimic_joint.multiplier * joint_state.velocity [mimic_joint.mimicked_joint_index ];
299- }
300- else if (interface.name == hardware_interface::HW_IF_EFFORT)
301- {
302- joint_state.effort [mimic_joint.joint_index ] =
303- mimic_joint.multiplier * joint_state.effort [mimic_joint.mimicked_joint_index ];
212+ joints[i].name .c_str (), interface.name .c_str ());
304213 }
305214 }
306215 }
0 commit comments