debug_fk_vel_recursive_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <string>
19 #include <vector>
20 #include <algorithm>
21 #include <ros/ros.h>
22 
23 #include <sensor_msgs/JointState.h>
24 #include <control_msgs/JointTrajectoryControllerState.h>
25 #include <std_msgs/Float64.h>
26 #include <geometry_msgs/Twist.h>
27 
29 #include <kdl/chainfksolvervel_recursive.hpp>
30 #include <kdl/chainjnttojacsolver.hpp>
31 #include <kdl/frames.hpp>
32 #include <kdl/jntarray.hpp>
33 #include <kdl/jntarrayvel.hpp>
34 
35 #include <Eigen/Dense>
37 
39 {
47 
48  std::string chain_base_link_;
49  std::string chain_tip_link_;
50 
54 
55 public:
56  int init()
57  {
58  if (!nh_.getParam("chain_base_link", this->chain_base_link_))
59  {
60  ROS_ERROR("Failed to get parameter \"chain_base_link\".");
61  return -1;
62  }
63 
64  if (!nh_.getParam("chain_tip_link", this->chain_tip_link_))
65  {
66  ROS_ERROR("Failed to get parameter \"chain_tip_link\".");
67  return -2;
68  }
69 
71  KDL::Tree my_tree;
72  if (!kdl_parser::treeFromParam("/robot_description", my_tree))
73  {
74  ROS_ERROR("Failed to construct kdl tree");
75  return -3;
76  }
77 
78  my_tree.getChain(this->chain_base_link_, this->chain_tip_link_, chain_);
79  if (chain_.getNrOfJoints() == 0)
80  {
81  ROS_ERROR("Failed to initialize kinematic chain");
82  return -4;
83  }
84 
85  //debug chain
86  ROS_WARN("~~~~~~~~~~~~~ DEBUG CHAIN ~~~~~~~~~~~~~");
87  ROS_WARN_STREAM("NrOfJoints: "<<chain_.getNrOfJoints());
88  ROS_WARN_STREAM("NrOfSegments: "<<chain_.getNrOfSegments());
89  for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
90  {
91  KDL::Segment segment = chain_.getSegment(i);
92  ROS_WARN_STREAM("SegmentName: "<<segment.getName());
93  KDL::Joint joint = segment.getJoint();
94  ROS_WARN_STREAM("JointName: "<<joint.getName());
95  ROS_WARN_STREAM("JointType: "<<joint.getTypeName());
96  }
97  ROS_WARN("~~~~~~~~~~~~~ DEBUG CHAIN ~~~~~~~~~~~~~");
98 
99  p_fksolver_vel_ = new KDL::ChainFkSolverVel_recursive(chain_);
100  p_jnt2jac_ = new KDL::ChainJntToJacSolver(chain_);
101 
103  // joint_states_sub_ = nh_.subscribe("joint_states", 1, &DebugFkVelRecursive::jointstatesCallback, this); // analyzing controller_state instead
104  controller_state_sub_ = nh_.subscribe("joint_trajectory_controller/state", 1, &DebugFkVelRecursive::controllerstateCallback, this);
105  manipulability_pub_ = nh_.advertise<std_msgs::Float64> ("debug/manipulability", 1);
106  twist_current_pub_ = nh_.advertise<geometry_msgs::Twist> ("debug/twist_current", 1);
107  twist_magnitude_desired_pub_ = nh_.advertise<sensor_msgs::JointState> ("debug/twist_magnitude/desired", 1);
108  twist_magnitude_actual_pub_ = nh_.advertise<sensor_msgs::JointState> ("debug/twist_magnitude/actual", 1);
109 
110  return 0;
111  }
112 
113  void jointstatesCallback(const sensor_msgs::JointState::ConstPtr& msg)
114  {
116  KDL::JntArray q_dot = KDL::JntArray(chain_.getNrOfJoints());
117 
119  for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
120  {
121  KDL::Joint joint = chain_.getSegment(i).getJoint();
122  std::string joint_name = joint.getName();
123  if (joint.getType() == KDL::Joint::None)
124  {
125  ROS_DEBUG_STREAM("Skip fixed Joint '" << joint_name);
126  continue;
127  }
128  else
129  {
130  if (std::find(msg->name.begin(), msg->name.end(), joint_name) != msg->name.end())
131  {
132  unsigned int index = std::distance(msg->name.begin(), std::find(msg->name.begin(), msg->name.end(), joint_name));
133  q(index) = msg->position[index];
134  q_dot(index) = msg->velocity[index];
135  }
136  else
137  {
138  ROS_ERROR_STREAM("Joint '" << joint_name << "' not found in JointStates");
139  return;
140  }
141  }
142  }
143 
145  std::vector< KDL::FrameVel > v_FrameVel;
146  KDL::JntArrayVel jntArrayVel = KDL::JntArrayVel(q, q_dot);
147  v_FrameVel.resize(chain_.getNrOfSegments());
148  if (p_fksolver_vel_->JntToCart(jntArrayVel, v_FrameVel, chain_.getNrOfSegments()) >= 0)
149  {
150  //last entry is twist of tip_link
151  geometry_msgs::Twist twist_msg;
152  tf::twistKDLToMsg(v_FrameVel.back().GetTwist(), twist_msg);
153  twist_current_pub_.publish(twist_msg);
154 
155  //recursively calculate FrameVel magnitudes
156  sensor_msgs::JointState magnitude_msg;
157  magnitude_msg.header.stamp = msg->header.stamp;
158  for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
159  {
160  magnitude_msg.name.push_back(chain_.getSegment(i).getName());
161  magnitude_msg.velocity.push_back(v_FrameVel[i].GetTwist().vel.Norm());
162  }
163  twist_magnitude_actual_pub_.publish(magnitude_msg);
164  }
165 
167  KDL::Jacobian jac(chain_.getNrOfJoints());
168  p_jnt2jac_->JntToJac(q, jac);
169  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> prod = jac.data * jac.data.transpose();
170  double d = prod.determinant();
171  double kappa = std::sqrt(std::abs(d));
172  std_msgs::Float64 manipulability_msg;
173  manipulability_msg.data = kappa;
174  manipulability_pub_.publish(manipulability_msg);
175  }
176 
177  void controllerstateCallback(const control_msgs::JointTrajectoryControllerState::ConstPtr& msg)
178  {
179  KDL::JntArray q_desired = KDL::JntArray(chain_.getNrOfJoints());
180  KDL::JntArray q_desired_dot = KDL::JntArray(chain_.getNrOfJoints());
181  KDL::JntArray q_actual = KDL::JntArray(chain_.getNrOfJoints());
182  KDL::JntArray q_actual_dot = KDL::JntArray(chain_.getNrOfJoints());
183 
184  for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
185  {
186  KDL::Joint joint = chain_.getSegment(i).getJoint();
187  std::string joint_name = joint.getName();
188  if (joint.getType() == KDL::Joint::None)
189  {
190  ROS_DEBUG_STREAM("Skip fixed Joint '" << joint_name);
191  continue;
192  }
193  else
194  {
195  if (std::find(msg->joint_names.begin(), msg->joint_names.end(), joint_name) != msg->joint_names.end())
196  {
197  unsigned int index = std::distance(msg->joint_names.begin(), std::find(msg->joint_names.begin(), msg->joint_names.end(), joint_name));
198  q_desired(index) = msg->desired.positions[index];
199  q_desired_dot(index) = msg->desired.velocities[index];
200  q_actual(index) = msg->actual.positions[index];
201  q_actual_dot(index) = msg->actual.velocities[index];
202  }
203  else
204  {
205  ROS_ERROR_STREAM("Joint '" << joint_name << "' not found in JointTrajectoryControllerState");
206  return;
207  }
208  }
209  }
210 
212  std::vector< KDL::FrameVel > v_FrameVel_desired;
213  KDL::JntArrayVel jntArrayVel_desired = KDL::JntArrayVel(q_desired, q_desired_dot);
214  v_FrameVel_desired.resize(chain_.getNrOfSegments());
215  if (p_fksolver_vel_->JntToCart(jntArrayVel_desired, v_FrameVel_desired, chain_.getNrOfSegments()) >= 0)
216  {
217  sensor_msgs::JointState magnitude_desired_msg;
218  magnitude_desired_msg.header.stamp = msg->header.stamp;
219  for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
220  {
221  magnitude_desired_msg.name.push_back(chain_.getSegment(i).getName());
222  magnitude_desired_msg.velocity.push_back(v_FrameVel_desired[i].GetTwist().vel.Norm());
223  }
224  twist_magnitude_desired_pub_.publish(magnitude_desired_msg);
225  }
227  std::vector< KDL::FrameVel > v_FrameVel_actual;
228  KDL::JntArrayVel jntArrayVel_actual = KDL::JntArrayVel(q_actual, q_actual_dot);
229  v_FrameVel_actual.resize(chain_.getNrOfSegments());
230  if (p_fksolver_vel_->JntToCart(jntArrayVel_actual, v_FrameVel_actual, chain_.getNrOfSegments()) >= 0)
231  {
232  sensor_msgs::JointState magnitude_actual_msg;
233  magnitude_actual_msg.header.stamp = msg->header.stamp;
234  for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
235  {
236  magnitude_actual_msg.name.push_back(chain_.getSegment(i).getName());
237  magnitude_actual_msg.velocity.push_back(v_FrameVel_actual[i].GetTwist().vel.Norm());
238  }
239  twist_magnitude_actual_pub_.publish(magnitude_actual_msg);
240  }
241  }
242 
243 };
244 
245 
246 int main(int argc, char** argv)
247 {
248  ros::init(argc, argv, "debug_fk_vel_recursive_node");
249 
250  DebugFkVelRecursive dfvr;
251  if (dfvr.init() != 0)
252  {
253  ROS_ERROR("Failed to initialize DebugFkVelRecursive.");
254  return -1;
255  }
256 
257  ros::spin();
258 }
d
Definition: setup.py:6
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
unsigned int getNrOfSegments() const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
const Segment & getSegment(unsigned int nr) const
#define ROS_ERROR(...)
#define ROS_WARN(...)
int main(int argc, char **argv)
void controllerstateCallback(const control_msgs::JointTrajectoryControllerState::ConstPtr &msg)
const Joint & getJoint() const
void publish(const boost::shared_ptr< M > &message) const
unsigned int getNrOfJoints() const
bool getParam(const std::string &key, std::string &s) const
void twistKDLToMsg(const KDL::Twist &k, geometry_msgs::Twist &m)
bool getChain(const std::string &chain_root, const std::string &chain_tip, Chain &chain) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
const JointType & getType() const
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
void jointstatesCallback(const sensor_msgs::JointState::ConstPtr &msg)
virtual int JntToCart(const JntArrayVel &q_in, FrameVel &out, int segmentNr=-1)
KDL_PARSER_PUBLIC bool treeFromParam(const std::string &param, KDL::Tree &tree)
KDL::ChainFkSolverVel_recursive * p_fksolver_vel_
KDL::ChainJntToJacSolver * p_jnt2jac_
const std::string & getName() const
const std::string & getName() const
#define ROS_ERROR_STREAM(args)
virtual int JntToJac(const JntArray &q_in, Jacobian &jac, int seg_nr=-1)


cob_twist_controller
Author(s): Felix Messmer , Marco Bezzon , Christoph Mark , Francisco Moreno
autogenerated on Mon May 1 2023 02:50:29