-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port cartesian_impedance_controller to franka_ros2 example controllers #51
base: humble
Are you sure you want to change the base?
Conversation
Friendly ping @BarisYazici |
Sorry for the delay! I will try to review in short the upcoming days |
franka_example_controllers/src/cartesian_impedance_example_controller.cpp
Outdated
Show resolved
Hide resolved
Can you also create the bringup launch file that starts this controller? |
@@ -0,0 +1,243 @@ | |||
#include "franka_example_controllers/cartesian_impedance_example_controller.hpp" | |||
#include "franka_example_controllers/pseudo_inverse.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Header file is called pseudo_inversion.hpp
// Equilibrium pose subscription | ||
sub_equilibrium_pose_ = get_node()->create_subscription<geometry_msgs::msg::PoseStamped>( | ||
"equilibrium_pose", 20, | ||
std::bind(&FSMImpedanceController::equilibriumPoseCallback, this, std::placeholders::_1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this &FSMImpedanceController coming from? Could you also provide the code for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was related to local class on our project, now equilibriumPoseCallback is memeber of &CartesianImpedanceExampleController
@BarisYazici Thank you for your feedback! I have made the requested changes:
Please let me know if there are any further adjustments needed or if there's anything else you'd like me to address |
...le_controllers/include/franka_example_controllers/cartesian_impedance_example_controller.hpp
Outdated
Show resolved
Hide resolved
...le_controllers/include/franka_example_controllers/cartesian_impedance_example_controller.hpp
Outdated
Show resolved
Hide resolved
...le_controllers/include/franka_example_controllers/cartesian_impedance_example_controller.hpp
Outdated
Show resolved
Hide resolved
...le_controllers/include/franka_example_controllers/cartesian_impedance_example_controller.hpp
Outdated
Show resolved
Hide resolved
...le_controllers/include/franka_example_controllers/cartesian_impedance_example_controller.hpp
Outdated
Show resolved
Hide resolved
franka_example_controllers/src/cartesian_impedance_example_controller.cpp
Outdated
Show resolved
Hide resolved
franka_example_controllers/include/franka_example_controllers/pseudo_inversion.hpp
Outdated
Show resolved
Hide resolved
@AndreasKuhner Thanks for your feedback! I have made the requested changes. Please let me know if there are any further adjustments needed or if there's anything else you'd like me to address |
franka_example_controllers/src/cartesian_impedance_example_controller.cpp
Outdated
Show resolved
Hide resolved
Looks good from my side. I guess we would only need to run it on the robot for testing it :) |
Please add the franka_ros2/franka_example_controllers/CMakeLists.txt Lines 29 to 44 in d3d0fb4
|
Add the arm_id parameter similar to the other launch file examples and pass parameter this to the |
|
||
// pseudoinverse for nullspace handling | ||
Eigen::MatrixXd jacobian_transpose_pinv; | ||
pseudoInverse(jacobian.transpose(), jacobian_transpose_pinv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
based on the definition on PseudoInverse from you:
inline Eigen::MatrixXd pseudoInverse(const Eigen::MatrixXd& M_, bool damped = true) {
double lambda_ = damped ? 0.2 : 0.0;
Eigen::JacobiSVD<Eigen::MatrixXd> svd(M_, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::JacobiSVD<Eigen::MatrixXd>::SingularValuesType sing_vals_ = svd.singularValues();
Eigen::MatrixXd S_ = M_; // copying the dimensions of M_, its content is not needed.
S_.setZero();
for (int i = 0; i < sing_vals_.size(); i++)
S_(i, i) = (sing_vals_(i)) / (sing_vals_(i) * sing_vals_(i) + lambda_ * lambda_);
return svd.matrixV() * S_.transpose() * svd.matrixU().transpose();
}
second parameter should be bool damped
. And the returned value should be the inverted matrix.
Thanks for the review @BarisYazici. Updated |
I think Baris tried to run it on the robot and it didn't work - did you do tests on the robot? |
Yes after fixing all the issues in the PR, it still didn't run on the robot. Did you do any tests on the robot? |
Yes, tested on FR3 and i could access the robot interface, send commands and the robot successfully converged to equilibrium pose (set it manually). I'll provide terminal outputs once i get access to the robot. |
I wrote this because the code you started the PR with was not compiling and the source code was not in the CMakelists.txt. I invested some time to fix the issues with the code and got it in a correctly compiling state. After I tested couple of time with the robot and it was throwing some communication violations. I didn't try to debug further than that. If you say you tried it on the hardware, I will give it another try. But please put all the files necessary to run the example in this PR. You mention a node to publish equilibrium pose. Could you also put it in this PR? I noticed in the image of the terminal output your example controller name is force_impedance_control. Is it the same setup you are using in the tests? Please make sure it's exactly the same. |
tau_d << tau_task + tau_nullspace + coriolis; | ||
|
||
// saturate the commanded torque to joint limits | ||
tau_d << saturateTorqueRate(tau_d, tau_j_d); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo with tau_j_d -> tau_J_d
} | ||
|
||
controller_interface::return_type CartesianImpedanceExampleController::update( | ||
const rclcpp::Time& time, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment time and period out to make linter happy
const rclcpp::Time& time, | |
controller_interface::return_type CartesianImpedanceExampleController::update( | |
const rclcpp::Time& /*time*/, | |
const rclcpp::Duration& /*period*/) { |
@@ -47,6 +47,10 @@ controller_manager: | |||
franka_robot_state_broadcaster: | |||
type: franka_robot_state_broadcaster/FrankaRobotStateBroadcaster | |||
|
|||
cartesian_impedance_example_controller: | |||
type: franka_example_controllers::CartesianImpedanceExampleController |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type: franka_example_controllers::CartesianImpedanceExampleController | |
type: franka_example_controllers/CartesianImpedanceExampleController |
|
||
for (int i = 0; i < num_joints; i++) { | ||
command_interfaces_[i].set_value(tau_d[i]); | ||
std::cout << tau_d[i] << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove std::cout
There is an error occurs because
How to fix this? |
To my knowledge, there is no |
Description:
This PR offers a high level port of Cartesian impedance example controller provided in Franka ROS1 and requests feedback.
ros humble run test
The port was basically based on :
Architecture:
Controller class is implemented based on ROS2 Control Controller Interface Class :
all parameters defining their default values are.
`
`
`
`
Real-time update() method is pretty much ported from ROS1 version (requires release build : DCMAKE_BUILD_TYPE=Release)
lifecycle management methods :
on_configure() and on_deactivate() : Nothing special here, first to configures controller and second is called when controller is deactivated (stopped).
on_activate() - called when controller is activated (started), I think this method is the equivalent functionality to the starting() method in ROS 1, since it is called when a controller is activated, and this is a suitable place to perform actions
that need to occur just before the controller starts updating its state.
Notes :
Questions :
I need feedback/confirmation about those points if possible :
Thanks in advance !