SMACC2
Loading...
Searching...
No Matches
cl_moveit2z::CbMoveEndEffectorTrajectory Class Referenceabstract

#include <cb_move_end_effector_trajectory.hpp>

Inheritance diagram for cl_moveit2z::CbMoveEndEffectorTrajectory:
Inheritance graph
Collaboration diagram for cl_moveit2z::CbMoveEndEffectorTrajectory:
Collaboration graph

Public Member Functions

 CbMoveEndEffectorTrajectory (std::optional< std::string > tipLink=std::nullopt)
 
 CbMoveEndEffectorTrajectory (const std::vector< geometry_msgs::msg::PoseStamped > &endEffectorTrajectory, std::optional< std::string > tipLink=std::nullopt)
 
template<typename TOrthogonal , typename TSourceObject >
void onOrthogonalAllocation ()
 
virtual void onEntry () override
 
virtual void onExit () override
 
 CbMoveEndEffectorTrajectory (std::optional< std::string > tipLink=std::nullopt)
 
 CbMoveEndEffectorTrajectory (const std::vector< geometry_msgs::msg::PoseStamped > &endEffectorTrajectory, std::optional< std::string > tipLink=std::nullopt)
 
template<typename TOrthogonal , typename TSourceObject >
void onOrthogonalAllocation ()
 
virtual void onEntry () override
 
virtual void onExit () override
 
virtual void update () override
 
- Public Member Functions inherited from smacc2::SmaccAsyncClientBehavior
template<typename TOrthogonal , typename TSourceObject >
void onOrthogonalAllocation ()
 
template<typename TOrthogonal , typename TSourceObject >
void onStateOrthogonalAllocation ()
 
virtual ~SmaccAsyncClientBehavior ()
 
template<typename TCallback , typename T >
boost::signals2::connection onSuccess (TCallback callback, T *object)
 
template<typename TCallback , typename T >
boost::signals2::connection onFinished (TCallback callback, T *object)
 
template<typename TCallback , typename T >
boost::signals2::connection onFailure (TCallback callback, T *object)
 
void requestForceFinish ()
 
void executeOnEntry () override
 
void executeOnExit () override
 
void waitOnEntryThread (bool requestFinish)
 
template<typename TCallbackMethod , typename T >
boost::signals2::connection onSuccess (TCallbackMethod callback, T *object)
 
template<typename TCallbackMethod , typename T >
boost::signals2::connection onFinished (TCallbackMethod callback, T *object)
 
template<typename TCallbackMethod , typename T >
boost::signals2::connection onFailure (TCallbackMethod callback, T *object)
 
- Public Member Functions inherited from smacc2::ISmaccClientBehavior
 ISmaccClientBehavior ()
 
virtual ~ISmaccClientBehavior ()
 
ISmaccStateMachinegetStateMachine ()
 
std::string getName () const
 
template<typename SmaccClientType >
void requiresClient (SmaccClientType *&storage)
 
template<typename SmaccComponentType >
void requiresComponent (SmaccComponentType *&storage, bool throwExceptionIfNotExist)
 
template<typename SmaccComponentType >
void requiresComponent (SmaccComponentType *&storage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
- Public Member Functions inherited from smacc2::ISmaccUpdatable
 ISmaccUpdatable ()
 
 ISmaccUpdatable (rclcpp::Duration duration)
 
void executeUpdate (rclcpp::Node::SharedPtr node)
 
void setUpdatePeriod (rclcpp::Duration duration)
 

Public Attributes

std::optional< std::string > group_
 
std::optional< std::string > tipLink_
 
std::optional< bool > allowInitialTrajectoryStateJointDiscontinuity_
 

Protected Member Functions

ComputeJointTrajectoryErrorCode computeJointSpaceTrajectory (moveit_msgs::msg::RobotTrajectory &computedJointTrajectory)
 
void executeJointSpaceTrajectory (const moveit_msgs::msg::RobotTrajectory &computedJointTrajectory)
 
virtual void generateTrajectory ()
 
virtual void createMarkers ()
 
void getCurrentEndEffectorPose (std::string globalFrame, tf2::Stamped< tf2::Transform > &currentEndEffectorTransform)
 
ComputeJointTrajectoryErrorCode computeJointSpaceTrajectory (moveit_msgs::msg::RobotTrajectory &computedJointTrajectory)
 
void executeJointSpaceTrajectory (const moveit_msgs::msg::RobotTrajectory &computedJointTrajectory)
 
virtual void generateTrajectory ()=0
 
virtual void createMarkers ()
 
void getCurrentEndEffectorPose (std::string globalFrame, tf2::Stamped< tf2::Transform > &currentEndEffectorTransform)
 
- Protected Member Functions inherited from smacc2::SmaccAsyncClientBehavior
void postSuccessEvent ()
 
void postFailureEvent ()
 
virtual void dispose () override
 
bool isShutdownRequested ()
 onEntry is executed in a new thread. However the current state cannot be left until the onEntry thread finishes. This flag can be checked from the onEntry thread to force finishing the thread.
 
- Protected Member Functions inherited from smacc2::ISmaccClientBehavior
virtual void runtimeConfigure ()
 
template<typename EventType >
void postEvent (const EventType &ev)
 
template<typename EventType >
void postEvent ()
 
ISmaccStategetCurrentState ()
 
virtual rclcpp::Node::SharedPtr getNode () const
 
virtual rclcpp::Logger getLogger () const
 
- Protected Member Functions inherited from smacc2::ISmaccUpdatable

Protected Attributes

std::vector< geometry_msgs::msg::PoseStamped > endEffectorTrajectory_
 
ClMoveit2zmovegroupClient_ = nullptr
 
visualization_msgs::msg::MarkerArray beahiorMarkers_
 

Private Member Functions

void initializeROS ()
 
void initializeROS ()
 

Private Attributes

rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr markersPub_
 
rclcpp::Client< moveit_msgs::srv::GetPositionIK >::SharedPtr iksrv_
 
std::mutex m_mutex_
 
std::function< void(moveit_msgs::msg::RobotTrajectory &)> postJointDiscontinuityEvent
 
std::function< void(moveit_msgs::msg::RobotTrajectory &)> postIncorrectInitialStateEvent
 
std::function< void()> postMotionExecutionFailureEvents
 
bool autocleanmarkers = false
 
std::atomic< bool > markersInitialized_
 

Detailed Description

Definition at line 51 of file cb_move_end_effector_trajectory.hpp.

Constructor & Destructor Documentation

◆ CbMoveEndEffectorTrajectory() [1/4]

cl_moveit2z::CbMoveEndEffectorTrajectory::CbMoveEndEffectorTrajectory ( std::optional< std::string > tipLink = std::nullopt)
inline

Definition at line 70 of file cb_move_end_effector_trajectory.hpp.

70 : tipLink_(tipLink)
71 {
72 }

◆ CbMoveEndEffectorTrajectory() [2/4]

cl_moveit2z::CbMoveEndEffectorTrajectory::CbMoveEndEffectorTrajectory ( const std::vector< geometry_msgs::msg::PoseStamped > & endEffectorTrajectory,
std::optional< std::string > tipLink = std::nullopt )
inline

Definition at line 74 of file cb_move_end_effector_trajectory.hpp.

77 : tipLink_(tipLink), endEffectorTrajectory_(endEffectorTrajectory)
78 {
79 }
std::vector< geometry_msgs::msg::PoseStamped > endEffectorTrajectory_

◆ CbMoveEndEffectorTrajectory() [3/4]

cl_moveit2z::CbMoveEndEffectorTrajectory::CbMoveEndEffectorTrajectory ( std::optional< std::string > tipLink = std::nullopt)

◆ CbMoveEndEffectorTrajectory() [4/4]

cl_moveit2z::CbMoveEndEffectorTrajectory::CbMoveEndEffectorTrajectory ( const std::vector< geometry_msgs::msg::PoseStamped > & endEffectorTrajectory,
std::optional< std::string > tipLink = std::nullopt )

Member Function Documentation

◆ computeJointSpaceTrajectory() [1/2]

ComputeJointTrajectoryErrorCode cl_moveit2z::CbMoveEndEffectorTrajectory::computeJointSpaceTrajectory ( moveit_msgs::msg::RobotTrajectory & computedJointTrajectory)
inlineprotected

Definition at line 228 of file cb_move_end_effector_trajectory.hpp.

230 {
231 // Try to use CpJointSpaceTrajectoryPlanner component (preferred)
232 CpJointSpaceTrajectoryPlanner * trajectoryPlanner = nullptr;
233 this->requiresComponent(trajectoryPlanner, false); // Optional component
234
235 if (trajectoryPlanner != nullptr)
236 {
237 // Use component-based trajectory planner (preferred)
238 RCLCPP_INFO(
239 getLogger(),
240 "[CbMoveEndEffectorTrajectory] Using CpJointSpaceTrajectoryPlanner component for IK "
241 "trajectory generation");
242
243 JointTrajectoryOptions options;
244 if (tipLink_ && !tipLink_->empty())
245 {
246 options.tipLink = *tipLink_;
247 }
249 {
250 options.allowInitialDiscontinuity = *allowInitialTrajectoryStateJointDiscontinuity_;
251 }
252
253 auto result = trajectoryPlanner->planFromWaypoints(endEffectorTrajectory_, options);
254
255 if (result.success)
256 {
257 computedJointTrajectory = result.trajectory;
258 RCLCPP_INFO(
259 getLogger(),
260 "[CbMoveEndEffectorTrajectory] IK trajectory generation succeeded (via "
261 "CpJointSpaceTrajectoryPlanner)");
263 }
264 else
265 {
266 computedJointTrajectory = result.trajectory; // Still return partial trajectory
267 RCLCPP_WARN(
268 getLogger(),
269 "[CbMoveEndEffectorTrajectory] IK trajectory generation failed (via "
270 "CpJointSpaceTrajectoryPlanner): %s",
271 result.errorMessage.c_str());
272
273 // Map error codes
274 switch (result.errorCode)
275 {
280 default:
282 }
283 }
284 }
285 else
286 {
287 // Fallback to legacy IK trajectory generation
288 RCLCPP_WARN(
289 getLogger(),
290 "[CbMoveEndEffectorTrajectory] CpJointSpaceTrajectoryPlanner component not available, "
291 "using legacy IK trajectory generation (consider adding CpJointSpaceTrajectoryPlanner "
292 "component)");
293
294 // LEGACY IMPLEMENTATION (keep for backward compatibility)
295 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] getting current state.. waiting");
296
297 auto currentState = movegroupClient_->moveGroupClientInterface->getCurrentState(100);
298 auto groupname = movegroupClient_->moveGroupClientInterface->getName();
299
300 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] getting joint names");
301 auto currentjointnames =
302 currentState->getJointModelGroup(groupname)->getActiveJointModelNames();
303
304 if (!tipLink_ || *tipLink_ == "")
305 {
306 tipLink_ = movegroupClient_->moveGroupClientInterface->getEndEffectorLink();
307 }
308
309 std::vector<double> jointPositions;
310 currentState->copyJointGroupPositions(groupname, jointPositions);
311
312 std::vector<std::vector<double>> trajectory;
313 std::vector<rclcpp::Duration> trajectoryTimeStamps;
314
315 trajectory.push_back(jointPositions);
316 trajectoryTimeStamps.push_back(rclcpp::Duration(0s));
317
318 auto & first = endEffectorTrajectory_.front();
319 rclcpp::Time referenceTime(first.header.stamp);
320
321 std::vector<int> discontinuityIndexes;
322
323 int ikAttempts = 4;
324 for (size_t k = 0; k < this->endEffectorTrajectory_.size(); k++)
325 {
326 auto & pose = this->endEffectorTrajectory_[k];
327 auto req = std::make_shared<moveit_msgs::srv::GetPositionIK::Request>();
328
329 req->ik_request.ik_link_name = *tipLink_;
330 req->ik_request.robot_state.joint_state.name = currentjointnames;
331 req->ik_request.robot_state.joint_state.position = jointPositions;
332 req->ik_request.group_name = groupname;
333 req->ik_request.avoid_collisions = true;
334 req->ik_request.pose_stamped = pose;
335
336 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] IK request: " << k << " " << *req);
337
338 auto resfut = iksrv_->async_send_request(req);
339 auto status = resfut.wait_for(3s);
340
341 if (status == std::future_status::ready)
342 {
343 auto & prevtrajpoint = trajectory.back();
344 auto res = resfut.get();
345
346 std::stringstream ss;
347 for (size_t j = 0; j < res->solution.joint_state.position.size(); j++)
348 {
349 auto & jointname = res->solution.joint_state.name[j];
350 auto it = std::find(currentjointnames.begin(), currentjointnames.end(), jointname);
351 if (it != currentjointnames.end())
352 {
353 int index = std::distance(currentjointnames.begin(), it);
354 jointPositions[index] = res->solution.joint_state.position[j];
355 ss << jointname << "(" << index << "): " << jointPositions[index] << std::endl;
356 }
357 }
358
359 // Continuity check
360 size_t jointindex = 0;
361 int discontinuityJointIndex = -1;
362 double discontinuityDeltaJointIndex = -1;
363 double deltajoint;
364
365 bool check = k > 0 || !allowInitialTrajectoryStateJointDiscontinuity_ ||
367 !(*allowInitialTrajectoryStateJointDiscontinuity_));
368 if (check)
369 {
370 for (jointindex = 0; jointindex < jointPositions.size(); jointindex++)
371 {
372 deltajoint = jointPositions[jointindex] - prevtrajpoint[jointindex];
373 if (fabs(deltajoint) > 0.3)
374 {
375 discontinuityDeltaJointIndex = deltajoint;
376 discontinuityJointIndex = jointindex;
377 }
378 }
379 }
380
381 if (ikAttempts > 0 && discontinuityJointIndex != -1)
382 {
383 k--;
384 ikAttempts--;
385 continue;
386 }
387 else
388 {
389 bool discontinuity = false;
390 if (ikAttempts == 0)
391 {
392 discontinuityIndexes.push_back(k);
393 discontinuity = true;
394 }
395
396 ikAttempts = 4;
397
398 if (discontinuity && discontinuityJointIndex != -1)
399 {
400 std::stringstream ss;
401 ss << "Traj[" << k << "/" << endEffectorTrajectory_.size() << "] "
402 << currentjointnames[discontinuityJointIndex]
403 << " IK discontinuity : " << discontinuityDeltaJointIndex << std::endl
404 << "prev joint value: " << prevtrajpoint[discontinuityJointIndex] << std::endl
405 << "current joint value: " << jointPositions[discontinuityJointIndex] << std::endl;
406
407 ss << std::endl;
408 for (size_t ji = 0; ji < jointPositions.size(); ji++)
409 {
410 ss << currentjointnames[ji] << ": " << jointPositions[ji] << std::endl;
411 }
412
413 for (size_t kindex = 0; kindex < trajectory.size(); kindex++)
414 {
415 ss << "[" << kindex << "]: " << trajectory[kindex][discontinuityJointIndex]
416 << std::endl;
417 }
418
419 if (k == 0)
420 {
421 ss
422 << "This is the first posture of the trajectory. Maybe the robot initial posture "
423 "is "
424 "not coincident to the initial posture of the generated joint trajectory."
425 << std::endl;
426 }
427
428 RCLCPP_ERROR_STREAM(getLogger(), ss.str());
429
430 trajectory.push_back(jointPositions);
431 rclcpp::Duration durationFromStart = rclcpp::Time(pose.header.stamp) - referenceTime;
432 trajectoryTimeStamps.push_back(durationFromStart);
433 continue;
434 }
435 else
436 {
437 trajectory.push_back(jointPositions);
438 rclcpp::Duration durationFromStart = rclcpp::Time(pose.header.stamp) - referenceTime;
439 trajectoryTimeStamps.push_back(durationFromStart);
440
441 RCLCPP_DEBUG_STREAM(getLogger(), "IK solution: " << res->solution.joint_state);
442 RCLCPP_DEBUG_STREAM(getLogger(), "trajpoint: " << std::endl << ss.str());
443 }
444 }
445 }
446 else
447 {
448 RCLCPP_ERROR_STREAM(getLogger(), "[" << getName() << "] wrong IK call");
449 }
450 }
451
452 computedJointTrajectory.joint_trajectory.joint_names = currentjointnames;
453 int i = 0;
454 for (auto & p : trajectory)
455 {
456 if (i == 0) // Skip current state
457 {
458 i++;
459 continue;
460 }
461
462 trajectory_msgs::msg::JointTrajectoryPoint jp;
463 jp.positions = p;
464 jp.time_from_start = trajectoryTimeStamps[i];
465 computedJointTrajectory.joint_trajectory.points.push_back(jp);
466 i++;
467 }
468
469 if (discontinuityIndexes.size())
470 {
471 if (discontinuityIndexes[0] == 0)
473 else
475 }
476
478 }
479 }
rclcpp::Client< moveit_msgs::srv::GetPositionIK >::SharedPtr iksrv_
std::shared_ptr< moveit::planning_interface::MoveGroupInterface > moveGroupClientInterface
void requiresComponent(SmaccComponentType *&storage, bool throwExceptionIfNotExist)
virtual rclcpp::Logger getLogger() const

References cl_moveit2z::JointTrajectoryOptions::allowInitialDiscontinuity, allowInitialTrajectoryStateJointDiscontinuity_, smacc2::ISmaccClientBehavior::currentState, endEffectorTrajectory_, smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), iksrv_, cl_moveit2z::INCORRECT_INITIAL_STATE, cl_moveit2z::JOINT_TRAJECTORY_DISCONTINUITY, movegroupClient_, cl_moveit2z::ClMoveit2z::moveGroupClientInterface, cl_moveit2z::CpJointSpaceTrajectoryPlanner::planFromWaypoints(), smacc2::ISmaccClientBehavior::requiresComponent(), cl_moveit2z::SUCCESS, cl_moveit2z::JointTrajectoryOptions::tipLink, and tipLink_.

Referenced by onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ computeJointSpaceTrajectory() [2/2]

ComputeJointTrajectoryErrorCode cl_moveit2z::CbMoveEndEffectorTrajectory::computeJointSpaceTrajectory ( moveit_msgs::msg::RobotTrajectory & computedJointTrajectory)
protected

◆ createMarkers() [1/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::createMarkers ( )
inlineprotectedvirtual

Reimplemented in cl_moveit2z::CbCircularPivotMotion, cl_moveit2z::CbCircularPivotMotion, and cl_moveit2z::CbCircularPouringMotion.

Definition at line 556 of file cb_move_end_effector_trajectory.hpp.

557 {
558 tf2::Transform localdirection;
559 localdirection.setIdentity();
560 localdirection.setOrigin(tf2::Vector3(0.05, 0, 0));
561 auto frameid = this->endEffectorTrajectory_.front().header.frame_id;
562
563 for (auto & pose : this->endEffectorTrajectory_)
564 {
565 visualization_msgs::msg::Marker marker;
566 marker.header.frame_id = frameid;
567 marker.header.stamp = getNode()->now();
568 marker.ns = "trajectory";
569 marker.id = this->beahiorMarkers_.markers.size();
570 marker.type = visualization_msgs::msg::Marker::ARROW;
571 marker.action = visualization_msgs::msg::Marker::ADD;
572 marker.scale.x = 0.005;
573 marker.scale.y = 0.01;
574 marker.scale.z = 0.01;
575 marker.color.a = 0.8;
576 marker.color.r = 1.0;
577 marker.color.g = 0;
578 marker.color.b = 0;
579
580 geometry_msgs::msg::Point start, end;
581 start.x = 0;
582 start.y = 0;
583 start.z = 0;
584
585 tf2::Transform basetransform;
586 tf2::fromMsg(pose.pose, basetransform);
587 // tf2::Transform endarrow = localdirection * basetransform;
588
589 end.x = localdirection.getOrigin().x();
590 end.y = localdirection.getOrigin().y();
591 end.z = localdirection.getOrigin().z();
592
593 marker.pose.position = pose.pose.position;
594 marker.pose.orientation = pose.pose.orientation;
595 marker.points.push_back(start);
596 marker.points.push_back(end);
597
598 beahiorMarkers_.markers.push_back(marker);
599 }
600 }
virtual rclcpp::Node::SharedPtr getNode() const
const std::string frameid

References beahiorMarkers_, endEffectorTrajectory_, and smacc2::ISmaccClientBehavior::getNode().

Referenced by cl_moveit2z::CbCircularPivotMotion::createMarkers(), cl_moveit2z::CbCircularPouringMotion::createMarkers(), and onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createMarkers() [2/2]

virtual void cl_moveit2z::CbMoveEndEffectorTrajectory::createMarkers ( )
protectedvirtual

◆ executeJointSpaceTrajectory() [1/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::executeJointSpaceTrajectory ( const moveit_msgs::msg::RobotTrajectory & computedJointTrajectory)
inlineprotected

Definition at line 481 of file cb_move_end_effector_trajectory.hpp.

483 {
484 RCLCPP_INFO_STREAM(getLogger(), "[" << this->getName() << "] Executing joint trajectory");
485
486 // Try to use CpTrajectoryExecutor component (preferred)
487 CpTrajectoryExecutor * trajectoryExecutor = nullptr;
488 this->requiresComponent(trajectoryExecutor, false); // Optional component
489
490 bool executionSuccess = false;
491
492 if (trajectoryExecutor != nullptr)
493 {
494 // Use component-based trajectory executor (preferred)
495 RCLCPP_INFO(
496 getLogger(),
497 "[CbMoveEndEffectorTrajectory] Using CpTrajectoryExecutor component for execution");
498
499 ExecutionOptions execOptions;
500 execOptions.trajectoryName = this->getName();
501
502 auto execResult = trajectoryExecutor->execute(computedJointTrajectory, execOptions);
503 executionSuccess = execResult.success;
504
505 if (executionSuccess)
506 {
507 RCLCPP_INFO(
508 getLogger(),
509 "[CbMoveEndEffectorTrajectory] Execution succeeded (via CpTrajectoryExecutor)");
510 }
511 else
512 {
513 RCLCPP_WARN(
514 getLogger(),
515 "[CbMoveEndEffectorTrajectory] Execution failed (via CpTrajectoryExecutor): %s",
516 execResult.errorMessage.c_str());
517 }
518 }
519 else
520 {
521 // Fallback to legacy direct execution
522 RCLCPP_WARN(
523 getLogger(),
524 "[CbMoveEndEffectorTrajectory] CpTrajectoryExecutor component not available, using legacy "
525 "execution (consider adding CpTrajectoryExecutor component)");
526
527 auto executionResult =
528 this->movegroupClient_->moveGroupClientInterface->execute(computedJointTrajectory);
529 executionSuccess = (executionResult == moveit_msgs::msg::MoveItErrorCodes::SUCCESS);
530
531 RCLCPP_INFO(
532 getLogger(), "[CbMoveEndEffectorTrajectory] Execution %s (legacy mode)",
533 executionSuccess ? "succeeded" : "failed");
534 }
535
536 // Post events
537 if (executionSuccess)
538 {
539 RCLCPP_INFO_STREAM(getLogger(), "[" << this->getName() << "] motion execution succeeded");
541 this->postSuccessEvent();
542 }
543 else
544 {
546 this->postFailureEvent();
547 }
548 }

References cl_moveit2z::CpTrajectoryExecutor::execute(), smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), movegroupClient_, cl_moveit2z::ClMoveit2z::moveGroupClientInterface, cl_moveit2z::ClMoveit2z::postEventMotionExecutionSucceded(), smacc2::SmaccAsyncClientBehavior::postFailureEvent(), postMotionExecutionFailureEvents, smacc2::SmaccAsyncClientBehavior::postSuccessEvent(), smacc2::ISmaccClientBehavior::requiresComponent(), and cl_moveit2z::ExecutionOptions::trajectoryName.

Referenced by cl_moveit2z::CbExecuteLastTrajectory::onEntry(), onEntry(), and cl_moveit2z::CbUndoLastTrajectory::onEntry().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ executeJointSpaceTrajectory() [2/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::executeJointSpaceTrajectory ( const moveit_msgs::msg::RobotTrajectory & computedJointTrajectory)
protected

◆ generateTrajectory() [1/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::generateTrajectory ( )
inlineprotectedvirtual

Reimplemented in cl_moveit2z::CbCircularPivotMotion, cl_moveit2z::CbCircularPivotMotion, cl_moveit2z::CbCircularPouringMotion, cl_moveit2z::CbExecuteLastTrajectory, cl_moveit2z::CbMoveCartesianRelative2, cl_moveit2z::CbMoveCartesianRelative2, cl_moveit2z::CbUndoLastTrajectory, and cl_moveit2z::CbUndoLastTrajectory.

Definition at line 550 of file cb_move_end_effector_trajectory.hpp.

551 {
552 // bypass current trajectory, overridden in derived classes
553 // this->endEffectorTrajectory_ = ...
554 }

Referenced by onEntry().

Here is the caller graph for this function:

◆ generateTrajectory() [2/2]

◆ getCurrentEndEffectorPose() [1/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::getCurrentEndEffectorPose ( std::string globalFrame,
tf2::Stamped< tf2::Transform > & currentEndEffectorTransform )
inlineprotected

Definition at line 608 of file cb_move_end_effector_trajectory.hpp.

610 {
611 // Use CpTfListener component for transform lookups
612 CpTfListener * tfListener = nullptr;
613 this->requiresComponent(tfListener, false); // Optional component
614
615 try
616 {
617 if (!tipLink_ || *tipLink_ == "")
618 {
619 tipLink_ = this->movegroupClient_->moveGroupClientInterface->getEndEffectorLink();
620 }
621
622 if (tfListener != nullptr)
623 {
624 // Use component-based TF listener (preferred)
625 auto transformOpt = tfListener->lookupTransform(globalFrame, *tipLink_, rclcpp::Time(0));
626 if (transformOpt)
627 {
628 tf2::fromMsg(transformOpt.value(), currentEndEffectorTransform);
629 }
630 else
631 {
632 RCLCPP_ERROR_STREAM(
633 getLogger(), "[" << getName() << "] Failed to lookup transform from " << *tipLink_
634 << " to " << globalFrame);
635 }
636 }
637 else
638 {
639 // Fallback to legacy TF2 usage if component not available
640 RCLCPP_WARN_STREAM(
641 getLogger(), "[" << getName()
642 << "] CpTfListener component not available, using legacy TF2 (consider "
643 "adding CpTfListener component)");
644 tf2_ros::Buffer tfBuffer(getNode()->get_clock());
645 tf2_ros::TransformListener tfListenerLegacy(tfBuffer);
646
647 tf2::fromMsg(
648 tfBuffer.lookupTransform(globalFrame, *tipLink_, rclcpp::Time(0), rclcpp::Duration(10s)),
649 currentEndEffectorTransform);
650 }
651 }
652 catch (const std::exception & e)
653 {
654 RCLCPP_ERROR_STREAM(
655 getLogger(), "[" << getName() << "] Exception in getCurrentEndEffectorPose: " << e.what());
656 }
657 }

References smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), smacc2::ISmaccClientBehavior::getNode(), cl_moveit2z::CpTfListener::lookupTransform(), cl_moveit2z::ClMoveit2z::moveGroupClientInterface, smacc2::ISmaccClientBehavior::requiresComponent(), and tipLink_.

Referenced by cl_moveit2z::CbCircularPouringMotion::createMarkers(), cl_moveit2z::CbCircularPouringMotion::generateTrajectory(), and cl_moveit2z::CbMoveCartesianRelative2::generateTrajectory().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCurrentEndEffectorPose() [2/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::getCurrentEndEffectorPose ( std::string globalFrame,
tf2::Stamped< tf2::Transform > & currentEndEffectorTransform )
protected

◆ initializeROS() [1/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::initializeROS ( )
inlineprivate

Definition at line 660 of file cb_move_end_effector_trajectory.hpp.

661 {
662 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] initializing ros");
663
664 auto nh = this->getNode();
665
666 // Only create marker publisher for legacy mode (when CpTrajectoryVisualizer is not used)
667 markersPub_ = nh->create_publisher<visualization_msgs::msg::MarkerArray>(
668 "trajectory_markers", rclcpp::QoS(1));
669
670 iksrv_ = nh->create_client<moveit_msgs::srv::GetPositionIK>("/compute_ik");
671 }
rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr markersPub_

References smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), smacc2::ISmaccClientBehavior::getNode(), iksrv_, and markersPub_.

Referenced by onOrthogonalAllocation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initializeROS() [2/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::initializeROS ( )
private

◆ onEntry() [1/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::onEntry ( )
inlineoverridevirtual

Reimplemented from smacc2::ISmaccClientBehavior.

Reimplemented in cl_moveit2z::CbEndEffectorRotate, cl_moveit2z::CbEndEffectorRotate, cl_moveit2z::CbExecuteLastTrajectory, cl_moveit2z::CbUndoLastTrajectory, and cl_moveit2z::CbUndoLastTrajectory.

Definition at line 110 of file cb_move_end_effector_trajectory.hpp.

111 {
113
114 // Get optional components for visualization
115 CpTrajectoryVisualizer * trajectoryVisualizer = nullptr;
116 this->requiresComponent(trajectoryVisualizer, false); // Optional component
117
118 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] Generating end effector trajectory");
119
120 this->generateTrajectory();
121
122 if (this->endEffectorTrajectory_.size() == 0)
123 {
124 RCLCPP_WARN_STREAM(
125 getLogger(), "[" << smacc2::demangleSymbol(typeid(*this).name())
126 << "] No points in the trajectory. Skipping behavior.");
127 return;
128 }
129
130 // Use CpTrajectoryVisualizer if available, otherwise use legacy marker system
131 if (trajectoryVisualizer != nullptr)
132 {
133 RCLCPP_INFO_STREAM(
134 getLogger(),
135 "[" << getName() << "] Setting trajectory visualization using CpTrajectoryVisualizer.");
136 trajectoryVisualizer->setTrajectory(this->endEffectorTrajectory_, "trajectory");
137 }
138 else
139 {
140 RCLCPP_INFO_STREAM(
141 getLogger(), "[" << getName()
142 << "] Creating markers (legacy mode - consider adding "
143 "CpTrajectoryVisualizer component).");
144 this->createMarkers();
145 }
146
147 moveit_msgs::msg::RobotTrajectory computedTrajectory;
148
149 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] Computing joint space trajectory.");
150
151 auto errorcode = computeJointSpaceTrajectory(computedTrajectory);
152
153 bool trajectoryGenerationSuccess = errorcode == ComputeJointTrajectoryErrorCode::SUCCESS;
154
155 CpTrajectoryHistory * trajectoryHistory;
156 this->requiresComponent(trajectoryHistory);
157
158 if (!trajectoryGenerationSuccess)
159 {
160 RCLCPP_INFO_STREAM(
161 getLogger(), "[" << this->getName() << "] Incorrect trajectory. Posting failure event.");
162 if (trajectoryHistory != nullptr)
163 {
164 moveit_msgs::msg::MoveItErrorCodes error;
165 error.val = moveit_msgs::msg::MoveItErrorCodes::NO_IK_SOLUTION;
166 trajectoryHistory->pushTrajectory(this->getName(), computedTrajectory, error);
167 }
168
170 this->postFailureEvent();
171
173 {
174 this->postJointDiscontinuityEvent(computedTrajectory);
175 }
177 {
178 this->postIncorrectInitialStateEvent(computedTrajectory);
179 }
180 return;
181 }
182 else
183 {
184 if (trajectoryHistory != nullptr)
185 {
186 moveit_msgs::msg::MoveItErrorCodes error;
187 error.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
188 trajectoryHistory->pushTrajectory(this->getName(), computedTrajectory, error);
189 }
190
191 this->executeJointSpaceTrajectory(computedTrajectory);
192 }
193
194 // handle finishing events
195 }
std::function< void(moveit_msgs::msg::RobotTrajectory &)> postIncorrectInitialStateEvent
std::function< void(moveit_msgs::msg::RobotTrajectory &)> postJointDiscontinuityEvent
ComputeJointTrajectoryErrorCode computeJointSpaceTrajectory(moveit_msgs::msg::RobotTrajectory &computedJointTrajectory)
void executeJointSpaceTrajectory(const moveit_msgs::msg::RobotTrajectory &computedJointTrajectory)
void requiresClient(SmaccClientType *&storage)
std::string demangleSymbol()

References computeJointSpaceTrajectory(), createMarkers(), smacc2::introspection::demangleSymbol(), endEffectorTrajectory_, executeJointSpaceTrajectory(), generateTrajectory(), smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), cl_moveit2z::INCORRECT_INITIAL_STATE, cl_moveit2z::JOINT_TRAJECTORY_DISCONTINUITY, movegroupClient_, cl_moveit2z::ClMoveit2z::postEventMotionExecutionFailed(), smacc2::SmaccAsyncClientBehavior::postFailureEvent(), postIncorrectInitialStateEvent, postJointDiscontinuityEvent, cl_moveit2z::CpTrajectoryHistory::pushTrajectory(), smacc2::ISmaccClientBehavior::requiresClient(), smacc2::ISmaccClientBehavior::requiresComponent(), cl_moveit2z::CpTrajectoryVisualizer::setTrajectory(), and cl_moveit2z::SUCCESS.

Here is the call graph for this function:

◆ onEntry() [2/2]

virtual void cl_moveit2z::CbMoveEndEffectorTrajectory::onEntry ( )
overridevirtual

◆ onExit() [1/2]

void cl_moveit2z::CbMoveEndEffectorTrajectory::onExit ( )
inlineoverridevirtual

Reimplemented from smacc2::ISmaccClientBehavior.

Definition at line 197 of file cb_move_end_effector_trajectory.hpp.

198 {
199 // Get optional components for visualization cleanup
200 CpTrajectoryVisualizer * trajectoryVisualizer = nullptr;
201 this->requiresComponent(trajectoryVisualizer, false); // Optional component
202
203 if (trajectoryVisualizer != nullptr && autocleanmarkers)
204 {
205 RCLCPP_INFO_STREAM(
206 getLogger(),
207 "[" << getName() << "] Clearing trajectory markers via CpTrajectoryVisualizer.");
208 trajectoryVisualizer->clearMarkers();
209 }
210 else if (autocleanmarkers)
211 {
212 // Legacy marker cleanup
213 std::lock_guard<std::mutex> guard(m_mutex_);
214 for (auto & marker : this->beahiorMarkers_.markers)
215 {
216 marker.header.stamp = getNode()->now();
217 marker.action = visualization_msgs::msg::Marker::DELETE;
218 }
219
220 if (markersPub_)
221 {
223 }
224 }
225 }

References autocleanmarkers, beahiorMarkers_, cl_moveit2z::CpTrajectoryVisualizer::clearMarkers(), smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), smacc2::ISmaccClientBehavior::getNode(), m_mutex_, markersPub_, and smacc2::ISmaccClientBehavior::requiresComponent().

Here is the call graph for this function:

◆ onExit() [2/2]

virtual void cl_moveit2z::CbMoveEndEffectorTrajectory::onExit ( )
overridevirtual

Reimplemented from smacc2::ISmaccClientBehavior.

◆ onOrthogonalAllocation() [1/2]

template<typename TOrthogonal , typename TSourceObject >
void cl_moveit2z::CbMoveEndEffectorTrajectory::onOrthogonalAllocation ( )
inline

Definition at line 82 of file cb_move_end_effector_trajectory.hpp.

83 {
84 this->initializeROS();
85
87
88 postJointDiscontinuityEvent = [this](auto traj)
89 {
90 auto ev = new EvJointDiscontinuity<TSourceObject, TOrthogonal>();
91 ev->trajectory = traj;
92 this->postEvent(ev);
93 };
94
95 postIncorrectInitialStateEvent = [this](auto traj)
96 {
97 auto ev = new EvIncorrectInitialPosition<TSourceObject, TOrthogonal>();
98 ev->trajectory = traj;
99 this->postEvent(ev);
100 };
101
103 {
104 RCLCPP_INFO_STREAM(getLogger(), "[" << this->getName() << "] motion execution failed");
107 };
108 }

References smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), initializeROS(), movegroupClient_, smacc2::SmaccAsyncClientBehavior::onOrthogonalAllocation(), smacc2::ISmaccClientBehavior::postEvent(), cl_moveit2z::ClMoveit2z::postEventMotionExecutionFailed(), postIncorrectInitialStateEvent, postJointDiscontinuityEvent, and postMotionExecutionFailureEvents.

Here is the call graph for this function:

◆ onOrthogonalAllocation() [2/2]

template<typename TOrthogonal , typename TSourceObject >
void cl_moveit2z::CbMoveEndEffectorTrajectory::onOrthogonalAllocation ( )
inline

Definition at line 69 of file cb_move_end_effector_trajectory.hpp.

70 {
71 this->initializeROS();
72
74
75 postJointDiscontinuityEvent = [this](auto traj)
76 {
77 auto ev = new EvJointDiscontinuity<TSourceObject, TOrthogonal>();
78 ev->trajectory = traj;
79 this->postEvent(ev);
80 };
81
82 postIncorrectInitialStateEvent = [this](auto traj)
83 {
84 auto ev = new EvIncorrectInitialPosition<TSourceObject, TOrthogonal>();
85 ev->trajectory = traj;
86 this->postEvent(ev);
87 };
88
90 {
91 RCLCPP_INFO_STREAM(getLogger(), "[" << this->getName() << "] motion execution failed");
94 };
95 }

References smacc2::ISmaccClientBehavior::getLogger(), smacc2::ISmaccClientBehavior::getName(), initializeROS(), movegroupClient_, smacc2::SmaccAsyncClientBehavior::onOrthogonalAllocation(), smacc2::ISmaccClientBehavior::postEvent(), cl_moveit2z::ClMoveit2z::postEventMotionExecutionFailed(), postIncorrectInitialStateEvent, postJointDiscontinuityEvent, and postMotionExecutionFailureEvents.

Here is the call graph for this function:

◆ update()

void cl_moveit2z::CbMoveEndEffectorTrajectory::update ( )
overridevirtual

Implements smacc2::ISmaccUpdatable.

Definition at line 359 of file cb_move_end_effector_trajectory.cpp.

360{
362 {
363 std::lock_guard<std::mutex> guard(m_mutex_);
365 }
366}

Member Data Documentation

◆ allowInitialTrajectoryStateJointDiscontinuity_

std::optional< bool > cl_moveit2z::CbMoveEndEffectorTrajectory::allowInitialTrajectoryStateJointDiscontinuity_

Definition at line 68 of file cb_move_end_effector_trajectory.hpp.

Referenced by computeJointSpaceTrajectory().

◆ autocleanmarkers

bool cl_moveit2z::CbMoveEndEffectorTrajectory::autocleanmarkers = false
private

Definition at line 684 of file cb_move_end_effector_trajectory.hpp.

Referenced by onExit().

◆ beahiorMarkers_

visualization_msgs::msg::MarkerArray cl_moveit2z::CbMoveEndEffectorTrajectory::beahiorMarkers_
protected

◆ endEffectorTrajectory_

std::vector< geometry_msgs::msg::PoseStamped > cl_moveit2z::CbMoveEndEffectorTrajectory::endEffectorTrajectory_
protected

◆ group_

std::optional< std::string > cl_moveit2z::CbMoveEndEffectorTrajectory::group_

Definition at line 64 of file cb_move_end_effector_trajectory.hpp.

◆ iksrv_

rclcpp::Client< moveit_msgs::srv::GetPositionIK >::SharedPtr cl_moveit2z::CbMoveEndEffectorTrajectory::iksrv_
private

◆ m_mutex_

std::mutex cl_moveit2z::CbMoveEndEffectorTrajectory::m_mutex_
private

Definition at line 677 of file cb_move_end_effector_trajectory.hpp.

Referenced by onExit().

◆ markersInitialized_

std::atomic<bool> cl_moveit2z::CbMoveEndEffectorTrajectory::markersInitialized_
private

Definition at line 128 of file cb_move_end_effector_trajectory.hpp.

◆ markersPub_

rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr cl_moveit2z::CbMoveEndEffectorTrajectory::markersPub_
private

Definition at line 673 of file cb_move_end_effector_trajectory.hpp.

Referenced by initializeROS(), and onExit().

◆ movegroupClient_

◆ postIncorrectInitialStateEvent

std::function< void(moveit_msgs::msg::RobotTrajectory &)> cl_moveit2z::CbMoveEndEffectorTrajectory::postIncorrectInitialStateEvent
private

Definition at line 680 of file cb_move_end_effector_trajectory.hpp.

Referenced by onEntry(), and onOrthogonalAllocation().

◆ postJointDiscontinuityEvent

std::function< void(moveit_msgs::msg::RobotTrajectory &)> cl_moveit2z::CbMoveEndEffectorTrajectory::postJointDiscontinuityEvent
private

Definition at line 679 of file cb_move_end_effector_trajectory.hpp.

Referenced by onEntry(), and onOrthogonalAllocation().

◆ postMotionExecutionFailureEvents

std::function< void()> cl_moveit2z::CbMoveEndEffectorTrajectory::postMotionExecutionFailureEvents
private

◆ tipLink_


The documentation for this class was generated from the following files: