204 moveit_msgs::msg::RobotTrajectory & computedJointTrajectory)
209 if (trajectoryPlanner !=
nullptr)
214 "[CbMoveEndEffectorTrajectory] Using CpJointSpaceTrajectoryPlanner component for IK "
215 "trajectory generation");
231 computedJointTrajectory = result.trajectory;
234 "[CbMoveEndEffectorTrajectory] IK trajectory generation succeeded (via "
235 "CpJointSpaceTrajectoryPlanner)");
240 computedJointTrajectory = result.trajectory;
243 "[CbMoveEndEffectorTrajectory] IK trajectory generation failed (via "
244 "CpJointSpaceTrajectoryPlanner): %s",
245 result.errorMessage.c_str());
248 switch (result.errorCode)
264 "[CbMoveEndEffectorTrajectory] CpJointSpaceTrajectoryPlanner component not available, "
265 "using legacy IK trajectory generation (consider adding CpJointSpaceTrajectoryPlanner "
269 RCLCPP_INFO_STREAM(
getLogger(),
"[" <<
getName() <<
"] getting current state.. waiting");
274 RCLCPP_INFO_STREAM(
getLogger(),
"[" <<
getName() <<
"] getting joint names");
275 auto currentjointnames =
276 currentState->getJointModelGroup(groupname)->getActiveJointModelNames();
283 std::vector<double> jointPositions;
284 currentState->copyJointGroupPositions(groupname, jointPositions);
286 std::vector<std::vector<double>> trajectory;
287 std::vector<rclcpp::Duration> trajectoryTimeStamps;
289 trajectory.push_back(jointPositions);
290 trajectoryTimeStamps.push_back(rclcpp::Duration(0s));
293 rclcpp::Time referenceTime(first.header.stamp);
295 std::vector<int> discontinuityIndexes;
301 auto req = std::make_shared<moveit_msgs::srv::GetPositionIK::Request>();
303 req->ik_request.ik_link_name = *
tipLink_;
304 req->ik_request.robot_state.joint_state.name = currentjointnames;
305 req->ik_request.robot_state.joint_state.position = jointPositions;
306 req->ik_request.group_name = groupname;
307 req->ik_request.avoid_collisions =
true;
308 req->ik_request.pose_stamped = pose;
310 RCLCPP_INFO_STREAM(
getLogger(),
"[" <<
getName() <<
"] IK request: " << k <<
" " << *req);
312 auto resfut =
iksrv_->async_send_request(req);
313 auto status = resfut.wait_for(3s);
315 if (status == std::future_status::ready)
317 auto & prevtrajpoint = trajectory.back();
318 auto res = resfut.get();
320 std::stringstream ss;
321 for (
size_t j = 0; j < res->solution.joint_state.position.size(); j++)
323 auto & jointname = res->solution.joint_state.name[j];
324 auto it = std::find(currentjointnames.begin(), currentjointnames.end(), jointname);
325 if (it != currentjointnames.end())
327 int index = std::distance(currentjointnames.begin(), it);
328 jointPositions[index] = res->solution.joint_state.position[j];
329 ss << jointname <<
"(" << index <<
"): " << jointPositions[index] << std::endl;
334 size_t jointindex = 0;
335 int discontinuityJointIndex = -1;
336 double discontinuityDeltaJointIndex = -1;
341 !(*allowInitialTrajectoryStateJointDiscontinuity_));
344 for (jointindex = 0; jointindex < jointPositions.size(); jointindex++)
346 deltajoint = jointPositions[jointindex] - prevtrajpoint[jointindex];
347 if (fabs(deltajoint) > 0.3)
349 discontinuityDeltaJointIndex = deltajoint;
350 discontinuityJointIndex = jointindex;
355 if (ikAttempts > 0 && discontinuityJointIndex != -1)
363 bool discontinuity =
false;
366 discontinuityIndexes.push_back(k);
367 discontinuity =
true;
372 if (discontinuity && discontinuityJointIndex != -1)
374 std::stringstream ss;
376 << currentjointnames[discontinuityJointIndex]
377 <<
" IK discontinuity : " << discontinuityDeltaJointIndex << std::endl
378 <<
"prev joint value: " << prevtrajpoint[discontinuityJointIndex] << std::endl
379 <<
"current joint value: " << jointPositions[discontinuityJointIndex] << std::endl;
382 for (
size_t ji = 0; ji < jointPositions.size(); ji++)
384 ss << currentjointnames[ji] <<
": " << jointPositions[ji] << std::endl;
387 for (
size_t kindex = 0; kindex < trajectory.size(); kindex++)
389 ss <<
"[" << kindex <<
"]: " << trajectory[kindex][discontinuityJointIndex]
396 <<
"This is the first posture of the trajectory. Maybe the robot initial posture "
398 "not coincident to the initial posture of the generated joint trajectory."
402 RCLCPP_ERROR_STREAM(
getLogger(), ss.str());
404 trajectory.push_back(jointPositions);
405 rclcpp::Duration durationFromStart = rclcpp::Time(pose.header.stamp) - referenceTime;
406 trajectoryTimeStamps.push_back(durationFromStart);
411 trajectory.push_back(jointPositions);
412 rclcpp::Duration durationFromStart = rclcpp::Time(pose.header.stamp) - referenceTime;
413 trajectoryTimeStamps.push_back(durationFromStart);
415 RCLCPP_DEBUG_STREAM(
getLogger(),
"IK solution: " << res->solution.joint_state);
416 RCLCPP_DEBUG_STREAM(
getLogger(),
"trajpoint: " << std::endl << ss.str());
426 computedJointTrajectory.joint_trajectory.joint_names = currentjointnames;
428 for (
auto & p : trajectory)
436 trajectory_msgs::msg::JointTrajectoryPoint jp;
438 jp.time_from_start = trajectoryTimeStamps[i];
439 computedJointTrajectory.joint_trajectory.points.push_back(jp);
443 if (discontinuityIndexes.size())
445 if (discontinuityIndexes[0] == 0)
529 tf2::Transform localdirection;
530 localdirection.setIdentity();
531 localdirection.setOrigin(tf2::Vector3(0.05, 0, 0));
536 visualization_msgs::msg::Marker marker;
537 marker.header.frame_id = frameid;
538 marker.header.stamp =
getNode()->now();
539 marker.ns =
"trajectory";
541 marker.type = visualization_msgs::msg::Marker::ARROW;
542 marker.action = visualization_msgs::msg::Marker::ADD;
543 marker.scale.x = 0.005;
544 marker.scale.y = 0.01;
545 marker.scale.z = 0.01;
546 marker.color.a = 0.8;
547 marker.color.r = 1.0;
551 geometry_msgs::msg::Point start, end;
556 tf2::Transform basetransform;
557 tf2::fromMsg(pose.pose, basetransform);
560 end.x = localdirection.getOrigin().x();
561 end.y = localdirection.getOrigin().y();
562 end.z = localdirection.getOrigin().z();
564 marker.pose.position = pose.pose.position;
565 marker.pose.orientation = pose.pose.orientation;
566 marker.points.push_back(start);
567 marker.points.push_back(end);
582 std::string globalFrame, tf2::Stamped<tf2::Transform> & currentEndEffectorTransform)
594 if (tfListener !=
nullptr)
600 tf2::fromMsg(transformOpt.value(), currentEndEffectorTransform);
606 <<
" to " << globalFrame);
614 <<
"] CpTfListener component not available, using legacy TF2 (consider "
615 "adding CpTfListener component)");
616 tf2_ros::Buffer tfBuffer(
getNode()->get_clock());
617 tf2_ros::TransformListener tfListenerLegacy(tfBuffer);
620 tfBuffer.lookupTransform(globalFrame, *
tipLink_, rclcpp::Time(0), rclcpp::Duration(10s)),
621 currentEndEffectorTransform);
624 catch (
const std::exception & e)
627 getLogger(),
"[" <<
getName() <<
"] Exception in getCurrentEndEffectorPose: " << e.what());