-
Notifications
You must be signed in to change notification settings - Fork 429
[Reference Only/Draft] joint_trajectory_controller convert trajectories to effort values #36
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
Changes from all commits
3a4c7b7
13a6cfc
e2e33fa
493f50c
46a938b
bbbcebc
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 |
|---|---|---|
|
|
@@ -14,20 +14,21 @@ | |
|
|
||
| #include "joint_trajectory_controller/joint_trajectory_controller.hpp" | ||
|
|
||
| #include <angles/angles.h> | ||
|
|
||
| #include <cassert> | ||
| #include <chrono> | ||
| #include <iterator> | ||
| #include <string> | ||
| #include <memory> | ||
| #include <vector> | ||
|
|
||
| #include "angles/angles.h" | ||
|
|
||
| #include "builtin_interfaces/msg/time.hpp" | ||
|
|
||
| #include "lifecycle_msgs/msg/state.hpp" | ||
|
|
||
| #include "rclcpp/time.hpp" | ||
|
|
||
| #include "rclcpp_lifecycle/state.hpp" | ||
|
|
||
| #include "rcutils/logging_macros.h" | ||
|
|
@@ -97,7 +98,7 @@ JointTrajectoryController::update() | |
| point.velocities.resize(size); | ||
| point.accelerations.resize(size); | ||
| }; | ||
| auto compute_error_for_joint = [](JointTrajectoryPoint & error, int index, | ||
| auto compute_error_for_joint = [this](JointTrajectoryPoint & error, int index, | ||
| const JointTrajectoryPoint & current, const JointTrajectoryPoint & desired) | ||
| { | ||
| // error defined as the difference between current and desired | ||
|
|
@@ -115,6 +116,8 @@ JointTrajectoryController::update() | |
| JointTrajectoryPoint state_current, state_desired, state_error; | ||
| auto joint_num = registered_joint_state_handles_.size(); | ||
| resize_joint_trajectory_point(state_current, joint_num); | ||
| resize_joint_trajectory_point(state_error, joint_num); | ||
| resize_joint_trajectory_point(state_desired, joint_num); | ||
|
|
||
| // current state update | ||
| for (auto index = 0ul; index < joint_num; ++index) { | ||
|
|
@@ -153,14 +156,14 @@ JointTrajectoryController::update() | |
|
|
||
| if (before_last_point && !check_state_tolerance_per_joint( | ||
| state_error, index, | ||
| default_tolerances_.state_tolerance[index], false)) | ||
| default_tolerances_.state_tolerance[index], true)) | ||
| { | ||
| abort = true; | ||
| } | ||
| // past the final point, check that we end up inside goal tolerance | ||
| if (!before_last_point && !check_state_tolerance_per_joint( | ||
| state_error, index, | ||
| default_tolerances_.goal_state_tolerance[index], false)) | ||
| default_tolerances_.goal_state_tolerance[index], true)) | ||
| { | ||
| outside_goal_tolerance = true; | ||
| break; | ||
|
|
@@ -209,8 +212,8 @@ JointTrajectoryController::update() | |
| rt_active_goal_.reset(); | ||
| RCLCPP_WARN( | ||
| lifecycle_node_->get_logger(), | ||
| "Aborted due goal_time_tolerance exceeding by %f seconds", | ||
| difference); | ||
| "Aborted due goal_time_tolerance exceeding by %f seconds (given: %f)", | ||
| difference, default_tolerances_.goal_time_tolerance); | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -219,6 +222,28 @@ JointTrajectoryController::update() | |
|
|
||
| set_op_mode(hardware_interface::OperationMode::ACTIVE); | ||
| } | ||
| else | ||
| { | ||
| state_desired = traj_msg_home_ptr_->points[0]; | ||
|
|
||
| for (auto index = 0ul; index < joint_num; ++index) { | ||
| compute_error_for_joint(state_error, index, state_current, state_desired); | ||
| } | ||
| } | ||
|
|
||
| double period = lifecycle_node_->get_parameter("period").as_double(); | ||
| //convert to an effort command buffer via ClosedLoopHardwareInterfaceAdapter::updateCommand | ||
| for (auto index = 0ul; index < joint_num; ++index) { | ||
|
|
||
| double f = 0.0; | ||
| if (index < state_error.positions.size() && index < state_error.velocities.size() && index < state_desired.velocities.size()) | ||
| { | ||
| f = pids_[index]->computeCommand(state_error.positions[index], state_error.velocities[index], rclcpp::Duration::from_seconds(period)); | ||
|
|
||
| const double command = (state_desired.velocities[index] * velocity_ff_[index]) + f; | ||
| registered_joint_cmd_handles_[index]->set_cmd(command); | ||
|
Contributor
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. It took a significant amount of effort tracing down effort_controllers::JointTrajectoryController. But it boiled down to this code. I use control_toolbox::pid to convert the errors to effort values. |
||
| } | ||
| } | ||
|
|
||
| publish_state(state_desired, state_current, state_error); | ||
| return CONTROLLER_INTERFACE_RET_SUCCESS; | ||
|
|
@@ -275,6 +300,16 @@ JointTrajectoryController::on_configure(const rclcpp_lifecycle::State & previous | |
| return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::FAILURE; | ||
| } | ||
| } | ||
| /*registered_joint_eff_cmd_handles_.resize(joint_names_.size()); | ||
| for (size_t index = 0; index < joint_names_.size(); ++index) { | ||
| auto ret = robot_hardware->get_joint_command_handle( | ||
| joint_names_[index].c_str(), ®istered_joint_eff_cmd_handles_[index]); | ||
| if (ret != hardware_interface::HW_RET_OK) { | ||
| RCLCPP_WARN( | ||
| logger, "unable to obtain joint command handle for %s", joint_names_[index].c_str()); | ||
| return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::FAILURE; | ||
| } | ||
| }*/ | ||
| } else { | ||
| return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR; | ||
| } | ||
|
|
@@ -297,10 +332,14 @@ JointTrajectoryController::on_configure(const rclcpp_lifecycle::State & previous | |
| traj_msg_home_ptr_->points[0].time_from_start.sec = 0; | ||
| traj_msg_home_ptr_->points[0].time_from_start.nanosec = 50000000; | ||
| traj_msg_home_ptr_->points[0].positions.resize(registered_joint_state_handles_.size()); | ||
| traj_msg_home_ptr_->points[0].velocities.resize(registered_joint_state_handles_.size()); | ||
| for (size_t index = 0; index < registered_joint_state_handles_.size(); ++index) { | ||
| traj_msg_home_ptr_->points[0].positions[index] = | ||
| registered_joint_state_handles_[index]->get_position(); | ||
| traj_msg_home_ptr_->points[0].velocities[index] = | ||
| registered_joint_state_handles_[index]->get_velocity(); | ||
| } | ||
|
|
||
|
|
||
| traj_external_point_ptr_ = std::make_shared<Trajectory>(); | ||
| traj_home_point_ptr_ = std::make_shared<Trajectory>(); | ||
|
|
@@ -394,6 +433,34 @@ JointTrajectoryController::on_configure(const rclcpp_lifecycle::State & previous | |
| std::bind(&JointTrajectoryController::feedback_setup_callback, this, _1) | ||
| ); | ||
|
|
||
| for (size_t index = 0; index < registered_joint_state_handles_.size(); ++index) { | ||
| traj_msg_home_ptr_->points[0].positions[index] = | ||
| registered_joint_state_handles_[index]->get_position(); | ||
| traj_msg_home_ptr_->points[0].velocities[index] = | ||
| registered_joint_state_handles_[index]->get_velocity(); | ||
| } | ||
|
|
||
| pids_.resize(joint_names_.size()); | ||
| velocity_ff_.resize(joint_names_.size()); | ||
| for (uint j=0; j<pids_.size(); ++j) | ||
| { | ||
| /*lifecycle_node_->declare_parameter("gains." + joint_names_[j] + ".p"); | ||
| lifecycle_node_->declare_parameter("gains." + joint_names_[j] + ".d"); | ||
| lifecycle_node_->declare_parameter("gains." + joint_names_[j] + ".i"); | ||
| lifecycle_node_->declare_parameter("gains." + joint_names_[j] + ".i_clamp");*/ | ||
|
|
||
| double p = lifecycle_node_->get_parameter("gains." + joint_names_[j] + ".p").get_value<double>(); | ||
| double d = lifecycle_node_->get_parameter("gains." + joint_names_[j] + ".d").get_value<double>(); | ||
| double i = lifecycle_node_->get_parameter("gains." + joint_names_[j] + ".i").get_value<double>(); | ||
| double iclamp = lifecycle_node_->get_parameter("gains." + joint_names_[j] + ".i_clamp").get_value<double>(); | ||
|
Contributor
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. pid parameters are retrieved from the node. |
||
|
|
||
| pids_[j].reset(new control_toolbox::Pid()); | ||
| pids_[j]->initPid(p, i, d, std::abs(iclamp), -std::abs(iclamp), true); | ||
| pids_[j]->reset(); | ||
|
|
||
| velocity_ff_[j] = 0.0; | ||
| } | ||
|
|
||
| set_op_mode(hardware_interface::OperationMode::INACTIVE); | ||
|
|
||
| return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS; | ||
|
|
@@ -552,6 +619,15 @@ rclcpp_action::GoalResponse JointTrajectoryController::goal_callback( | |
| "Joints on incoming goal don't match the controller joints."); | ||
| return rclcpp_action::GoalResponse::REJECT; | ||
| } | ||
|
|
||
| std::vector<unsigned int> mapping_vector = mapping(goal->trajectory.joint_names, joint_names_); | ||
| if (mapping_vector.empty()) | ||
| { | ||
| RCLCPP_ERROR( | ||
| lifecycle_node_->get_logger(), | ||
| "Joints on incoming goal don't match the controller joints."); | ||
| return rclcpp_action::GoalResponse::REJECT; | ||
| } | ||
| } | ||
|
|
||
| RCLCPP_INFO(lifecycle_node_->get_logger(), "Accepted new action goal"); | ||
|
|
@@ -590,9 +666,42 @@ void JointTrajectoryController::feedback_setup_callback( | |
| // Update new trajectory | ||
| { | ||
| std::lock_guard<std::mutex> guard(trajectory_mtx_); | ||
| preempt_active_goal(); | ||
| //preempt_active_goal(); | ||
| rt_active_goal_.reset(); | ||
| auto traj_msg = std::make_shared<trajectory_msgs::msg::JointTrajectory>( | ||
| goal_handle->get_goal()->trajectory); | ||
|
|
||
| // rearrange all points in the trajectory message based on mapping | ||
| std::vector<unsigned int> mapping_vector = mapping(traj_msg->joint_names, joint_names_); | ||
| auto remap = [](const std::vector<double>& to_remap, const std::vector<unsigned int>& mapping) | ||
| -> std::vector<double> | ||
| { | ||
| if (to_remap.size() != mapping.size()) | ||
| return to_remap; | ||
| std::vector<double> output; | ||
| output.resize(mapping.size(), 0.0); | ||
| for (auto index = 0ul; index<mapping.size(); ++index) | ||
| { | ||
| unsigned int map_index = mapping[index]; | ||
| output[map_index] = to_remap[index]; | ||
| } | ||
| return output; | ||
| }; | ||
| for (auto index = 0ul; index < traj_msg->points.size(); ++index) | ||
| { | ||
| traj_msg->points[index].positions = | ||
| remap(traj_msg->points[index].positions, mapping_vector); | ||
|
|
||
| traj_msg->points[index].velocities = | ||
| remap(traj_msg->points[index].velocities, mapping_vector); | ||
|
|
||
| traj_msg->points[index].accelerations = | ||
| remap(traj_msg->points[index].accelerations, mapping_vector); | ||
|
|
||
| traj_msg->points[index].effort = | ||
| remap(traj_msg->points[index].effort, mapping_vector); | ||
| } | ||
|
|
||
| traj_external_point_ptr_->update(traj_msg); | ||
|
|
||
| RealtimeGoalHandlePtr rt_goal = std::make_shared<RealtimeGoalHandle>(goal_handle); | ||
|
|
||
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 hack is supplied upstream from gazebo_ros_controls; ideally we should use something else.