-
Notifications
You must be signed in to change notification settings - Fork 15
Implementation of new skill to apply joint torque #19
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
base: master
Are you sure you want to change the base?
Changes from all commits
93d8721
8b6b9ed
f1cbf7c
777778e
ab44f03
8ca90e5
c59f430
0c60399
4ca4162
f58106a
2478965
69861be
3778c32
1af8538
d3a3914
8c7a9a2
9844bef
2c3878c
42ef5de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| cd catkin_ws | ||
| catkin build | ||
| catkin build --cmake-args -DFranka_DIR=/root/git/franka-interface/libfranka/build | ||
| source devel/setup.bash | ||
| cd .. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #ifndef FRANKA_INTERFACE_FEEDBACK_CONTROLLER_TORQUE_FEEDBACK_CONTROLLER_H_ | ||
| #define FRANKA_INTERFACE_FEEDBACK_CONTROLLER_TORQUE_FEEDBACK_CONTROLLER_H_ | ||
|
|
||
|
|
||
| #include <Eigen/Dense> | ||
|
|
||
| #include "franka-interface/feedback_controller/feedback_controller.h" | ||
|
|
||
| class TorqueFeedbackController : public FeedbackController{ | ||
| public: | ||
| using FeedbackController::FeedbackController; | ||
| void parse_parameters() override; | ||
| void initialize_controller(FrankaRobot *robot) override; | ||
| void parse_sensor_data(const franka::RobotState &robot_state) override; | ||
| void get_next_step(const franka::RobotState &robot_state, | ||
| TrajectoryGenerator *traj_generator) override; | ||
|
|
||
| protected: | ||
| TorqueControllerSensorMessage torque_feedback_sensor_msg_; | ||
| Eigen::VectorXd tau_d; | ||
| }; | ||
|
|
||
| #endif // FRANKA_INTERFACE_FEEDBACK_CONTROLLER_TORQUE_FEEDBACK_CONTROLLER_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
|
|
||
| #ifndef FRANKA_INTERFACE_SKILLS_JOINT_TORQUE_SKILL_H_ | ||
| #define FRANKA_INTERFACE_SKILLS_JOINT_TORQUE_SKILL_H_ | ||
|
|
||
| #include "franka-interface/skills/base_skill.h" | ||
|
|
||
| class JointTorqueSkill: public BaseSkill{ | ||
| public: | ||
| JointTorqueSkill(int skill_idx, int meta_skill_idx, std::string description): | ||
| BaseSkill(skill_idx, meta_skill_idx, description) | ||
| {}; | ||
| void limit_current_joint_torques(double period); | ||
| void execute_skill_on_franka(run_loop* run_loop, | ||
| FrankaRobot* robot, | ||
| FrankaGripper* gripper, | ||
| RobotStateData* robot_state_data) override; | ||
| private: | ||
| bool return_status_{false}; | ||
|
|
||
| double safety_factor = 0.1; | ||
|
|
||
| std::array<double, 7> previous_joint_torques_; | ||
| std::array<double, 7> current_joint_torques_; | ||
| std::array<double, 7> current_joint_rotatums_; | ||
|
|
||
| // Franka Parameters from https://frankaemika.github.io/docs/control_parameters.html | ||
| std::array<double, 7> max_joint_torques_{87, 87, 87, 87, 12, 12, 12}; // Nm | ||
| std::array<double, 7> max_joint_rotatums_{1000, 1000, 1000, 1000, 1000, 1000, 1000}; // Nm / s | ||
| }; | ||
| #endif // FRANKA_INTERFACE_SKILLS_JOINT_TORQUE_SKILL_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| #include <exception> | ||
| #include "franka-interface/feedback_controller/torque_feedback_controller.h" | ||
|
|
||
| void TorqueFeedbackController::parse_parameters(){ | ||
|
|
||
| } | ||
| void TorqueFeedbackController::initialize_controller(FrankaRobot *robot) { | ||
| tau_d.resize(7); | ||
| tau_d.setZero(); | ||
| } | ||
|
|
||
| void TorqueFeedbackController::parse_sensor_data(const franka::RobotState &robot_state){ | ||
| tau_d.resize(7); | ||
| tau_d.setZero(); | ||
| SensorDataManagerReadStatus sensor_msg_status = sensor_data_manager_->readFeedbackControllerSensorMessage(torque_feedback_sensor_msg_); | ||
| if (sensor_msg_status == SensorDataManagerReadStatus::SUCCESS) { | ||
| for(int i = 0; i < 7 ; i++){ | ||
| tau_d(i) = torque_feedback_sensor_msg_.joint_torques_cmd(i); | ||
| } | ||
| } | ||
| } | ||
| void TorqueFeedbackController::get_next_step(const franka::RobotState &robot_state, | ||
| TrajectoryGenerator *traj_generator){ | ||
| Eigen::VectorXd::Map(&tau_d_array_[0], 7) = tau_d; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| #include "franka-interface/skills/joint_torque_skill.h" | ||
| #include <franka/robot.h> | ||
|
|
||
| #include "franka-interface/robot_state_data.h" | ||
| #include "franka-interface/run_loop.h" | ||
| #include "franka-interface/run_loop_shared_memory_handler.h" | ||
| #include "franka-interface/feedback_controller/set_internal_impedance_feedback_controller.h" | ||
| #include "franka-interface/trajectory_generator/joint_trajectory_generator.h" | ||
| #include <franka-interface-common/run_loop_process_info.h> | ||
|
|
||
|
|
||
|
|
||
| void JointTorqueSkill::limit_current_joint_torques(double period) { | ||
| for(int i = 0; i < 7; i++) { | ||
| if(std::abs(current_joint_torques_[i]) > max_joint_torques_[i] * safety_factor) { | ||
| if(current_joint_torques_[i] > 0) { | ||
| current_joint_torques_[i] = max_joint_torques_[i] * safety_factor; | ||
| } else { | ||
| current_joint_torques_[i] = -max_joint_torques_[i] * safety_factor; | ||
| } | ||
| } | ||
| current_joint_rotatums_[i] = (current_joint_torques_[i] - previous_joint_torques_[i]) / period; | ||
|
|
||
| if(std::abs(current_joint_rotatums_[i]) > max_joint_rotatums_[i] * safety_factor) { | ||
| if(current_joint_rotatums_[i] > 0) { | ||
| current_joint_rotatums_[i] = max_joint_rotatums_[i] * safety_factor; | ||
| } else { | ||
| current_joint_rotatums_[i] = -max_joint_rotatums_[i] * safety_factor; | ||
| } | ||
| } | ||
| current_joint_torques_[i] = previous_joint_torques_[i] + current_joint_rotatums_[i] * period; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't this logic really discontinuous, i.e. at t = 0, we have 0 torques and then just directly at the next state we have a large torque value?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is fine,
|
||
| } | ||
| } | ||
| void JointTorqueSkill::execute_skill_on_franka(run_loop* run_loop, | ||
| FrankaRobot* robot, | ||
| FrankaGripper* gripper, | ||
| RobotStateData *robot_state_data) { | ||
| double time = 0.0; | ||
| int log_counter = 0; | ||
| std::array<double, 16> pose_desired; | ||
|
|
||
| RunLoopSharedMemoryHandler* shared_memory_handler = run_loop->get_shared_memory_handler(); | ||
| RunLoopProcessInfo* run_loop_info = shared_memory_handler->getRunLoopProcessInfo(); | ||
| boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock( | ||
| *(shared_memory_handler->getRunLoopProcessInfoMutex()), | ||
| boost::interprocess::defer_lock); | ||
| SensorDataManager* sensor_data_manager = run_loop->get_sensor_data_manager(); | ||
|
|
||
| std::cout << "Will run the control loop\n"; | ||
|
|
||
| std::function<franka::Torques(const franka::RobotState&, franka::Duration)> | ||
| joint_torque_callback = [&]( | ||
| const franka::RobotState& robot_state, | ||
| franka::Duration period) -> franka::Torques { | ||
|
|
||
| current_period_ = period.toSec(); | ||
| time += current_period_; | ||
| if(time == 0.0 ){ | ||
| for(int i = 0; i < 7; i++) { | ||
| current_joint_torques_[i] = 0; | ||
| previous_joint_torques_[i] = 0; | ||
| } | ||
|
|
||
| try { | ||
| if (lock.try_lock()) { | ||
| run_loop_info->set_time_skill_started_in_robot_time(robot_state.time.toSec()); | ||
| lock.unlock(); | ||
| } | ||
| } catch (boost::interprocess::lock_exception) { | ||
| // Do nothing | ||
| } | ||
| } | ||
|
|
||
| if (robot_state_data->mutex_.try_lock()) { | ||
| robot_state_data->counter_ += 1; | ||
| robot_state_data->time_ = period.toSec(); | ||
| robot_state_data->has_data_ = true; | ||
| robot_state_data->mutex_.unlock(); | ||
| } | ||
|
|
||
| log_counter += 1; | ||
| try { | ||
| sensor_data_manager->getSensorBufferGroupMutex()->try_lock(); | ||
| traj_generator_->parse_sensor_data(robot_state); | ||
| termination_handler_->parse_sensor_data(robot_state); | ||
| sensor_data_manager->getSensorBufferGroupMutex()->unlock(); | ||
| } catch (boost::interprocess::lock_exception) { | ||
| } | ||
|
|
||
| if (log_counter % 1 == 0) { | ||
| pose_desired = robot_state.O_T_EE_d; | ||
| robot_state_data->log_robot_state(pose_desired, robot_state, robot->getModel(), time); | ||
| } | ||
|
|
||
| feedback_controller_->parse_sensor_data(robot_state); | ||
| feedback_controller_->get_next_step(robot_state, traj_generator_); | ||
|
|
||
| bool done = termination_handler_->should_terminate(robot_state, model_, traj_generator_); | ||
| if (done && time > 0.0) { | ||
| try{ | ||
| if (lock.try_lock()) { | ||
| run_loop_info->set_time_skill_finished_in_robot_time(robot_state.time.toSec()); | ||
| lock.unlock(); | ||
| } | ||
| } catch (boost::interprocess::lock_exception) { | ||
| // Do nothing | ||
| } | ||
|
|
||
| return franka::MotionFinished(franka::Torques(feedback_controller_->tau_d_array_)); | ||
| } | ||
|
|
||
| for(int i = 0; i < 7; i++) { | ||
| current_joint_torques_[i] = feedback_controller_->tau_d_array_[i]; | ||
| } | ||
|
|
||
| if (period.toSec() > 0.0){ | ||
| limit_current_joint_torques(current_period_); | ||
| } | ||
|
|
||
| for(int i = 0; i < 7; i++) { | ||
| previous_joint_torques_[i] = current_joint_torques_[i]; | ||
| } | ||
|
|
||
| return current_joint_torques_; | ||
|
|
||
| }; | ||
|
|
||
| robot->robot_.control(joint_torque_callback, true); | ||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.