72
72
* \endcode
73
73
*
74
74
*/
75
- PLUGINLIB_EXPORT_CLASS (cartesian_controller_base::ForwardDynamicsSolver,
76
- cartesian_controller_base::IKSolver)
75
+ PLUGINLIB_EXPORT_CLASS (cartesian_controller_base::ForwardDynamicsSolver, cartesian_controller_base::IKSolver)
77
76
78
77
namespace cartesian_controller_base {
79
78
80
79
ForwardDynamicsSolver::ForwardDynamicsSolver () {}
81
80
82
81
ForwardDynamicsSolver::~ForwardDynamicsSolver () {}
83
82
84
- trajectory_msgs::JointTrajectoryPoint
85
- ForwardDynamicsSolver::getJointControlCmds (ros::Duration period,
86
- const ctrl::Vector6D& net_force) {
83
+ trajectory_msgs::JointTrajectoryPoint ForwardDynamicsSolver::getJointControlCmds (ros::Duration period, const ctrl::Vector6D &net_force) {
87
84
// Compute joint space inertia matrix with actualized link masses
88
85
buildGenericModel ();
89
- m_jnt_space_inertia_solver->JntToMass (m_current_positions,
90
- m_jnt_space_inertia);
86
+ m_jnt_space_inertia_solver->JntToMass (m_current_positions, m_jnt_space_inertia);
91
87
92
88
// Compute joint jacobian
93
89
m_jnt_jacobian_solver->JntToJac (m_current_positions, m_jnt_jacobian);
94
90
95
91
// Compute joint accelerations according to: \f$ \ddot{q} = H^{-1} ( J^T f)
96
92
// \f$
97
- m_current_accelerations.data = m_jnt_space_inertia.data .inverse () *
98
- m_jnt_jacobian.data .transpose () * net_force;
93
+ m_current_accelerations.data = m_jnt_space_inertia.data .inverse () * m_jnt_jacobian.data .transpose () * net_force;
99
94
100
95
// Numerical time integration with the Euler forward method
101
- m_current_positions.data =
102
- m_last_positions.data + m_last_velocities.data * period.toSec ();
103
- m_current_velocities.data =
104
- m_last_velocities.data + m_current_accelerations.data * period.toSec ();
105
- m_current_velocities.data *=
106
- 0.9 ; // 10 % global damping against unwanted null space motion.
107
- // Will cause exponential slow-down without input.
96
+ m_current_positions.data = m_last_positions.data + m_last_velocities.data * period.toSec ();
97
+ m_current_velocities.data = m_last_velocities.data + m_current_accelerations.data * period.toSec ();
98
+ m_current_velocities.data *= 0.9 ; // 10 % global damping against unwanted null space motion.
99
+ // Will cause exponential slow-down without input.
108
100
109
101
// Make sure positions stay in allowed margins
110
102
applyJointVelocityLimits ();
@@ -120,7 +112,7 @@ ForwardDynamicsSolver::getJointControlCmds(ros::Duration period,
120
112
// by most hardware joint drivers as max. tolerated values. As a
121
113
// consequence, the robot will move very slowly.
122
114
}
123
- control_cmd.time_from_start = period; // valid for this duration
115
+ control_cmd.time_from_start = period; // valid for this duration
124
116
125
117
// Update for the next cycle
126
118
m_last_positions = m_current_positions;
@@ -129,69 +121,94 @@ ForwardDynamicsSolver::getJointControlCmds(ros::Duration period,
129
121
return control_cmd;
130
122
}
131
123
132
- bool ForwardDynamicsSolver::init (ros::NodeHandle& nh, const KDL::Chain& chain,
133
- const KDL::JntArray& upper_pos_limits,
134
- const KDL::JntArray& lower_pos_limits,
135
- const KDL::JntArray& velocity_limits) {
136
- IKSolver::init (nh, chain, upper_pos_limits, lower_pos_limits,
137
- velocity_limits);
124
+ bool ForwardDynamicsSolver::init (ros::NodeHandle &nh, const KDL::Chain &chain, const KDL::JntArray &upper_pos_limits, const KDL::JntArray &lower_pos_limits, const KDL::JntArray &velocity_limits) {
125
+ IKSolver::init (nh, chain, upper_pos_limits, lower_pos_limits, velocity_limits);
138
126
139
127
if (!buildGenericModel ()) {
140
- ROS_ERROR (
141
- " ForwardDynamicsSolver: Something went wrong in setting up the "
142
- " internal model." );
128
+ ROS_ERROR (" ForwardDynamicsSolver: Something went wrong in setting up the "
129
+ " internal model." );
143
130
return false ;
144
131
}
145
132
146
133
// Forward dynamics
147
134
m_jnt_jacobian_solver.reset (new KDL::ChainJntToJacSolver (m_chain));
148
- m_jnt_space_inertia_solver.reset (
149
- new KDL::ChainDynParam (m_chain, KDL::Vector::Zero ()));
135
+ m_jnt_space_inertia_solver.reset (new KDL::ChainDynParam (m_chain, KDL::Vector::Zero ()));
150
136
m_jnt_jacobian.resize (m_number_joints);
151
137
m_jnt_space_inertia.resize (m_number_joints);
152
138
153
139
// Connect dynamic reconfigure and overwrite the default values with values
154
140
// on the parameter server. This is done automatically if parameters with
155
141
// the according names exist.
156
- m_callback_type =
157
- std::bind (&ForwardDynamicsSolver::dynamicReconfigureCallback, this ,
158
- std::placeholders::_1, std::placeholders::_2);
142
+ m_callback_type = std::bind (&ForwardDynamicsSolver::dynamicReconfigureCallback, this , std::placeholders::_1, std::placeholders::_2);
159
143
160
- m_dyn_conf_server.reset (new dynamic_reconfigure::Server<IKConfig>(
161
- ros::NodeHandle (nh.getNamespace () + " /solver/forward_dynamics" )));
144
+ m_dyn_conf_server.reset (new dynamic_reconfigure::Server<IKConfig>(ros::NodeHandle (nh.getNamespace () + " /solver/forward_dynamics" )));
162
145
163
146
m_dyn_conf_server->setCallback (m_callback_type);
164
147
165
148
ROS_INFO (" Forward dynamics solver initialized" );
166
- ROS_INFO (" Forward dynamics solver has control over %i joints" ,
167
- m_number_joints);
149
+ ROS_INFO (" Forward dynamics solver has control over %i joints" , m_number_joints);
168
150
169
151
return true ;
170
152
}
171
153
172
- bool ForwardDynamicsSolver::buildGenericModel () {
154
+ bool ForwardDynamicsSolver::buildGenericModel ()
155
+ {
156
+ // Set all masses and inertias to minimal (yet stable) values.
157
+ double ip_min = 0.000001 ;
158
+ for (size_t i = 0 ; i < m_chain.segments .size (); ++i)
159
+ {
160
+ // Fixed joint segment
161
+ if (m_chain.segments [i].getJoint ().getType () == KDL::Joint::None)
162
+ {
163
+ m_chain.segments [i].setInertia (
164
+ KDL::RigidBodyInertia::Zero ());
165
+ }
166
+ else // relatively moving segment
167
+ {
168
+ m_chain.segments [i].setInertia (
169
+ KDL::RigidBodyInertia (
170
+ m_min, // mass
171
+ KDL::Vector::Zero (), // center of gravity
172
+ KDL::RotationalInertia (
173
+ ip_min, // ixx
174
+ ip_min, // iyy
175
+ ip_min // izz
176
+ // ixy, ixy, iyz default to 0.0
177
+ )));
178
+ }
179
+ }
180
+
181
+ // Only give the last segment a generic mass and inertia.
182
+ // See https://arxiv.org/pdf/1908.06252.pdf for a motivation for this setting.
183
+ double m = 1 ;
184
+ double ip = 1 ;
185
+ m_chain.segments [m_chain.segments .size ()-1 ].setInertia (
186
+ KDL::RigidBodyInertia (
187
+ m,
188
+ KDL::Vector::Zero (),
189
+ KDL::RotationalInertia (ip, ip, ip)));
190
+
191
+ return true ;
192
+ }
193
+
194
+ bool ForwardDynamicsSolver::buildUR5eModel () {
173
195
double mass[6 ] = {1.98 , 3.4445 , 1.437 , 0.871 , 0.805 , 0.261 };
174
196
double centor_of_mass[6 ][3 ] = {
175
- {0.0 , 0.0 , -0.02 }, {-0.11355 , 0.0 , 0.1157 }, {-0.1632 , 0.0 , 0.0238 },
176
- {0.0 , -0.01 , 0.0 }, {0.0 , 0.01 , 0.0 }, {0.0 , 0.0 , -0.02 },
197
+ {0.0 , 0.0 , -0.02 }, {-0.11355 , 0.0 , 0.1157 }, {-0.1632 , 0.0 , 0.0238 }, {0.0 , -0.01 , 0.0 }, {0.0 , 0.01 , 0.0 }, {0.0 , 0.0 , -0.02 },
177
198
};
178
199
double inertia_tensor[6 ][6 ] = {
179
200
// xx, yy, zz, xy, xz, yz
180
- {0.008093166666666665 , 0.008093166666666665 , 0.005625 , 0.0 , 0.0 , 0.0 },
181
- {0.021728491912499998 , 0.021728491912499998 , 0.00961875 , 0.0 , 0.0 , 0.0 },
182
- {0.006544570199999999 , 0.006544570199999999 , 0.00354375 , 0.0 , 0.0 , 0.0 },
183
- {0.0020849999999999996 , 0.0020849999999999996 , 0.00225 , 0.0 , 0.0 , 0.0 },
184
- {0.0020849999999999996 , 0.0020849999999999996 , 0.00225 , 0.0 , 0.0 , 0.0 },
185
- {0.00013626666666666665 , 0.00013626666666666665 , 0.0001792 , 0.0 , 0.0 ,
186
- 0.0 },
201
+ {0.008093166666666665 , 0.008093166666666665 , 0.005625 , 0.0 , 0.0 , 0.0 }, {0.021728491912499998 , 0.021728491912499998 , 0.00961875 , 0.0 , 0.0 , 0.0 },
202
+ {0.006544570199999999 , 0.006544570199999999 , 0.00354375 , 0.0 , 0.0 , 0.0 }, {0.0020849999999999996 , 0.0020849999999999996 , 0.00225 , 0.0 , 0.0 , 0.0 },
203
+ {0.0020849999999999996 , 0.0020849999999999996 , 0.00225 , 0.0 , 0.0 , 0.0 }, {0.00013626666666666665 , 0.00013626666666666665 , 0.0001792 , 0.0 , 0.0 , 0.0 },
187
204
};
188
205
// Set all masses and inertias to minimal (yet stable) values.
189
- double ip_min = 0.000001 ;
206
+ // double ip_min = 0.000001;
190
207
for (size_t i = 0 ; i < m_chain.segments .size (); ++i) {
191
208
// Fixed joint segment
192
209
if (m_chain.segments [i].getJoint ().getType () == KDL::Joint::None) {
193
210
m_chain.segments [i].setInertia (KDL::RigidBodyInertia::Zero ());
194
- } else // relatively moving segment
211
+ } else // relatively moving segment
195
212
{
196
213
m_chain.segments [i].setInertia (KDL::RigidBodyInertia (
197
214
// m_min, // mass
@@ -201,15 +218,15 @@ bool ForwardDynamicsSolver::buildGenericModel() {
201
218
// ip_min // izz
202
219
// // ixy, ixy, iyz default to 0.0
203
220
// )));
204
- mass[i], // mass
221
+ mass[i], // mass
205
222
KDL::Vector (centor_of_mass[i][0 ], centor_of_mass[i][1 ],
206
- centor_of_mass[i][2 ]), // center of gravity
207
- KDL::RotationalInertia (inertia_tensor[i][0 ], // ixx
208
- inertia_tensor[i][1 ], // iyy
209
- inertia_tensor[i][2 ], // izz
210
- inertia_tensor[i][3 ], // ixy
211
- inertia_tensor[i][4 ], // ixz
212
- inertia_tensor[i][5 ] // iyz
223
+ centor_of_mass[i][2 ]), // center of gravity
224
+ KDL::RotationalInertia (inertia_tensor[i][0 ], // ixx
225
+ inertia_tensor[i][1 ], // iyy
226
+ inertia_tensor[i][2 ], // izz
227
+ inertia_tensor[i][3 ], // ixy
228
+ inertia_tensor[i][4 ], // ixz
229
+ inertia_tensor[i][5 ] // iyz
213
230
)));
214
231
}
215
232
}
@@ -218,16 +235,11 @@ bool ForwardDynamicsSolver::buildGenericModel() {
218
235
// See https://arxiv.org/pdf/1908.06252.pdf for a motivation for this setting.
219
236
double m = 1 ;
220
237
double ip = 1 ;
221
- m_chain.segments [m_chain.segments .size () - 1 ].setInertia (
222
- KDL::RigidBodyInertia (m, KDL::Vector::Zero (),
223
- KDL::RotationalInertia (ip, ip, ip)));
238
+ m_chain.segments [m_chain.segments .size () - 1 ].setInertia (KDL::RigidBodyInertia (m, KDL::Vector::Zero (), KDL::RotationalInertia (ip, ip, ip)));
224
239
225
240
return true ;
226
241
}
227
242
228
- void ForwardDynamicsSolver::dynamicReconfigureCallback (IKConfig& config,
229
- uint32_t level) {
230
- m_min = config.link_mass ;
231
- }
243
+ void ForwardDynamicsSolver::dynamicReconfigureCallback (IKConfig &config, uint32_t level) { m_min = config.link_mass ; }
232
244
233
- } // namespace cartesian_controller_base
245
+ } // namespace cartesian_controller_base
0 commit comments