40 #include <kdl/jntarray.hpp> 42 #include <kdl/chainiksolverpos_nr_jl.hpp> 43 #include <kdl/chainiksolvervel_pinv.hpp> 44 #include <kdl/chainfksolverpos_recursive.hpp> 45 #include <kdl/chainjnttojacsolver.hpp> 46 #include <kdl/tree.hpp> 52 inline geometry_msgs::Vector3 transformVector(
const Eigen::Affine3d& transform,
const geometry_msgs::Vector3& vector)
55 p = Eigen::Vector3d(vector.x, vector.y, vector.z);
56 p = transform.linear() * p;
58 geometry_msgs::Vector3 result;
68 const geometry_msgs::Vector3& gravity_vector)
77 ROS_ERROR_NAMED(
"dynamics_solver",
"Group '%s' is not a chain. Will not initialize dynamics solver",
85 ROS_ERROR_NAMED(
"dynamics_solver",
"Group '%s' has a mimic joint. Will not initialize dynamics solver",
94 ROS_ERROR_NAMED(
"dynamics_solver",
"Group '%s' does not have a parent link", group_name.c_str());
104 const urdf::ModelInterfaceSharedPtr urdf_model =
robot_model_->getURDF();
110 ROS_ERROR_NAMED(
"dynamics_solver",
"Could not initialize tree object");
116 ROS_ERROR_NAMED(
"dynamics_solver",
"Could not initialize chain object");
124 state_->setToDefaultValues();
127 for (std::size_t i = 0; i < joint_model_names.size(); ++i)
129 const urdf::Joint* ujoint = urdf_model->getJoint(joint_model_names[i]).get();
130 if (ujoint && ujoint->limits)
136 KDL::Vector gravity(gravity_vector.x, gravity_vector.y,
145 const std::vector<double>& joint_accelerations,
146 const std::vector<geometry_msgs::Wrench>& wrenches, std::vector<double>& torques)
const 150 ROS_DEBUG_NAMED(
"dynamics_solver",
"Did not construct DynamicsSolver object properly. " 151 "Check error logs.");
186 kdl_angles(i) = joint_angles[i];
187 kdl_velocities(i) = joint_velocities[i];
188 kdl_accelerations(i) = joint_accelerations[i];
193 kdl_wrenches[i](0) = wrenches[i].force.x;
194 kdl_wrenches[i](1) = wrenches[i].force.y;
195 kdl_wrenches[i](2) = wrenches[i].force.z;
197 kdl_wrenches[i](3) = wrenches[i].torque.x;
198 kdl_wrenches[i](4) = wrenches[i].torque.y;
199 kdl_wrenches[i](5) = wrenches[i].torque.z;
202 if (
chain_id_solver_->CartToJnt(kdl_angles, kdl_velocities, kdl_accelerations, kdl_wrenches, kdl_torques) < 0)
204 ROS_ERROR_NAMED(
"dynamics_solver",
"Something went wrong computing torques");
209 torques[i] = kdl_torques(i);
215 unsigned int& joint_saturated)
const 219 ROS_DEBUG_NAMED(
"dynamics_solver",
"Did not construct DynamicsSolver object properly. " 220 "Check error logs.");
232 if (!
getTorques(joint_angles, joint_velocities, joint_accelerations, wrenches, zero_torques))
247 const Eigen::Affine3d& tip_frame =
state_->getFrameTransform(
tip_name_);
248 Eigen::Affine3d transform = tip_frame.inverse(Eigen::Isometry) * base_frame;
249 wrenches.back().force.z = 1.0;
250 wrenches.back().force = transformVector(transform, wrenches.back().force);
251 wrenches.back().torque = transformVector(transform, wrenches.back().torque);
253 ROS_DEBUG_NAMED(
"dynamics_solver",
"New wrench (local frame): %f %f %f", wrenches.back().force.x,
254 wrenches.back().force.y, wrenches.back().force.z);
256 if (!
getTorques(joint_angles, joint_velocities, joint_accelerations, wrenches, torques))
259 double min_payload = std::numeric_limits<double>::max();
262 double payload_joint = std::max<double>((
max_torques_[i] - zero_torques[i]) / (torques[i] - zero_torques[i]),
264 (torques[i] - zero_torques[i]));
265 ROS_DEBUG_NAMED(
"dynamics_solver",
"Joint: %d, Actual Torque: %f, Max Allowed: %f, Gravity: %f", i, torques[i],
267 ROS_DEBUG_NAMED(
"dynamics_solver",
"Joint: %d, Payload Allowed (N): %f", i, payload_joint);
268 if (payload_joint < min_payload)
270 min_payload = payload_joint;
280 std::vector<double>& joint_torques)
const 284 ROS_DEBUG_NAMED(
"dynamics_solver",
"Did not construct DynamicsSolver object properly. " 285 "Check error logs.");
303 const Eigen::Affine3d& tip_frame =
state_->getFrameTransform(
tip_name_);
304 Eigen::Affine3d transform = tip_frame.inverse(Eigen::Isometry) * base_frame;
305 wrenches.back().force.z = payload *
gravity_;
306 wrenches.back().force = transformVector(transform, wrenches.back().force);
307 wrenches.back().torque = transformVector(transform, wrenches.back().torque);
309 ROS_DEBUG_NAMED(
"dynamics_solver",
"New wrench (local frame): %f %f %f", wrenches.back().force.x,
310 wrenches.back().force.y, wrenches.back().force.z);
312 return getTorques(joint_angles, joint_velocities, joint_accelerations, wrenches, joint_torques);
const std::string & getName() const
The name of this link.
Core components of MoveIt!
bool isChain() const
Check if this group is a linear chain.
KDL_PARSER_PUBLIC bool treeFromUrdfModel(const urdf::ModelInterface &robot_model, KDL::Tree &tree)
bool getPayloadTorques(const std::vector< double > &joint_angles, double payload, std::vector< double > &joint_torques) const
Get torques corresponding to a particular payload value. Payload is the weight that this group can ho...
std::shared_ptr< KDL::ChainIdSolver_RNE > chain_id_solver_
const std::vector< std::string > & getLinkModelNames() const
Get the names of the links that are part of this joint group.
unsigned int getNrOfSegments() const
robot_model::RobotModelConstPtr robot_model_
const std::vector< const JointModel * > & getMimicJointModels() const
Get the mimic joints that are part of this group.
#define ROS_DEBUG_NAMED(name,...)
unsigned int num_segments_
const std::vector< double > & getMaxTorques() const
Get maximum torques for this group.
const std::vector< std::string > & getJointModelNames() const
Get the names of the joints in this group. These are the names of the joints returned by getJointMode...
This namespace includes the dynamics_solver library.
unsigned int getNrOfJoints() const
A joint from the robot. Models the transform that this joint applies in the kinematic chain...
robot_state::RobotStatePtr state_
std::vector< Wrench > Wrenches
bool getChain(const std::string &chain_root, const std::string &chain_tip, Chain &chain) const
const robot_model::JointModelGroup * joint_model_group_
bool getTorques(const std::vector< double > &joint_angles, const std::vector< double > &joint_velocities, const std::vector< double > &joint_accelerations, const std::vector< geometry_msgs::Wrench > &wrenches, std::vector< double > &torques) const
Get the torques (the order of all input and output is the same as the order of joints for this group ...
std::vector< double > max_torques_
const std::vector< const JointModel * > & getJointRoots() const
Unlike a complete kinematic model, a group may contain disconnected parts of the kinematic tree – a ...
#define ROS_ERROR_NAMED(name,...)
const LinkModel * getParentLinkModel() const
Get the link that this joint connects to. The robot is assumed to start with a joint, so the root joint will return a NULL pointer here.
Representation of a robot's state. This includes position, velocity, acceleration and effort...
bool getMaxPayload(const std::vector< double > &joint_angles, double &payload, unsigned int &joint_saturated) const
Get the maximum payload for this group (in kg). Payload is the weight that this group can hold when t...
DynamicsSolver(const robot_model::RobotModelConstPtr &robot_model, const std::string &group_name, const geometry_msgs::Vector3 &gravity_vector)
Initialize the dynamics solver.