Skip to content

Commit da805ab

Browse files
AlexD15216yibodanielsanjoseproCopilot
authored
feat: Fix Cartesian Controller to work with respect to the base_frame indicated in the parameters and not just world frame (#10)
* now the cartesian controller can handle the desired pose in base_frame instead of world frame defined in urdf * Include description of new attributes Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Removing a few old comments --------- Co-authored-by: yibo <yibo.di@iis.fraunhofer.de> Co-authored-by: Daniel San José Pro <42489409+danielsanjosepro@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 4e67d51 commit da805ab

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

include/crisp_controllers/cartesian_controller.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,15 @@ class CartesianController
258258
* @return true if publisher count is safe (<=1), false otherwise
259259
*/
260260
bool check_topic_publisher_count(const std::string& topic_name);
261+
262+
/**
263+
* @brief End-effector pose expressed in the base frame (base_frame)
264+
*/
265+
pinocchio::SE3 end_effector_pose_b;
266+
/**
267+
* @brief Pinocchio frame ID for params_.base_frame
268+
*/
269+
int base_frame_id;
261270
};
262271

263272
} // namespace crisp_controllers

src/cartesian_controller.cpp

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,15 @@ CartesianController::update(const rclcpp::Time &time,
6363
model_.getJointId(joint_name); // pinocchio joind id might be different
6464
auto joint = model_.joints[joint_id];
6565

66-
/*q[i] = exponential_moving_average(q[i], state_interfaces_[i].get_value(),*/
67-
/* params_.filter.q);*/
6866
q[i] = state_interfaces_[i].get_value();
69-
if (continous_joint_types.count(
70-
joint.shortname())) { // Then we are handling a continous
71-
// joint that is SO(2)
67+
if (continous_joint_types.count(joint.shortname())) {
68+
// Then we are handling a continous joint that is SO(2)
7269
q_pin[joint.idx_q()] = std::cos(q[i]);
7370
q_pin[joint.idx_q() + 1] = std::sin(q[i]);
74-
} else { // simple revolute joint case
71+
} else {
72+
// simple revolute joint case
7573
q_pin[joint.idx_q()] = q[i];
7674
}
77-
/*dq[i] = exponential_moving_average(*/
78-
/* dq[i], state_interfaces_[num_joints + i].get_value(),*/
79-
/* params_.filter.dq);*/
8075
dq[i] = state_interfaces_[num_joints + i].get_value();
8176
}
8277

@@ -94,24 +89,16 @@ CartesianController::update(const rclcpp::Time &time,
9489
pinocchio::log6(target_pose_), pinocchio::log6(new_target_pose),
9590
params_.filter.target_pose));
9691

97-
/*target_pose_ = pinocchio::SE3(target_orientation_.toRotationMatrix(),
98-
* target_position_);*/
9992
end_effector_pose = data_.oMf[end_effector_frame_id];
93+
const pinocchio::SE3 base_frame_pose = data_.oMf[base_frame_id];
94+
95+
end_effector_pose_b = base_frame_pose.inverse() * end_effector_pose;
10096

10197
// We consider translation and rotation separately to avoid unatural screw
10298
// motions
103-
if (params_.use_local_jacobian) {
104-
error.head(3) =
105-
end_effector_pose.rotation().transpose() *
106-
(target_pose_.translation() - end_effector_pose.translation());
107-
error.tail(3) = pinocchio::log3(end_effector_pose.rotation().transpose() *
108-
target_pose_.rotation());
109-
} else {
110-
error.head(3) =
111-
target_pose_.translation() - end_effector_pose.translation();
112-
error.tail(3) = pinocchio::log3(target_pose_.rotation() *
113-
end_effector_pose.rotation().transpose());
114-
}
99+
error.head(3) = target_pose_.translation() - end_effector_pose_b.translation();
100+
error.tail(3) = pinocchio::log3(target_pose_.rotation() * end_effector_pose_b.rotation().transpose());
101+
115102

116103
if (params_.limit_error) {
117104
max_delta_ << params_.task.error_clip.x, params_.task.error_clip.y, params_.task.error_clip.z,
@@ -120,11 +107,19 @@ CartesianController::update(const rclcpp::Time &time,
120107
}
121108

122109
J.setZero();
123-
auto reference_frame = params_.use_local_jacobian
124-
? pinocchio::ReferenceFrame::LOCAL
125-
: pinocchio::ReferenceFrame::WORLD;
126-
pinocchio::computeFrameJacobian(model_, data_, q_pin, end_effector_frame_id,
127-
reference_frame, J);
110+
if (params_.use_local_jacobian) {
111+
Eigen::MatrixXd J_local(6, model_.nv);
112+
pinocchio::computeFrameJacobian(model_, data_, q_pin, end_effector_frame_id,
113+
pinocchio::ReferenceFrame::LOCAL, J_local);
114+
const Eigen::Matrix<double,6,6> Ad_be = end_effector_pose_b.toActionMatrix();
115+
J.noalias() = Ad_be * J_local;
116+
} else {
117+
Eigen::MatrixXd J_world(6, model_.nv);
118+
pinocchio::computeFrameJacobian(model_, data_, q_pin, end_effector_frame_id,
119+
pinocchio::ReferenceFrame::WORLD, J_world);
120+
const Eigen::Matrix<double,6,6> Ad_bw = base_frame_pose.inverse().toActionMatrix();
121+
J.noalias() = Ad_bw * J_world;
122+
}
128123

129124
Eigen::MatrixXd J_pinv(model_.nv, 6);
130125
J_pinv = pseudo_inverse(J, params_.nullspace.regularization);
@@ -159,7 +154,7 @@ CartesianController::update(const rclcpp::Time &time,
159154
}
160155

161156
if (model_.nq != model_.nv) {
162-
// TODO: Then we have some continouts joints, not being handled for now
157+
// TODO: Joint liimits for continous joints not implemented yet
163158
tau_joint_limits = Eigen::VectorXd::Zero(model_.nv);
164159
} else {
165160
tau_joint_limits = get_joint_limit_torque(q, model_.lowerPositionLimit,
@@ -197,8 +192,6 @@ CartesianController::update(const rclcpp::Time &time,
197192
if (params_.limit_torques) {
198193
tau_d = saturateTorqueRate(tau_d, tau_previous, params_.max_delta_tau);
199194
}
200-
/*tau_d = exponential_moving_average(tau_d, tau_previous,*/
201-
/* params_.filter.output_torque);*/
202195

203196
if (not params_.stop_commands) {
204197
for (size_t i = 0; i < num_joints; ++i) {
@@ -308,6 +301,7 @@ CallbackReturn CartesianController::on_configure(
308301
}
309302

310303
end_effector_frame_id = model_.getFrameId(params_.end_effector_frame);
304+
base_frame_id = model_.getFrameId(params_.base_frame);
311305
q = Eigen::VectorXd::Zero(model_.nv);
312306
q_pin = Eigen::VectorXd::Zero(model_.nq);
313307
dq = Eigen::VectorXd::Zero(model_.nv);
@@ -477,8 +471,13 @@ CallbackReturn CartesianController::on_activate(
477471

478472
end_effector_pose = data_.oMf[end_effector_frame_id];
479473

480-
target_position_ = end_effector_pose.translation();
481-
target_orientation_ = Eigen::Quaterniond(end_effector_pose.rotation());
474+
const pinocchio::SE3 T_wb = data_.oMf[base_frame_id];
475+
const pinocchio::SE3 T_bw = T_wb.inverse();
476+
477+
end_effector_pose_b = T_bw * end_effector_pose;
478+
479+
target_position_ = end_effector_pose_b.translation();
480+
target_orientation_ = Eigen::Quaterniond(end_effector_pose_b.rotation());
482481
target_pose_ =
483482
pinocchio::SE3(target_orientation_.toRotationMatrix(), target_position_);
484483

0 commit comments

Comments
 (0)