38 const std::shared_ptr<rclcpp_lifecycle::LifecycleNode> & node,
const size_t num_joints,
39 const std::string & robot_description)
41 num_joints_ = num_joints;
47 if (!parameters_.kinematics.plugin_name.empty())
52 if (kinematics_loader_)
57 std::make_shared<pluginlib::ClassLoader<kinematics_interface::KinematicsInterface>>(
58 parameters_.kinematics.plugin_package,
"kinematics_interface::KinematicsInterface");
59 kinematics_ = std::unique_ptr<kinematics_interface::KinematicsInterface>(
60 kinematics_loader_->createUnmanagedInstance(parameters_.kinematics.plugin_name));
62 if (!kinematics_->initialize(
63 robot_description, node->get_node_parameters_interface(),
"kinematics"))
65 return controller_interface::return_type::ERROR;
68 catch (pluginlib::PluginlibException & ex)
71 rclcpp::get_logger(
"AdmittanceRule"),
"Exception while loading the IK plugin '%s': '%s'",
72 parameters_.kinematics.plugin_name.c_str(), ex.what());
73 return controller_interface::return_type::ERROR;
79 rclcpp::get_logger(
"AdmittanceRule"),
80 "A differential IK plugin name was not specified in the config file.");
81 return controller_interface::return_type::ERROR;
85 state_message_.ft_sensor_frame.data = parameters_.ft_sensor.frame.id;
87 return controller_interface::return_type::OK;
93 state_message_.joint_state.name.assign(num_joints,
"");
94 state_message_.joint_state.position.assign(num_joints, 0);
95 state_message_.joint_state.velocity.assign(num_joints, 0);
96 state_message_.joint_state.effort.assign(num_joints, 0);
97 for (
size_t i = 0; i < parameters_.joints.size(); ++i)
99 state_message_.joint_state.name = parameters_.joints;
101 state_message_.mass.data.resize(NUM_CARTESIAN_DOF, 0.0);
102 state_message_.selected_axes.data.resize(NUM_CARTESIAN_DOF, 0);
103 state_message_.damping.data.resize(NUM_CARTESIAN_DOF, 0);
104 state_message_.stiffness.data.resize(NUM_CARTESIAN_DOF, 0);
105 state_message_.wrench_base.header.frame_id = parameters_.kinematics.base;
106 state_message_.admittance_velocity.header.frame_id = parameters_.kinematics.base;
107 state_message_.admittance_acceleration.header.frame_id = parameters_.kinematics.base;
116 wrench_world_.setZero();
117 end_effector_weight_.setZero();
122 return controller_interface::return_type::OK;
149 const trajectory_msgs::msg::JointTrajectoryPoint & current_joint_state,
150 const trajectory_msgs::msg::JointTrajectoryPoint & reference_joint_state)
153 bool success = kinematics_->calculate_link_transform(
154 reference_joint_state.positions, parameters_.ft_sensor.frame.id,
155 admittance_transforms_.ref_base_ft_);
158 success &= kinematics_->calculate_link_transform(
159 current_joint_state.positions, parameters_.ft_sensor.frame.id, admittance_transforms_.base_ft_);
160 success &= kinematics_->calculate_link_transform(
161 current_joint_state.positions, parameters_.kinematics.tip, admittance_transforms_.base_tip_);
162 success &= kinematics_->calculate_link_transform(
163 current_joint_state.positions, parameters_.fixed_world_frame.frame.id,
164 admittance_transforms_.world_base_);
165 success &= kinematics_->calculate_link_transform(
166 current_joint_state.positions, parameters_.gravity_compensation.frame.id,
167 admittance_transforms_.base_cog_);
168 success &= kinematics_->calculate_link_transform(
169 current_joint_state.positions, parameters_.control.frame.id,
170 admittance_transforms_.base_control_);
177 const trajectory_msgs::msg::JointTrajectoryPoint & current_joint_state,
178 const geometry_msgs::msg::Wrench & measured_wrench,
179 const trajectory_msgs::msg::JointTrajectoryPoint & reference_joint_state,
180 const rclcpp::Duration & period, trajectory_msgs::msg::JointTrajectoryPoint & desired_joint_state)
182 const double dt = period.seconds();
184 if (parameters_.enable_parameter_update_without_reactivation)
192 Eigen::Matrix<double, 3, 3> rot_world_sensor =
193 admittance_transforms_.world_base_.rotation() * admittance_transforms_.base_ft_.rotation();
194 Eigen::Matrix<double, 3, 3> rot_world_cog =
195 admittance_transforms_.world_base_.rotation() * admittance_transforms_.base_cog_.rotation();
199 admittance_state_.wrench_base.block<3, 1>(0, 0) =
200 admittance_transforms_.world_base_.rotation().transpose() * wrench_world_.block<3, 1>(0, 0);
201 admittance_state_.wrench_base.block<3, 1>(3, 0) =
202 admittance_transforms_.world_base_.rotation().transpose() * wrench_world_.block<3, 1>(3, 0);
205 vec_to_eigen(current_joint_state.positions, admittance_state_.current_joint_pos);
206 admittance_state_.rot_base_control = admittance_transforms_.base_control_.rotation();
207 admittance_state_.ref_trans_base_ft = admittance_transforms_.ref_base_ft_;
208 admittance_state_.ft_sensor_frame = parameters_.ft_sensor.frame.id;
215 desired_joint_state = reference_joint_state;
216 return controller_interface::return_type::ERROR;
220 for (
size_t i = 0; i < num_joints_; ++i)
222 auto idx =
static_cast<Eigen::Index
>(i);
223 desired_joint_state.positions[i] =
224 reference_joint_state.positions[i] + admittance_state_.joint_pos[idx];
225 desired_joint_state.velocities[i] =
226 reference_joint_state.velocities[i] + admittance_state_.joint_vel[idx];
227 desired_joint_state.accelerations[i] =
228 reference_joint_state.accelerations[i] + admittance_state_.joint_acc[idx];
231 return controller_interface::return_type::OK;
238 auto rot_base_control = admittance_state.rot_base_control;
239 Eigen::Matrix<double, 6, 6> K = Eigen::Matrix<double, 6, 6>::Zero();
240 Eigen::Matrix<double, 3, 3> K_pos = Eigen::Matrix<double, 3, 3>::Zero();
241 Eigen::Matrix<double, 3, 3> K_rot = Eigen::Matrix<double, 3, 3>::Zero();
242 K_pos.diagonal() = admittance_state.stiffness.block<3, 1>(0, 0);
243 K_rot.diagonal() = admittance_state.stiffness.block<3, 1>(3, 0);
248 K_pos = rot_base_control * K_pos * rot_base_control.transpose();
249 K_rot = rot_base_control * K_rot * rot_base_control.transpose();
250 K.block<3, 3>(0, 0) = K_pos;
251 K.block<3, 3>(3, 3) = K_rot;
254 Eigen::Matrix<double, 6, 6> D = Eigen::Matrix<double, 6, 6>::Zero();
255 Eigen::Matrix<double, 3, 3> D_pos = Eigen::Matrix<double, 3, 3>::Zero();
256 Eigen::Matrix<double, 3, 3> D_rot = Eigen::Matrix<double, 3, 3>::Zero();
257 D_pos.diagonal() = admittance_state.damping.block<3, 1>(0, 0);
258 D_rot.diagonal() = admittance_state.damping.block<3, 1>(3, 0);
259 D_pos = rot_base_control * D_pos * rot_base_control.transpose();
260 D_rot = rot_base_control * D_rot * rot_base_control.transpose();
261 D.block<3, 3>(0, 0) = D_pos;
262 D.block<3, 3>(3, 3) = D_rot;
265 Eigen::Isometry3d desired_trans_base_ft;
266 kinematics_->calculate_link_transform(
267 admittance_state.current_joint_pos, admittance_state.ft_sensor_frame, desired_trans_base_ft);
268 Eigen::Matrix<double, 6, 1> X;
269 X.block<3, 1>(0, 0) =
270 desired_trans_base_ft.translation() - admittance_state.ref_trans_base_ft.translation();
271 auto R_ref = admittance_state.ref_trans_base_ft.rotation();
272 auto R_desired = desired_trans_base_ft.rotation();
273 auto R = R_desired * R_ref.transpose();
275 admittance_state.admittance_position.setIdentity();
276 admittance_state.admittance_position.translation() = X.head<3>();
277 admittance_state.admittance_position.linear() = R;
279 auto angle_axis = Eigen::AngleAxisd(R);
280 X.block<3, 1>(3, 0) = angle_axis.angle() * angle_axis.axis();
283 auto X_dot = Eigen::Matrix<double, 6, 1>(admittance_state.admittance_velocity.data());
286 auto F_base = admittance_state.wrench_base;
289 Eigen::Matrix<double, 6, 1> F_control;
290 F_control.block<3, 1>(0, 0) = rot_base_control.transpose() * F_base.block<3, 1>(0, 0);
291 F_control.block<3, 1>(3, 0) = rot_base_control.transpose() * F_base.block<3, 1>(3, 0);
292 F_control = F_control.cwiseProduct(admittance_state.selected_axes);
293 F_base.block<3, 1>(0, 0) = rot_base_control * F_control.block<3, 1>(0, 0);
294 F_base.block<3, 1>(3, 0) = rot_base_control * F_control.block<3, 1>(3, 0);
297 Eigen::Matrix<double, 6, 1> X_ddot =
298 admittance_state.mass_inv.cwiseProduct(F_base - D * X_dot - K * X);
299 bool success = kinematics_->convert_cartesian_deltas_to_joint_deltas(
300 admittance_state.current_joint_pos, X_ddot, admittance_state.ft_sensor_frame,
301 admittance_state.joint_acc);
304 for (int64_t i = 0; i < admittance_state.joint_acc.size(); ++i)
306 admittance_state.joint_acc[i] -=
307 parameters_.admittance.joint_damping * admittance_state.joint_vel[i];
311 admittance_state.joint_vel += (admittance_state.joint_acc) * dt;
312 admittance_state.joint_pos += admittance_state.joint_vel * dt;
315 success &= kinematics_->convert_joint_deltas_to_cartesian_deltas(
316 admittance_state.current_joint_pos, admittance_state.joint_vel,
317 admittance_state.ft_sensor_frame, admittance_state.admittance_velocity);
318 success &= kinematics_->convert_joint_deltas_to_cartesian_deltas(
319 admittance_state.current_joint_pos, admittance_state.joint_acc,
320 admittance_state.ft_sensor_frame, admittance_state.admittance_acceleration);
326 const geometry_msgs::msg::Wrench & measured_wrench,
327 const Eigen::Matrix<double, 3, 3> & sensor_world_rot,
328 const Eigen::Matrix<double, 3, 3> & cog_world_rot)
330 Eigen::Matrix<double, 3, 2, Eigen::ColMajor> new_wrench;
331 new_wrench(0, 0) = measured_wrench.force.x;
332 new_wrench(1, 0) = measured_wrench.force.y;
333 new_wrench(2, 0) = measured_wrench.force.z;
334 new_wrench(0, 1) = measured_wrench.torque.x;
335 new_wrench(1, 1) = measured_wrench.torque.y;
336 new_wrench(2, 1) = measured_wrench.torque.z;
339 Eigen::Matrix<double, 3, 2> new_wrench_base = sensor_world_rot * new_wrench;
342 new_wrench_base(2, 0) -= end_effector_weight_[2];
343 new_wrench_base.block<3, 1>(0, 1) -= (cog_world_rot * cog_pos_).cross(end_effector_weight_);
346 for (Eigen::Index i = 0; i < 6; ++i)
348 wrench_world_(i) = filters::exponentialSmoothing(
349 new_wrench_base(i), wrench_world_(i), parameters_.ft_sensor.filter_coefficient);
355 for (
size_t i = 0; i < NUM_CARTESIAN_DOF; ++i)
357 auto idx =
static_cast<Eigen::Index
>(i);
358 state_message_.stiffness.data[i] = admittance_state_.stiffness[idx];
359 state_message_.damping.data[i] = admittance_state_.damping[idx];
360 state_message_.selected_axes.data[i] =
static_cast<bool>(admittance_state_.selected_axes[idx]);
361 state_message_.mass.data[i] = admittance_state_.mass[idx];
364 for (
size_t i = 0; i < parameters_.joints.size(); ++i)
366 auto idx =
static_cast<Eigen::Index
>(i);
367 state_message_.joint_state.name[i] = parameters_.joints[i];
368 state_message_.joint_state.position[i] = admittance_state_.joint_pos[idx];
369 state_message_.joint_state.velocity[i] = admittance_state_.joint_vel[idx];
370 state_message_.joint_state.effort[i] = admittance_state_.joint_acc[idx];
373 state_message_.wrench_base.wrench.force.x = admittance_state_.wrench_base[0];
374 state_message_.wrench_base.wrench.force.y = admittance_state_.wrench_base[1];
375 state_message_.wrench_base.wrench.force.z = admittance_state_.wrench_base[2];
376 state_message_.wrench_base.wrench.torque.x = admittance_state_.wrench_base[3];
377 state_message_.wrench_base.wrench.torque.y = admittance_state_.wrench_base[4];
378 state_message_.wrench_base.wrench.torque.z = admittance_state_.wrench_base[5];
380 state_message_.admittance_velocity.twist.linear.x = admittance_state_.admittance_velocity[0];
381 state_message_.admittance_velocity.twist.linear.y = admittance_state_.admittance_velocity[1];
382 state_message_.admittance_velocity.twist.linear.z = admittance_state_.admittance_velocity[2];
383 state_message_.admittance_velocity.twist.angular.x = admittance_state_.admittance_velocity[3];
384 state_message_.admittance_velocity.twist.angular.y = admittance_state_.admittance_velocity[4];
385 state_message_.admittance_velocity.twist.angular.z = admittance_state_.admittance_velocity[5];
387 state_message_.admittance_acceleration.twist.linear.x =
388 admittance_state_.admittance_acceleration[0];
389 state_message_.admittance_acceleration.twist.linear.y =
390 admittance_state_.admittance_acceleration[1];
391 state_message_.admittance_acceleration.twist.linear.z =
392 admittance_state_.admittance_acceleration[2];
393 state_message_.admittance_acceleration.twist.angular.x =
394 admittance_state_.admittance_acceleration[3];
395 state_message_.admittance_acceleration.twist.angular.y =
396 admittance_state_.admittance_acceleration[4];
397 state_message_.admittance_acceleration.twist.angular.z =
398 admittance_state_.admittance_acceleration[5];
400 state_message_.admittance_position = tf2::eigenToTransform(admittance_state_.admittance_position);
401 state_message_.admittance_position.header.frame_id = parameters_.kinematics.base;
402 state_message_.admittance_position.child_frame_id =
"admittance_offset";
404 state_message_.ref_trans_base_ft = tf2::eigenToTransform(admittance_state_.ref_trans_base_ft);
405 state_message_.ref_trans_base_ft.header.frame_id = parameters_.kinematics.base;
406 state_message_.ref_trans_base_ft.child_frame_id = parameters_.ft_sensor.frame.id;
408 Eigen::Quaterniond quat(admittance_state_.rot_base_control);
409 state_message_.rot_base_control.w = quat.w();
410 state_message_.rot_base_control.x = quat.x();
411 state_message_.rot_base_control.y = quat.y();
412 state_message_.rot_base_control.z = quat.z();
414 return state_message_;