41 static const rclcpp::Logger
LOGGER = rclcpp::get_logger(
"moveit_servo.utilities");
46 bool isNonZero(
const geometry_msgs::msg::TwistStamped& msg)
48 return msg.twist.linear.x != 0.0 || msg.twist.linear.y != 0.0 || msg.twist.linear.z != 0.0 ||
49 msg.twist.angular.x != 0.0 || msg.twist.angular.y != 0.0 || msg.twist.angular.z != 0.0;
53 bool isNonZero(
const control_msgs::msg::JointJog& msg)
55 bool all_zeros =
true;
56 for (
double delta : msg.velocities)
58 all_zeros &= (delta == 0.0);
65 const std::string& parent_frame,
66 const std::string& child_frame)
68 geometry_msgs::msg::TransformStamped output = tf2::eigenToTransform(eigen_tf);
69 output.header.frame_id = parent_frame;
70 output.child_frame_id = child_frame;
89 const Eigen::VectorXd& commanded_twist,
90 const Eigen::JacobiSVD<Eigen::MatrixXd>& svd,
91 const Eigen::MatrixXd& pseudo_inverse,
92 const double hard_stop_singularity_threshold,
93 const double lower_singularity_threshold,
94 const double leaving_singularity_threshold_multiplier, rclcpp::Clock& clock,
95 moveit::core::RobotStatePtr& current_state,
StatusCode& status)
97 double velocity_scale = 1;
98 std::size_t num_dimensions = commanded_twist.size();
104 Eigen::VectorXd vector_toward_singularity = svd.matrixU().col(num_dimensions - 1);
106 double ini_condition = svd.singularValues()(0) / svd.singularValues()(svd.singularValues().size() - 1);
112 Eigen::VectorXd delta_x(num_dimensions);
114 delta_x = vector_toward_singularity / scale;
117 Eigen::VectorXd new_theta;
118 current_state->copyJointGroupPositions(joint_model_group, new_theta);
119 new_theta += pseudo_inverse * delta_x;
120 current_state->setJointGroupPositions(joint_model_group, new_theta);
121 Eigen::MatrixXd new_jacobian = current_state->getJacobian(joint_model_group);
123 Eigen::JacobiSVD<Eigen::MatrixXd> new_svd(new_jacobian);
124 double new_condition = new_svd.singularValues()(0) / new_svd.singularValues()(new_svd.singularValues().size() - 1);
127 if (ini_condition >= new_condition)
129 vector_toward_singularity *= -1;
133 double dot = vector_toward_singularity.dot(commanded_twist);
135 double upper_threshold = dot > 0 ? hard_stop_singularity_threshold :
136 (hard_stop_singularity_threshold - lower_singularity_threshold) *
137 leaving_singularity_threshold_multiplier +
138 lower_singularity_threshold;
139 if ((ini_condition > lower_singularity_threshold) && (ini_condition < hard_stop_singularity_threshold))
142 1. - (ini_condition - lower_singularity_threshold) / (upper_threshold - lower_singularity_threshold);
149 else if (ini_condition >= upper_threshold)
156 return velocity_scale;
constexpr size_t ROS_LOG_THROTTLE_PERIOD
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_APPROACHING_SINGULARITY
@ DECELERATE_FOR_LEAVING_SINGULARITY
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.
const rclcpp::Logger LOGGER