@@ -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" 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 '" 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] + " /" 
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] + " /" 
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] + " /" 
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] + " /" 
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 + " /" 
221144    {
222-       joint_state[mimic_joint.joint_index ] = mimic_joint.multiplier  * joint_state[mimic_joint.mimicked_joint_index ];
145+       set_state (mimic_joint_name + " /" 
146+                 mimic_joint.offset  +
147+                     mimic_joint.multiplier  * get_state (mimicked_joint_name + " /" 
148+     }
149+     if  (has_state (mimic_joint_name + " /" 
150+     {
151+       set_state (mimic_joint_name + " /" 
152+                 mimic_joint.multiplier  * get_state (mimicked_joint_name + " /" 
153+     }
154+     if  (has_state (mimic_joint_name + " /" 
155+     {
156+       set_state (mimic_joint_name + " /" 
157+                 mimic_joint.multiplier  * get_state (mimicked_joint_name + " /" 
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  + " /" name ) -
181+                        get_command (joints[i].name  + " /" 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