Skip to content

Commit 16f33e8

Browse files
authored
Merge pull request #7 from lucabeber/logging
Logging is enabled if matlogger is found and LOGGIN flas is set to ON
2 parents 48ef9f7 + 5a7edd6 commit 16f33e8

File tree

4 files changed

+83
-34
lines changed

4 files changed

+83
-34
lines changed

cartesian_impedance_controller/CMakeLists.txt

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,39 @@ project(cartesian_impedance_controller)
33

44
set(CMAKE_CXX_STANDARD 17)
55
set(ADDITIONAL_COMPILE_OPTIONS -Wall -Wextra -Wpedantic -Wno-unused-parameter)
6+
7+
# Optional parameter to enable logging, only if MatLogger2 is found
8+
# Refer to https://github.com/ADVRHumanoids/MatLogger2 to install MatLogger2
9+
# output file is /tmp/cart_impedance_log<timestamp>.mat
10+
option(LOGGING "Enable logging" ON)
611
add_compile_options(${ADDITIONAL_COMPILE_OPTIONS})
7-
# build in release
12+
13+
# Build in release mode if not specified
814
if(NOT CMAKE_BUILD_TYPE)
915
set(CMAKE_BUILD_TYPE Release)
1016
endif()
17+
1118
find_package(Eigen3 3.3 REQUIRED NO_MODULE)
1219
add_definitions(-DEIGEN_MPL2_ONLY)
1320
find_package(ament_cmake REQUIRED)
1421
find_package(rclcpp REQUIRED)
1522
find_package(effort_controller_base REQUIRED)
1623
find_package(debug_msg REQUIRED)
1724

25+
# Try to find MatLogger2 if logging is enabled
26+
if (LOGGING)
27+
find_package(matlogger2 QUIET)
28+
if (matlogger2_FOUND)
29+
message(STATUS "MatLogger2 found: Logging enabled")
30+
set(LOGGING_ENABLED TRUE)
31+
else()
32+
message(WARNING "MatLogger2 not found: Logging disabled")
33+
set(LOGGING_ENABLED FALSE)
34+
endif()
35+
else()
36+
set(LOGGING_ENABLED FALSE)
37+
endif()
38+
1839
# Convenience variable for dependencies
1940
set(THIS_PACKAGE_INCLUDE_DEPENDS
2041
rclcpp
@@ -23,6 +44,11 @@ set(THIS_PACKAGE_INCLUDE_DEPENDS
2344
debug_msg
2445
)
2546

47+
if (LOGGING_ENABLED)
48+
list(APPEND THIS_PACKAGE_INCLUDE_DEPENDS matlogger2)
49+
add_compile_definitions(LOGGING)
50+
endif()
51+
2652
ament_export_dependencies(
2753
${THIS_PACKAGE_INCLUDE_DEPENDS}
2854
)
@@ -50,42 +76,30 @@ ament_target_dependencies(${PROJECT_NAME}
5076
# Prevent pluginlib from using boost
5177
target_compile_definitions(${PROJECT_NAME} PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
5278

79+
if (LOGGING_ENABLED)
80+
target_link_libraries(${PROJECT_NAME} matlogger2::matlogger2)
81+
endif()
82+
5383
#--------------------------------------------------------------------------------
5484
# Install and export
5585
#--------------------------------------------------------------------------------
5686

5787
pluginlib_export_plugin_description_file(controller_interface cartesian_impedance_controller_plugin.xml)
5888

59-
# Note: The workflow as described here https://docs.ros.org/en/foxy/How-To-Guides/Ament-CMake-Documentation.html#building-a-library
60-
# does not work for me.
61-
# I'm not sure what's the problem right now, but I need to out-comment the
62-
# lines below to achieve a correct symlink-install.
63-
64-
#ament_export_targets(my_targets_from_this_package HAS_LIBRARY_TARGET)
65-
6689
install(
6790
DIRECTORY include/
6891
DESTINATION include
6992
)
7093

7194
install(
7295
TARGETS ${PROJECT_NAME}
73-
#EXPORT my_targets_from_this_package
7496
LIBRARY DESTINATION lib
7597
ARCHIVE DESTINATION lib
7698
RUNTIME DESTINATION bin
77-
#INCLUDES DESTINATION include
7899
)
79100

80-
# Note: For the target based workflow, they seem to be superfluous.
81-
# But since that doesn't work yet, I'll add them just in case.
82-
# I took the joint_trajectory_controller as inspiration.
83101
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})
84-
ament_export_include_directories(
85-
include
86-
)
87-
ament_export_libraries(
88-
${PROJECT_NAME}
89-
)
102+
ament_export_include_directories(include)
103+
ament_export_libraries(${PROJECT_NAME})
90104

91105
ament_package()

cartesian_impedance_controller/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ cartesian_impedance_controller:
2121
robot_base_link: "base_link"
2222
ft_sensor_ref_link: "sensor_link"
2323
compliance_ref_link: "compliance_link"
24+
max_impedance_force: 10.0 # (N) maximum task force
25+
delta_tau_max: 1.0 # (Nm) maximum torque increment in one control cycle
2426
joints:
2527
- joint1
2628
- joint2

cartesian_impedance_controller/include/cartesian_impedance_controller/cartesian_impedance_controller.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
#include "effort_controller_base/Utility.h"
1111
#include "geometry_msgs/msg/pose_stamped.hpp"
1212
#include "geometry_msgs/msg/wrench_stamped.hpp"
13+
14+
1315
#define DEBUG 0
16+
#if LOGGING
17+
#include <matlogger2/matlogger2.h>
18+
#endif
1419

1520
namespace cartesian_impedance_controller {
1621

@@ -64,6 +69,7 @@ class CartesianImpedanceController
6469
// ctrl::Matrix6D m_cartesian_damping;
6570
double m_null_space_stiffness;
6671
double m_null_space_damping;
72+
double m_max_impendance_force;
6773
ctrl::Vector6D m_target_wrench;
6874

6975
private:
@@ -80,6 +86,9 @@ class CartesianImpedanceController
8086
rclcpp::Subscription<geometry_msgs::msg::PoseStamped>::SharedPtr
8187
m_target_frame_subscriber;
8288
rclcpp::Publisher<debug_msg::msg::Debug>::SharedPtr m_data_publisher;
89+
#if LOGGING
90+
XBot::MatLogger2::Ptr m_logger;
91+
#endif
8392
KDL::Frame m_target_frame;
8493
ctrl::Vector6D m_ft_sensor_wrench;
8594
std::string m_ft_sensor_ref_link;

cartesian_impedance_controller/src/cartesian_impedance_controller.cpp

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ CartesianImpedanceController::on_init() {
2626
auto_declare<double>("stiffness.rot_x", default_rot_stiff);
2727
auto_declare<double>("stiffness.rot_y", default_rot_stiff);
2828
auto_declare<double>("stiffness.rot_z", default_rot_stiff);
29+
auto_declare<double>("max_impedance_force", 70.0); //TODO
2930

3031
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::
3132
CallbackReturn::SUCCESS;
@@ -72,8 +73,8 @@ CartesianImpedanceController::on_configure(
7273
tmp[4] = 2 * sqrt(tmp[4]);
7374
tmp[5] = 2 * sqrt(tmp[5]);
7475

75-
// m_cartesian_damping = tmp.asDiagonal();
76-
76+
m_max_impendance_force =
77+
get_node()->get_parameter("max_impedance_force").as_double(); //TODO
7778
// Set nullspace stiffness
7879
m_null_space_stiffness =
7980
get_node()->get_parameter("nullspace_stiffness").as_double();
@@ -136,7 +137,10 @@ CartesianImpedanceController::on_activate(
136137
m_q_starting_pose = Base::m_joint_positions.data;
137138

138139
m_target_wrench = ctrl::Vector6D::Zero();
139-
140+
#if LOGGING
141+
m_logger = XBot::MatLogger2::MakeLogger("/tmp/cart_impedance_log");
142+
m_logger->set_buffer_mode(XBot::VariableBuffer::Mode::circular_buffer);
143+
#endif
140144
return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::
141145
CallbackReturn::SUCCESS;
142146
}
@@ -154,8 +158,9 @@ CartesianImpedanceController::on_deactivate(
154158
CallbackReturn::SUCCESS;
155159
}
156160

157-
controller_interface::return_type CartesianImpedanceController::update(
158-
const rclcpp::Time &time, const rclcpp::Duration &period) {
161+
controller_interface::return_type
162+
CartesianImpedanceController::update(const rclcpp::Time &time,
163+
const rclcpp::Duration &period) {
159164
// Update joint states
160165
Base::updateJointStates();
161166

@@ -183,7 +188,7 @@ ctrl::Vector6D CartesianImpedanceController::computeMotionError() {
183188
// Use Rodrigues Vector for a compact representation of orientation errors
184189
// Only for angles within [0,Pi)
185190
KDL::Vector rot_axis = KDL::Vector::Zero();
186-
double angle = error_kdl.M.GetRotAngle(rot_axis); // rot_axis is normalized
191+
double angle = error_kdl.M.GetRotAngle(rot_axis); // rot_axis is normalized
187192
double distance = error_kdl.p.Normalize();
188193

189194
// Clamp maximal tolerated error.
@@ -209,6 +214,11 @@ ctrl::Vector6D CartesianImpedanceController::computeMotionError() {
209214
}
210215

211216
ctrl::VectorND CartesianImpedanceController::computeTorque() {
217+
// Redefine joints velocities in Eigen format
218+
ctrl::VectorND q = Base::m_joint_positions.data;
219+
ctrl::VectorND q_dot = Base::m_joint_velocities.data;
220+
ctrl::VectorND q_null_space(Base::m_joint_number);
221+
212222
// Compute the forward kinematics
213223
Base::m_fk_solver->JntToCart(Base::m_joint_positions, m_current_frame);
214224

@@ -226,14 +236,8 @@ ctrl::VectorND CartesianImpedanceController::computeTorque() {
226236

227237
KDL::JntSpaceInertiaMatrix M(Base::m_joint_number);
228238
m_dyn_solver->JntToMass(Base::m_joint_positions, M);
229-
230239
Eigen::MatrixXd Lambda = (jac * M.data.inverse() * jac.transpose()).inverse();
231240

232-
// Redefine joints velocities in Eigen format
233-
ctrl::VectorND q = Base::m_joint_positions.data;
234-
ctrl::VectorND q_dot = Base::m_joint_velocities.data;
235-
ctrl::VectorND q_null_space(Base::m_joint_number);
236-
237241
// Compute the motion error
238242
ctrl::Vector6D motion_error = computeMotionError();
239243

@@ -254,12 +258,12 @@ ctrl::VectorND CartesianImpedanceController::computeTorque() {
254258
Base::displayInBaseLink(m_cartesian_stiffness, Base::m_end_effector_link);
255259

256260
Eigen::MatrixXd K_d = base_link_stiffness;
257-
Eigen::VectorXd damping_correction = 5.0 * Eigen::VectorXd::Ones(6);
261+
Eigen::VectorXd damping_correction = 3.0 * Eigen::VectorXd::Ones(6);
258262
auto D_d = compute_correct_damping(Lambda, K_d, 1.0);
259263

260264
// add a small damping correction to the diagonal of D_d to account for model
261265
// inaccuracies, remove this loop if you face strange behavior
262-
for (int i = 5; i < 6; i++) {
266+
for (int i = 3; i < 6; i++) {
263267
D_d(i, i) = D_d(i, i) + damping_correction(3);
264268
}
265269
Eigen::VectorXd stiffness_torque = jac.transpose() * (K_d * motion_error);
@@ -320,6 +324,26 @@ ctrl::VectorND CartesianImpedanceController::computeTorque() {
320324
}
321325
}
322326
m_data_publisher->publish(debug_msg);
327+
#endif
328+
#if LOGGING
329+
Eigen::VectorXd Force = K_d * motion_error - D_d * (jac * q_dot);
330+
// lambda that computes condition number
331+
auto compute_condition_number = [](const Eigen::MatrixXd &matrix) {
332+
Eigen::JacobiSVD<Eigen::MatrixXd> svd(matrix);
333+
Eigen::VectorXd singular_values = svd.singularValues();
334+
return singular_values(0) / singular_values(singular_values.size() - 1);
335+
};
336+
m_logger->add("condition_number mass", compute_condition_number(M.data));
337+
m_logger->add("condition_number jac", compute_condition_number(jac));
338+
for (int i = 0; i < 7; i++) {
339+
m_logger->add("stiffness_" + std::to_string(i), stiffness_torque(i));
340+
m_logger->add("damping_" + std::to_string(i), damping_torque(i));
341+
m_logger->add("coriolis_" + std::to_string(i), tau_coriolis(i));
342+
m_logger->add("nullspace_" + std::to_string(i), tau_null(i));
343+
if (i < 6) {
344+
m_logger->add("impedance_force_" + std::to_string(i), Force(i));
345+
}
346+
}
323347
#endif
324348
// Compute the torque to achieve the desired force
325349
tau_ext = jac.transpose() * m_target_wrench;
@@ -365,7 +389,7 @@ void CartesianImpedanceController::targetFrameCallback(
365389
KDL::Vector(target->pose.position.x, target->pose.position.y,
366390
target->pose.position.z));
367391
}
368-
} // namespace cartesian_impedance_controller
392+
} // namespace cartesian_impedance_controller
369393

370394
// Pluginlib
371395
#include <pluginlib/class_list_macros.hpp>

0 commit comments

Comments
 (0)