45 #include <std_msgs/msg/bool.hpp>
46 #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
53 using namespace std::chrono_literals;
59 static const rclcpp::Logger
LOGGER = rclcpp::get_logger(
"moveit_servo.servo_calcs");
61 static constexpr
double STOPPED_VELOCITY_EPS = 1e-4;
65 ServoCalcs::ServoCalcs(
const rclcpp::Node::SharedPtr& node,
66 const std::shared_ptr<const moveit_servo::ServoParameters>& parameters,
69 , parameters_(parameters)
71 , stop_requested_(true)
72 , done_stopping_(false)
74 , robot_link_command_frame_(parameters->robot_link_command_frame)
75 , smoothing_loader_(
"moveit_core",
"online_signal_smoothing::SmoothingBaseClass")
78 bool callback_success =
parameters_->registerSetParameterCallback(parameters->ns +
".robot_link_command_frame",
79 [
this](
const rclcpp::Parameter& parameter) {
80 return robotLinkCommandFrameCallback(parameter);
82 if (!callback_success)
84 throw std::runtime_error(
"Failed to register setParameterCallback");
92 RCLCPP_ERROR_STREAM(LOGGER,
"Invalid move group name: `" <<
parameters_->move_group_name <<
"`");
93 throw std::runtime_error(
"Invalid move group name");
98 parameters_->cartesian_command_in_topic, rclcpp::SystemDefaultsQoS(),
99 [
this](
const geometry_msgs::msg::TwistStamped::ConstSharedPtr& msg) {
return twistStampedCB(msg); });
102 parameters_->joint_command_in_topic, rclcpp::SystemDefaultsQoS(),
103 [
this](
const control_msgs::msg::JointJog::ConstSharedPtr& msg) {
return jointCmdCB(msg); });
107 "~/change_drift_dimensions",
108 [
this](
const std::shared_ptr<moveit_msgs::srv::ChangeDriftDimensions::Request>& req,
109 const std::shared_ptr<moveit_msgs::srv::ChangeDriftDimensions::Response>& res) {
115 "~/change_control_dimensions",
116 [
this](
const std::shared_ptr<moveit_msgs::srv::ChangeControlDimensions::Request>& req,
117 const std::shared_ptr<moveit_msgs::srv::ChangeControlDimensions::Response>& res) {
123 "~/reset_servo_status",
124 [
this](
const std::shared_ptr<std_srvs::srv::Empty::Request>& req,
125 const std::shared_ptr<std_srvs::srv::Empty::Response>& res) {
return resetServoStatus(req, res); });
129 "~/collision_velocity_scale", rclcpp::SystemDefaultsQoS(),
134 if (
parameters_->command_out_type ==
"trajectory_msgs/JointTrajectory")
137 parameters_->command_out_topic, rclcpp::SystemDefaultsQoS());
139 else if (
parameters_->command_out_type ==
"std_msgs/Float64MultiArray")
142 parameters_->command_out_topic, rclcpp::SystemDefaultsQoS());
165 catch (pluginlib::PluginlibException& ex)
167 RCLCPP_ERROR(LOGGER,
"Exception while loading the smoothing plugin '%s': '%s'",
168 parameters_->smoothing_filter_plugin_name.c_str(), ex.what());
169 std::exit(EXIT_FAILURE);
175 RCLCPP_ERROR(LOGGER,
"Smoothing plugin could not be initialized");
176 std::exit(EXIT_FAILURE);
180 Eigen::Matrix3d empty_matrix;
181 empty_matrix.setZero();
192 "No kinematics solver instantiated for group '%s'. Will use inverse Jacobian for servo calculations instead.",
199 "The loaded kinematics plugin does not support group '%s'. Will use inverse Jacobian for servo "
200 "calculations instead.",
216 auto initial_joint_trajectory = std::make_unique<trajectory_msgs::msg::JointTrajectory>();
217 initial_joint_trajectory->header.stamp =
node_->now();
218 initial_joint_trajectory->header.frame_id =
parameters_->planning_frame;
220 trajectory_msgs::msg::JointTrajectoryPoint point;
221 point.time_from_start = rclcpp::Duration::from_seconds(
parameters_->publish_period);
228 point.velocities = velocity;
237 initial_joint_trajectory->points.push_back(point);
279 rclcpp::WallRate rate(1.0 /
parameters_->publish_period);
296 const auto start_time =
node_->now();
298 const auto run_duration =
node_->now() - start_time;
301 if (run_duration.seconds() >
parameters_->publish_period)
303 rclcpp::Clock& clock = *
node_->get_clock();
305 "run_duration: " << run_duration.seconds() <<
" (" <<
parameters_->publish_period
312 main_loop_lock.unlock();
321 auto status_msg = std::make_unique<std_msgs::msg::Int8>();
322 status_msg->data =
static_cast<int8_t
>(
status_);
343 rclcpp::Duration::from_seconds(
parameters_->incoming_command_timeout));
345 rclcpp::Duration::from_seconds(
parameters_->incoming_command_timeout));
390 auto joint_trajectory = std::make_unique<trajectory_msgs::msg::JointTrajectory>();
414 for (
auto& point : joint_trajectory->points)
416 point.velocities.assign(point.velocities.size(), 0);
436 rclcpp::Clock& clock = *
node_->get_clock();
443 rclcpp::Clock& clock = *
node_->get_clock();
445 "Skipping publishing because incoming commands are stale.");
470 joint_trajectory->points[0].positions.clear();
475 joint_trajectory->points[0].velocities.clear();
479 joint_trajectory->points[0].accelerations.clear();
484 if (
parameters_->command_out_type ==
"trajectory_msgs/JointTrajectory")
488 joint_trajectory->header.stamp = rclcpp::Time(0);
492 else if (
parameters_->command_out_type ==
"std_msgs/Float64MultiArray")
494 auto joints = std::make_unique<std_msgs::msg::Float64MultiArray>();
495 if (
parameters_->publish_joint_positions && !joint_trajectory->points.empty())
496 joints->data = joint_trajectory->points[0].positions;
497 else if (
parameters_->publish_joint_velocities && !joint_trajectory->points.empty())
498 joints->data = joint_trajectory->points[0].velocities;
512 rcl_interfaces::msg::SetParametersResult result;
513 result.successful =
true;
521 trajectory_msgs::msg::JointTrajectory& joint_trajectory)
531 if (cmd.header.frame_id !=
parameters_->planning_frame)
533 Eigen::Vector3d translation_vector(cmd.twist.linear.x, cmd.twist.linear.y, cmd.twist.linear.z);
534 Eigen::Vector3d angular_vector(cmd.twist.angular.x, cmd.twist.angular.y, cmd.twist.angular.z);
542 else if (cmd.header.frame_id ==
parameters_->ee_frame_name)
552 const auto tf_moveit_to_incoming_cmd_frame =
555 translation_vector = tf_moveit_to_incoming_cmd_frame.linear() * translation_vector;
556 angular_vector = tf_moveit_to_incoming_cmd_frame.linear() * angular_vector;
561 cmd.twist.linear.x = translation_vector(0);
562 cmd.twist.linear.y = translation_vector(1);
563 cmd.twist.linear.z = translation_vector(2);
564 cmd.twist.angular.x = angular_vector(0);
565 cmd.twist.angular.y = angular_vector(1);
566 cmd.twist.angular.z = angular_vector(2);
575 Eigen::JacobiSVD<Eigen::MatrixXd> svd =
576 Eigen::JacobiSVD<Eigen::MatrixXd>(jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
577 Eigen::MatrixXd matrix_s = svd.singularValues().asDiagonal();
578 Eigen::MatrixXd pseudo_inverse = svd.matrixV() * matrix_s.inverse() * svd.matrixU().transpose();
586 Eigen::Isometry3d tf_pos_delta(Eigen::Isometry3d::Identity());
587 tf_pos_delta.translate(
Eigen::Vector3d(delta_x[0], delta_x[1], delta_x[2]));
589 Eigen::Isometry3d tf_rot_delta(Eigen::Isometry3d::Identity());
590 Eigen::Quaterniond q = Eigen::AngleAxisd(delta_x[3], Eigen::Vector3d::UnitX()) *
591 Eigen::AngleAxisd(delta_x[4], Eigen::Vector3d::UnitY()) *
592 Eigen::AngleAxisd(delta_x[5], Eigen::Vector3d::UnitZ());
593 tf_rot_delta.rotate(q);
605 auto tf_translation = tf_no_new_rot.translation();
606 auto tf_neg_translation = Eigen::Isometry3d::Identity();
607 tf_neg_translation(0, 3) = -tf_translation(0, 0);
608 tf_neg_translation(1, 3) = -tf_translation(1, 0);
609 tf_neg_translation(2, 3) = -tf_translation(2, 0);
610 auto tf_pos_translation = Eigen::Isometry3d::Identity();
611 tf_pos_translation(0, 3) = tf_translation(0, 0);
612 tf_pos_translation(1, 3) = tf_translation(1, 0);
613 tf_pos_translation(2, 3) = tf_translation(2, 0);
616 auto tf = tf_pos_translation * tf_rot_delta * tf_neg_translation * tf_no_new_rot;
617 geometry_msgs::msg::Pose next_pose = tf2::toMsg(tf);
621 moveit_msgs::msg::MoveItErrorCodes err;
625 solution, err, opts))
635 RCLCPP_WARN(LOGGER,
"Could not find IK solution for requested motion, got error code %d", err.val);
648 parameters_->leaving_singularity_threshold_multiplier,
655 trajectory_msgs::msg::JointTrajectory& joint_trajectory)
669 trajectory_msgs::msg::JointTrajectory& joint_trajectory,
684 if (collision_scale > 0 && collision_scale < 1)
687 rclcpp::Clock& clock = *
node_->get_clock();
690 else if (collision_scale == 0)
693 rclcpp::Clock& clock = *
node_->get_clock();
696 delta_theta *= collision_scale;
711 if (!joints_to_halt.empty())
740 if (joint_state.position.size() !=
static_cast<std::size_t
>(delta_theta.size()) ||
741 joint_state.velocity.size() != joint_state.position.size())
743 rclcpp::Clock& clock = *
node_->get_clock();
745 "Lengths of output and increments do not match.");
749 for (std::size_t i = 0; i < joint_state.position.size(); ++i)
752 joint_state.position[i] += delta_theta[i];
755 smoother_->doSmoothing(joint_state.position);
757 for (std::size_t i = 0; i < joint_state.position.size(); ++i)
760 joint_state.velocity[i] =
775 joint_trajectory.points.resize(count);
776 auto point = joint_trajectory.points[0];
778 for (
int i = 1; i < count; ++i)
780 point.time_from_start = rclcpp::Duration::from_seconds((i + 1) *
parameters_->publish_period);
781 joint_trajectory.points[i] = point;
792 trajectory_msgs::msg::JointTrajectory& joint_trajectory)
796 joint_trajectory.header.stamp = rclcpp::Time(0);
797 joint_trajectory.header.frame_id =
parameters_->planning_frame;
798 joint_trajectory.joint_names = joint_state.name;
800 trajectory_msgs::msg::JointTrajectoryPoint point;
801 point.time_from_start = rclcpp::Duration::from_seconds(
parameters_->publish_period);
803 point.positions = joint_state.position;
805 point.velocities = joint_state.velocity;
812 point.accelerations = acceleration;
814 joint_trajectory.points.push_back(point);
817 std::vector<const moveit::core::JointModel*>
821 double joint_angle = 0;
822 std::vector<const moveit::core::JointModel*> joints_to_halt;
825 for (std::size_t
c = 0;
c < joint_state.name.size(); ++
c)
828 if (joint_state.name[
c] == joint->getName())
830 joint_angle = joint_state.position.at(
c);
835 if (!joint->satisfiesPositionBounds(&joint_angle, -
parameters_->joint_limit_margin))
837 const std::vector<moveit_msgs::msg::JointLimits>& limits = joint->getVariableBoundsMsg();
843 auto joint_itr = std::find(joint_state.name.begin(), joint_state.name.end(), joint->getName());
844 auto joint_idx =
std::distance(joint_state.name.begin(), joint_itr);
846 if ((joint_state.velocity.at(joint_idx) < 0 &&
847 (joint_angle < (limits[0].min_position +
parameters_->joint_limit_margin))) ||
848 (joint_state.velocity.at(joint_idx) > 0 &&
849 (joint_angle > (limits[0].max_position -
parameters_->joint_limit_margin))))
851 joints_to_halt.push_back(joint);
856 if (!joints_to_halt.empty())
858 std::ostringstream joints_names;
859 std::transform(joints_to_halt.cbegin(), std::prev(joints_to_halt.cend()),
860 std::ostream_iterator<std::string>(joints_names,
", "),
861 [](
const auto& joint) { return joint->getName(); });
862 joints_names << joints_to_halt.back()->getName();
865 <<
" " << joints_names.str() <<
" close to a position limit. Halting.");
867 return joints_to_halt;
873 joint_trajectory.points.clear();
874 joint_trajectory.points.emplace_back();
884 smoother_->doSmoothing(joint_trajectory.points[0].positions);
888 joint_trajectory.points[0].velocities = std::vector<double>(
num_joints_, 0);
891 joint_trajectory.points[0].velocities.at(i) =
895 if (joint_trajectory.points[0].velocities.at(i) > STOPPED_VELOCITY_EPS)
903 std::fill(joint_trajectory.points[0].velocities.begin(), joint_trajectory.points[0].velocities.end(), 0);
909 joint_trajectory.points[0].accelerations = std::vector<double>(
num_joints_, 0);
912 joint_trajectory.points[0].accelerations.at(i) =
918 joint_trajectory.points[0].time_from_start = rclcpp::Duration::from_seconds(
parameters_->publish_period);
922 const std::vector<const moveit::core::JointModel*>& joints_to_halt)
const
925 for (
const auto& joint_to_halt : joints_to_halt)
927 const auto joint_it = std::find(joint_state.name.cbegin(), joint_state.name.cend(), joint_to_halt->getName());
928 if (joint_it != joint_state.name.cend())
930 const auto joint_index =
std::distance(joint_state.name.cbegin(), joint_it);
932 joint_state.velocity.at(joint_index) = 0.0;
950 for (
double velocity : cmd.velocities)
952 if (std::isnan(velocity))
954 rclcpp::Clock& clock = *
node_->get_clock();
956 "nan in incoming command. Skipping this datapoint.");
965 if (std::isnan(cmd.twist.linear.x) || std::isnan(cmd.twist.linear.y) || std::isnan(cmd.twist.linear.z) ||
966 std::isnan(cmd.twist.angular.x) || std::isnan(cmd.twist.angular.y) || std::isnan(cmd.twist.angular.z))
968 rclcpp::Clock& clock = *
node_->get_clock();
970 "nan in incoming command. Skipping this datapoint.");
977 if ((fabs(cmd.twist.linear.x) > 1) || (fabs(cmd.twist.linear.y) > 1) || (fabs(cmd.twist.linear.z) > 1) ||
978 (fabs(cmd.twist.angular.x) > 1) || (fabs(cmd.twist.angular.y) > 1) || (fabs(cmd.twist.angular.z) > 1))
980 rclcpp::Clock& clock = *
node_->get_clock();
982 "Component of incoming command is >1. Skipping this datapoint.");
993 Eigen::VectorXd result(6);
1007 else if (
parameters_->command_in_type ==
"speed_units")
1009 result[0] = command.twist.linear.x *
parameters_->publish_period;
1010 result[1] = command.twist.linear.y *
parameters_->publish_period;
1011 result[2] = command.twist.linear.z *
parameters_->publish_period;
1012 result[3] = command.twist.angular.x *
parameters_->publish_period;
1013 result[4] = command.twist.angular.y *
parameters_->publish_period;
1014 result[5] = command.twist.angular.z *
parameters_->publish_period;
1018 rclcpp::Clock& clock = *
node_->get_clock();
1031 for (std::size_t m = 0; m < command.joint_names.size(); ++m)
1037 catch (
const std::out_of_range& e)
1039 rclcpp::Clock& clock = *
node_->get_clock();
1040 RCLCPP_WARN_STREAM_THROTTLE(LOGGER, clock,
ROS_LOG_THROTTLE_PERIOD,
"Ignoring joint " << command.joint_names[m]);
1047 else if (
parameters_->command_in_type ==
"speed_units")
1048 result[
c] = command.velocities[m] *
parameters_->publish_period;
1051 rclcpp::Clock& clock = *
node_->get_clock();
1053 "Unexpected command_in_type, check yaml file.");
1062 unsigned int num_rows = jacobian.rows() - 1;
1063 unsigned int num_cols = jacobian.cols();
1065 if (row_to_remove < num_rows)
1067 jacobian.block(row_to_remove, 0, num_rows - row_to_remove, num_cols) =
1068 jacobian.block(row_to_remove + 1, 0, num_rows - row_to_remove, num_cols);
1069 delta_x.segment(row_to_remove, num_rows - row_to_remove) =
1070 delta_x.segment(row_to_remove + 1, num_rows - row_to_remove);
1072 jacobian.conservativeResize(num_rows, num_cols);
1073 delta_x.conservativeResize(num_rows);
1082 for (
auto dimension = matrix.rows() - 1; dimension >= 0; --dimension)
1095 command.twist.linear.x = 0;
1097 command.twist.linear.y = 0;
1099 command.twist.linear.z = 0;
1101 command.twist.angular.x = 0;
1103 command.twist.angular.y = 0;
1105 command.twist.angular.z = 0;
1114 return !transform.matrix().isZero(0);
1137 return !transform.matrix().isZero(0);
1160 if (msg->header.stamp != rclcpp::Time(0.))
1174 if (msg->header.stamp != rclcpp::Time(0.))
1188 const std::shared_ptr<moveit_msgs::srv::ChangeDriftDimensions::Response>& res)
1197 res->success =
true;
1201 const std::shared_ptr<moveit_msgs::srv::ChangeControlDimensions::Response>& res)
1210 res->success =
true;
1214 const std::shared_ptr<std_srvs::srv::Empty::Response>& )
const std::vector< const JointModel * > & getActiveJointModels() const
Get the active joints in this group (that have controllable DOF). This does not include mimic joints.
const std::string & getName() const
Get the name of the joint group.
const kinematics::KinematicsBaseConstPtr getSolverInstance() const
const std::vector< std::string > & getActiveJointModelNames() const
Get the names of the active joints in this group. These are the names of the joints returned by getJo...
const std::shared_ptr< const moveit_servo::ServoParameters > parameters_
bool latest_joint_cmd_is_nonzero_
bool have_nonzero_joint_command_
std::atomic< bool > paused_
void removeDimension(Eigen::MatrixXd &matrix, Eigen::VectorXd &delta_x, unsigned int row_to_remove) const
rclcpp::Publisher< std_msgs::msg::Int8 >::SharedPtr status_pub_
Eigen::Isometry3d tf_moveit_to_ee_frame_
std::array< bool, 6 > control_dimensions_
std::array< bool, 6 > drift_dimensions_
void changeDriftDimensions(const std::shared_ptr< moveit_msgs::srv::ChangeDriftDimensions::Request > &req, const std::shared_ptr< moveit_msgs::srv::ChangeDriftDimensions::Response > &res)
moveit::core::RobotStatePtr current_state_
void resetLowPassFilters(const sensor_msgs::msg::JointState &joint_state)
Set the filters to the specified values.
sensor_msgs::msg::JointState original_joint_state_
void updateJoints()
Parse the incoming joint msg for the joints of our MoveGroup.
control_msgs::msg::JointJog joint_servo_cmd_
void insertRedundantPointsIntoTrajectory(trajectory_msgs::msg::JointTrajectory &joint_trajectory, int count) const
Gazebo simulations have very strict message timestamp requirements. Satisfy Gazebo by stuffing multip...
void setPaused(bool paused)
Pause or unpause processing servo commands while keeping the timers alive.
rclcpp::Service< moveit_msgs::srv::ChangeControlDimensions >::SharedPtr control_dimensions_server_
Eigen::Isometry3d tf_moveit_to_robot_cmd_frame_
rclcpp::Service< moveit_msgs::srv::ChangeDriftDimensions >::SharedPtr drift_dimensions_server_
std::string robot_link_command_frame_
const int gazebo_redundant_message_count_
rclcpp::Publisher< std_msgs::msg::Float64MultiArray >::SharedPtr multiarray_outgoing_cmd_pub_
bool latest_twist_cmd_is_nonzero_
std::map< std::string, std::size_t > joint_state_name_map_
bool jointServoCalcs(const control_msgs::msg::JointJog &cmd, trajectory_msgs::msg::JointTrajectory &joint_trajectory)
Do servoing calculations for direct commands to a joint.
void stop()
Stop the currently running thread.
double collision_velocity_scale_
bool cartesianServoCalcs(geometry_msgs::msg::TwistStamped &cmd, trajectory_msgs::msg::JointTrajectory &joint_trajectory)
Do servoing calculations for Cartesian twist commands.
pluginlib::ClassLoader< online_signal_smoothing::SmoothingBaseClass > smoothing_loader_
rclcpp::Service< std_srvs::srv::Empty >::SharedPtr reset_servo_status_
bool twist_command_is_stale_
rclcpp::Subscription< geometry_msgs::msg::TwistStamped >::SharedPtr twist_stamped_sub_
control_msgs::msg::JointJog::ConstSharedPtr latest_joint_cmd_
geometry_msgs::msg::TwistStamped::ConstSharedPtr latest_twist_stamped_
bool joint_command_is_stale_
geometry_msgs::msg::TwistStamped twist_stamped_cmd_
rclcpp::Subscription< control_msgs::msg::JointJog >::SharedPtr joint_cmd_sub_
std::condition_variable input_cv_
Eigen::ArrayXd delta_theta_
sensor_msgs::msg::JointState internal_joint_state_
rclcpp::Subscription< std_msgs::msg::Float64 >::SharedPtr collision_velocity_scale_sub_
void changeControlDimensions(const std::shared_ptr< moveit_msgs::srv::ChangeControlDimensions::Request > &req, const std::shared_ptr< moveit_msgs::srv::ChangeControlDimensions::Response > &res)
Start the main calculation timer.
bool getEEFrameTransform(Eigen::Isometry3d &transform)
bool wait_for_servo_commands_
void collisionVelocityScaleCB(const std_msgs::msg::Float64::ConstSharedPtr &msg)
void twistStampedCB(const geometry_msgs::msg::TwistStamped::ConstSharedPtr &msg)
Eigen::VectorXd scaleJointCommand(const control_msgs::msg::JointJog &command)
If incoming velocity commands are from a unitless joystick, scale them to physical units....
bool internalServoUpdate(Eigen::ArrayXd &delta_theta, trajectory_msgs::msg::JointTrajectory &joint_trajectory, const ServoType servo_type)
Handles all aspects of the servoing after the desired joint commands are established Joint and Cartes...
rclcpp::Time latest_joint_command_stamp_
rcl_interfaces::msg::SetParametersResult robotLinkCommandFrameCallback(const rclcpp::Parameter ¶meter)
void mainCalcLoop()
Run the main calculation loop.
bool have_nonzero_command_
void calculateSingleIteration()
Do calculations for a single iteration. Publish one outgoing command.
void jointCmdCB(const control_msgs::msg::JointJog::ConstSharedPtr &msg)
rclcpp::Time latest_twist_command_stamp_
const moveit::core::JointModelGroup * joint_model_group_
rclcpp::Publisher< trajectory_msgs::msg::JointTrajectory >::SharedPtr trajectory_outgoing_cmd_pub_
std::mutex main_loop_mutex_
trajectory_msgs::msg::JointTrajectory::SharedPtr last_sent_command_
planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_
bool checkValidCommand(const control_msgs::msg::JointJog &cmd)
void composeJointTrajMessage(const sensor_msgs::msg::JointState &joint_state, trajectory_msgs::msg::JointTrajectory &joint_trajectory)
Compose the outgoing JointTrajectory message.
bool getCommandFrameTransform(Eigen::Isometry3d &transform)
void suddenHalt(sensor_msgs::msg::JointState &joint_state, const std::vector< const moveit::core::JointModel * > &joints_to_halt) const
Suddenly halt for a joint limit or other critical issue. Is handled differently for position vs....
std::shared_ptr< online_signal_smoothing::SmoothingBaseClass > smoother_
void filteredHalt(trajectory_msgs::msg::JointTrajectory &joint_trajectory)
Come to a halt in a smooth way. Apply a smoothing plugin, if one is configured.
void start()
Start the timer where we do work and publish outputs.
bool have_nonzero_twist_stamped_
Eigen::VectorXd scaleCartesianCommand(const geometry_msgs::msg::TwistStamped &command)
If incoming velocity commands are from a unitless joystick, scale them to physical units....
Eigen::Isometry3d ik_base_to_tip_frame_
void enforceControlDimensions(geometry_msgs::msg::TwistStamped &command)
void removeDriftDimensions(Eigen::MatrixXd &matrix, Eigen::VectorXd &delta_x)
bool resetServoStatus(const std::shared_ptr< std_srvs::srv::Empty::Request > &req, const std::shared_ptr< std_srvs::srv::Empty::Response > &res)
Service callback to reset Servo status, e.g. so the arm can move again after a collision.
std::shared_ptr< rclcpp::Node > node_
kinematics::KinematicsBaseConstPtr ik_solver_
bool applyJointUpdate(const Eigen::ArrayXd &delta_theta, sensor_msgs::msg::JointState &joint_state)
Joint-wise update of a sensor_msgs::msg::JointState with given delta's Also filters and calculates th...
std::atomic< bool > done_stopping_
std::vector< const moveit::core::JointModel * > enforcePositionLimits(sensor_msgs::msg::JointState &joint_state) const
Avoid overshooting joint limits.
constexpr size_t ROS_LOG_THROTTLE_PERIOD
Vec3fX< details::Vec3Data< double > > Vector3d
double velocityScalingFactorForSingularity(const moveit::core::JointModelGroup *joint_model_group, const Eigen::VectorXd &commanded_twist, const Eigen::JacobiSVD< Eigen::MatrixXd > &svd, const Eigen::MatrixXd &pseudo_inverse, const double hard_stop_singularity_threshold, const double lower_singularity_threshold, const double leaving_singularity_threshold_multiplier, rclcpp::Clock &clock, moveit::core::RobotStatePtr ¤t_state, StatusCode &status)
Possibly calculate a velocity scaling factor, due to proximity of singularity and direction of motion...
const std::unordered_map< StatusCode, std::string > SERVO_STATUS_CODE_MAP({ { StatusCode::INVALID, "Invalid" }, { StatusCode::NO_WARNING, "No warnings" }, { StatusCode::DECELERATE_FOR_APPROACHING_SINGULARITY, "Moving closer to a singularity, decelerating" }, { StatusCode::HALT_FOR_SINGULARITY, "Very close to a singularity, emergency stop" }, { StatusCode::DECELERATE_FOR_COLLISION, "Close to a collision, decelerating" }, { StatusCode::HALT_FOR_COLLISION, "Collision detected, emergency stop" }, { StatusCode::JOINT_BOUND, "Close to a joint bound (position or velocity), halting" }, { StatusCode::DECELERATE_FOR_LEAVING_SINGULARITY, "Moving away from a singularity, decelerating" } })
@ DECELERATE_FOR_COLLISION
geometry_msgs::msg::TransformStamped convertIsometryToTransform(const Eigen::Isometry3d &eigen_tf, const std::string &parent_frame, const std::string &child_frame)
Helper function for converting Eigen::Isometry3d to geometry_msgs/TransformStamped.
bool isNonZero(const geometry_msgs::msg::TwistStamped &msg)
Helper function for detecting zeroed message.
void enforceVelocityLimits(const moveit::core::JointModelGroup *joint_model_group, const double publish_period, sensor_msgs::msg::JointState &joint_state, const double override_velocity_scaling_factor=0.0)
Decrease robot position change and velocity, if needed, to satisfy joint velocity limits.
double distance(const urdf::Pose &transform)
const rclcpp::Logger LOGGER
A set of options for the kinematics solver.
bool return_approximate_solution