Skip to content

Commit cd76b55

Browse files
author
Hydran00
committed
hard stopping
1 parent f020929 commit cd76b55

File tree

1 file changed

+88
-59
lines changed

1 file changed

+88
-59
lines changed

cartesian_impedance_controller/src/cartesian_impedance_controller.cpp

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,12 @@ CartesianImpedanceController::on_configure(
114114
get_node()->get_name() + std::string("/data"), 1);
115115

116116
#if LOGGING
117-
m_logger = XBot::MatLogger2::MakeLogger("/tmp/cart_impedance_log500");
117+
XBot::MatLogger2::Options opt;
118+
opt.default_buffer_size = 1e5; // set default buffer size
119+
opt.enable_compression = true;
120+
m_logger = XBot::MatLogger2::MakeLogger("/tmp/cart_impedance.mat", opt);
118121
m_logger->set_buffer_mode(XBot::VariableBuffer::Mode::circular_buffer);
122+
119123
// subscribe to lbr_fri_idl/msg/LBRState
120124
m_state_subscriber =
121125
get_node()->create_subscription<lbr_fri_idl::msg::LBRState>(
@@ -166,6 +170,10 @@ CartesianImpedanceController::on_activate(
166170
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
167171
CartesianImpedanceController::on_deactivate(
168172
const rclcpp_lifecycle::State &previous_state) {
173+
// call logger destructor
174+
#if LOGGING
175+
m_logger.reset();
176+
#endif
169177
// Stop drifting by sending zero joint velocities
170178
Base::computeJointEffortCmds(ctrl::Vector6D::Zero());
171179
// Base::writeJointEffortCmds(ctrl::VectorND::Zero());
@@ -232,6 +240,11 @@ ctrl::Vector6D CartesianImpedanceController::computeMotionError() {
232240
return error;
233241
}
234242
void CartesianImpedanceController::computeTargetPos() {
243+
244+
// Compute the jacobian
245+
Base::m_jnt_to_jac_solver->JntToJac(Base::m_joint_positions,
246+
Base::m_jacobian);
247+
ctrl::MatrixND jac = Base::m_jacobian.data;
235248
// Compute the forward kinematics
236249
Base::m_fk_solver->JntToCart(Base::m_joint_positions, m_current_frame);
237250

@@ -256,82 +269,103 @@ void CartesianImpedanceController::computeTargetPos() {
256269
Eigen::Vector3d n_d = target_M.col(0);
257270
Eigen::Vector3d s_d = target_M.col(1);
258271
Eigen::Vector3d a_d = target_M.col(2);
272+
Eigen::Vector3d n_e, s_e, a_e;
259273

260-
Eigen::Vector3d angular_err;
261-
Eigen::Vector3d linear_err;
262-
Eigen::VectorXd error(6);
263-
error.setOnes();
274+
Eigen::Vector3d e_o;
275+
Eigen::Vector3d e_p;
276+
Eigen::Vector3d error_pos, error_rot, old_error_pos, old_error_rot;
277+
old_error_pos.setZero();
278+
old_error_rot.setZero();
264279
KDL::JntArray q_dot_des(Base::m_joint_number);
265280
q_dot_des.data.setZero();
266281

267-
double x_error_norm = 100.0;
268282
int num_steps = 0;
269-
const double K_p = 1.0;
270-
const double K_o = 100.0;
271-
const double eps_condition = 0.001;
272-
while (num_steps < 15 && x_error_norm > eps_condition) {
273-
num_steps++;
274-
275-
// Compute linear velocity
276-
Eigen::Vector3d linear_err(m_target_frame.p.x() - current_simulated_frame.p.x(),
277-
m_target_frame.p.y() - current_simulated_frame.p.y(),
278-
m_target_frame.p.z() - current_simulated_frame.p.z());
279-
Eigen::Vector3d linear_vel = linear_err / deltaT;
280-
281-
// Compute rotation error
282-
Eigen::Matrix<double, 3, 3> current_M(current_simulated_frame.M.data);
283-
Eigen::Vector3d n_e = current_M.col(0);
284-
Eigen::Vector3d s_e = current_M.col(1);
285-
Eigen::Vector3d a_e = current_M.col(2);
286-
Eigen::Vector3d angular_err =
287-
-0.5 * (n_e.cross(n_d) + s_e.cross(s_d) + a_e.cross(a_d));
283+
const double init_K_p = 5.0;
284+
const double init_K_o = 20.0;
285+
double K_p = init_K_p;
286+
double K_o = init_K_o;
287+
const double eps_condition_pos = 0.0001;
288+
const double eps_condition_rot = 0.0005;
289+
const double eps_condition_grad_pos = 1e-5;
290+
const double eps_condition_grad_rot = 2e-5;
291+
const int max_steps = 1000;
292+
// lambda for skew
293+
auto S = [](const Eigen::Vector3d &v) {
294+
Eigen::Matrix3d S;
295+
S << 0, -v(2), v(1), v(2), 0, -v(0), -v(1), v(0), 0;
296+
return S;
297+
};
298+
// while (num_steps < 15 && x_error_norm > eps_condition) {
299+
for (int num_steps = 0; num_steps < max_steps; num_steps++) {
300+
// Forward kinematics update
301+
Base::m_fk_solver->JntToCart(q_des, current_simulated_frame);
288302

303+
// Update error AFTER applying q_des
304+
e_p << m_target_frame.p.x() - current_simulated_frame.p.x(),
305+
m_target_frame.p.y() - current_simulated_frame.p.y(),
306+
m_target_frame.p.z() - current_simulated_frame.p.z();
307+
auto current_M =
308+
Eigen::Matrix<double, 3, 3>(current_simulated_frame.M.data);
309+
n_e = current_M.col(0);
310+
s_e = current_M.col(1);
311+
a_e = current_M.col(2);
312+
e_o = -0.5 * (n_e.cross(n_d) + s_e.cross(s_d) + a_e.cross(a_d));
313+
Eigen::MatrixXd L =
314+
-0.5 * (S(n_d) * S(n_e) + S(s_d) * S(s_e) + S(a_d) * S(a_e));
315+
// Compute norm of error
316+
error_pos = e_p;
317+
error_rot = e_o;
318+
auto L_damped = L + 0.01 * Eigen::Matrix3d::Identity();
319+
Eigen::Vector3d ang_vel = L_damped.inverse() * K_o * e_o;
320+
// if (error_pos.norm() < eps_condition_pos &&
321+
// error_rot.norm() < eps_condition_rot) {
322+
if ((((error_pos - old_error_pos).norm() < eps_condition_grad_pos &&
323+
(error_rot - old_error_rot).norm() < eps_condition_grad_rot)) ||
324+
((error_pos.norm() < eps_condition_pos &&
325+
error_rot.norm() < eps_condition_rot))) {
326+
RCLCPP_WARN(get_node()->get_logger(),
327+
"Met ending condition after %d steps", num_steps);
328+
break;
329+
} else {
330+
RCLCPP_WARN_THROTTLE(get_node()->get_logger(), *get_node()->get_clock(),
331+
300, "%d | Error pos: %f %f %f, Error rot: %f %f %f",
332+
num_steps, error_pos(0), error_pos(1), error_pos(2),
333+
error_rot(0), error_rot(1), error_rot(2));
334+
}
335+
old_error_pos = error_pos;
336+
old_error_rot = error_rot;
289337
// Define twist
290338
KDL::Twist v_d;
291-
v_d.vel = K_p * KDL::Vector(linear_vel(0), linear_vel(1), linear_vel(2));
292-
v_d.rot = K_o * KDL::Vector(angular_err(0), angular_err(1), angular_err(2));
339+
v_d.vel = K_p * KDL::Vector(e_p(0), e_p(1), e_p(2));
340+
v_d.rot = KDL::Vector(ang_vel(0), ang_vel(1), ang_vel(2));
293341

294342
// Solve for joint velocities
295343
if (Base::m_ik_solver_vel_nso->CartToJnt(q_des, v_d, q_dot_des) < 0) {
296344
RCLCPP_ERROR(get_node()->get_logger(), "Could not find IK nso solution");
297345
return;
298346
}
299-
300-
// Integrate q_des
347+
// RCLCPP_INFO("q_des before: %f %f %f %f %f %f %f", q_des(0), q_des(1),
348+
// q_des(2), q_des(3), q_des(4), q_des(5), q_des(6)); Integrate q_des
301349
for (int i = 0; i < Base::m_joint_number; i++) {
302350
q_des(i) += q_dot_des(i) * deltaT;
303351
}
304-
305-
// Forward kinematics update
306-
Base::m_fk_solver->JntToCart(q_des, current_simulated_frame);
307-
308-
// Update error AFTER applying q_des
309-
linear_err << m_target_frame.p.x() - current_simulated_frame.p.x(),
310-
m_target_frame.p.y() - current_simulated_frame.p.y(),
311-
m_target_frame.p.z() - current_simulated_frame.p.z();
312-
current_M = Eigen::Matrix<double, 3, 3>(current_simulated_frame.M.data);
313-
n_e = current_M.col(0);
314-
s_e = current_M.col(1);
315-
a_e = current_M.col(2);
316-
angular_err = -0.5 * (n_e.cross(n_d) + s_e.cross(s_d) + a_e.cross(a_d));
317-
318-
// Compute norm of error
319-
error.head(3) = linear_err;
320-
error.tail(3) = angular_err;
321-
x_error_norm = error.norm();
352+
// RCLCPP_INFO("q_des after: %f %f %f %f %f %f %f", q_des(0), q_des(1),
353+
// q_des(2), q_des(3), q_des(4), q_des(5), q_des(6));
354+
K_p = std::max(0.1 * init_K_p, init_K_p * std::exp(-0.01 * num_steps));
355+
K_o = std::max(0.1 * init_K_o, init_K_o * std::exp(-0.01 * num_steps));
322356
}
323357

324358
// RCLCPP_INFO(get_node()->get_logger(), "angular_err: %f %f %f ~ Steps: %d",
325359
// angular_err(0), angular_err(1), angular_err(2), num_steps);
326-
if (num_steps != 1 && num_steps != 500) {
327-
RCLCPP_WARN(get_node()->get_logger(), "STEPS: %d", num_steps);
328-
return;
329-
} else {
330-
RCLCPP_INFO(get_node()->get_logger(), "STEPS: %d", num_steps);
331-
}
360+
// if (num_steps != 1 && num_steps != 500) {
361+
// RCLCPP_WARN(get_node()->get_logger(), "STEPS: %d", num_steps);
362+
// return;
363+
// } else {
364+
// RCLCPP_INFO(get_node()->get_logger(), "STEPS: %d", num_steps);
365+
// }
332366
// RCLCPP_WARN(get_node()->get_logger(), "STEPS: %d", num_steps);
333367

334-
m_target_joint_position = q_des.data;
368+
m_target_joint_position = 0.9 * Base::m_joint_positions.data + 0.1 * q_des.data;
335369
// alpha * current_position + (1.0 - alpha) * desired_joint_position;
336370

337371
#if LOGGING
@@ -359,11 +393,6 @@ void CartesianImpedanceController::computeTargetPos() {
359393
std::end(m_state.commanded_torque));
360394
m_logger->add("commanded_torque", commanded_torque);
361395

362-
// Compute the jacobian
363-
Base::m_jnt_to_jac_solver->JntToJac(Base::m_joint_positions,
364-
Base::m_jacobian);
365-
ctrl::MatrixND jac = Base::m_jacobian.data;
366-
367396
auto compute_condition_number = [](const Eigen::MatrixXd &matrix) {
368397
Eigen::JacobiSVD<Eigen::MatrixXd> svd(matrix);
369398
Eigen::VectorXd singular_values = svd.singularValues();

0 commit comments

Comments
 (0)