SMACC2
Loading...
Searching...
No Matches
cl_moveit2z::CpJointSpaceTrajectoryPlanner Class Reference

Component for joint space trajectory generation from Cartesian waypoints. More...

#include <cp_joint_space_trajectory_planner.hpp>

Inheritance diagram for cl_moveit2z::CpJointSpaceTrajectoryPlanner:
Inheritance graph
Collaboration diagram for cl_moveit2z::CpJointSpaceTrajectoryPlanner:
Collaboration graph

Public Member Functions

 CpJointSpaceTrajectoryPlanner ()=default
 
virtual ~CpJointSpaceTrajectoryPlanner ()=default
 
void onInitialize () override
 Initialize the component and create IK service client.
 
JointTrajectoryResult planFromWaypoints (const std::vector< geometry_msgs::msg::PoseStamped > &waypoints, const JointTrajectoryOptions &options={})
 Compute joint space trajectory from Cartesian waypoints.
 
- Public Member Functions inherited from smacc2::ISmaccComponent
 ISmaccComponent ()
 
virtual ~ISmaccComponent ()
 
virtual std::string getName () const
 

Private Attributes

ClMoveit2zmoveit2zClient_ = nullptr
 
rclcpp::Client< moveit_msgs::srv::GetPositionIK >::SharedPtr ikClient_
 

Additional Inherited Members

- Protected Member Functions inherited from smacc2::ISmaccComponent
template<typename TOrthogonal , typename TClient >
void onComponentInitialization ()
 
template<typename EventType >
void postEvent (const EventType &ev)
 
template<typename EventType >
void postEvent ()
 
template<typename TOrthogonal , typename TSourceObject >
void onOrthogonalAllocation ()
 
template<typename TOrthogonal , typename TSourceObject >
void onStateOrthogonalAllocation ()
 
template<typename TComponent >
void requiresComponent (TComponent *&requiredComponentStorage, bool throwExceptionIfNotExist)
 
template<typename TComponent >
void requiresComponent (std::string name, TComponent *&requiredComponentStorage, bool throwExceptionIfNotExist)
 
template<typename TComponent >
void requiresComponent (TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
template<typename TComponent >
void requiresComponent (std::string name, TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
 
template<typename TClient >
void requiresClient (TClient *&requiredClientStorage)
 
template<typename SmaccComponentType , typename TOrthogonal , typename TClient , typename... TArgs>
SmaccComponentType * createSiblingComponent (TArgs... targs)
 
template<typename SmaccComponentType , typename TOrthogonal , typename TClient , typename... TArgs>
SmaccComponentType * createSiblingNamedComponent (std::string name, TArgs... targs)
 
rclcpp::Node::SharedPtr getNode ()
 
rclcpp::Logger getLogger () const
 
ISmaccStateMachinegetStateMachine ()
 
- Protected Attributes inherited from smacc2::ISmaccComponent
ISmaccStateMachinestateMachine_
 
ISmaccClientowner_
 

Detailed Description

Component for joint space trajectory generation from Cartesian waypoints.

This component centralizes IK-based trajectory generation:

  • Computes IK solutions for Cartesian waypoint sequences
  • Validates trajectory continuity
  • Detects and reports joint discontinuities
  • Handles initial state validation

Pattern: Trajectory planner with IK service integration

Definition at line 94 of file cp_joint_space_trajectory_planner.hpp.

Constructor & Destructor Documentation

◆ CpJointSpaceTrajectoryPlanner()

cl_moveit2z::CpJointSpaceTrajectoryPlanner::CpJointSpaceTrajectoryPlanner ( )
default

◆ ~CpJointSpaceTrajectoryPlanner()

virtual cl_moveit2z::CpJointSpaceTrajectoryPlanner::~CpJointSpaceTrajectoryPlanner ( )
virtualdefault

Member Function Documentation

◆ onInitialize()

void cl_moveit2z::CpJointSpaceTrajectoryPlanner::onInitialize ( )
inlineoverridevirtual

Initialize the component and create IK service client.

Reimplemented from smacc2::ISmaccComponent.

Definition at line 103 of file cp_joint_space_trajectory_planner.hpp.

104 {
106
107 // Create IK service client
108 ikClient_ = getNode()->create_client<moveit_msgs::srv::GetPositionIK>("/compute_ik");
109
110 RCLCPP_INFO(getLogger(), "[CpJointSpaceTrajectoryPlanner] Component initialized");
111 }
rclcpp::Client< moveit_msgs::srv::GetPositionIK >::SharedPtr ikClient_
void requiresClient(TClient *&requiredClientStorage)
rclcpp::Logger getLogger() const
rclcpp::Node::SharedPtr getNode()

References smacc2::ISmaccComponent::getLogger(), smacc2::ISmaccComponent::getNode(), ikClient_, moveit2zClient_, and smacc2::ISmaccComponent::requiresClient().

Here is the call graph for this function:

◆ planFromWaypoints()

JointTrajectoryResult cl_moveit2z::CpJointSpaceTrajectoryPlanner::planFromWaypoints ( const std::vector< geometry_msgs::msg::PoseStamped > & waypoints,
const JointTrajectoryOptions & options = {} )
inline

Compute joint space trajectory from Cartesian waypoints.

Parameters
waypointsVector of Cartesian poses to follow
optionsPlanning configuration options
Returns
JointTrajectoryResult with success status and computed trajectory

Definition at line 120 of file cp_joint_space_trajectory_planner.hpp.

122 {})
123 {
124 JointTrajectoryResult result;
125
126 if (waypoints.empty())
127 {
129 result.errorMessage = "No waypoints provided";
130 RCLCPP_WARN(getLogger(), "[CpJointSpaceTrajectoryPlanner] %s", result.errorMessage.c_str());
131 return result;
132 }
133
134 if (!moveit2zClient_)
135 {
136 result.errorMessage = "ClMoveit2z client not available";
137 RCLCPP_ERROR(getLogger(), "[CpJointSpaceTrajectoryPlanner] %s", result.errorMessage.c_str());
138 return result;
139 }
140
141 try
142 {
143 auto & moveGroup = moveit2zClient_->moveGroupClientInterface;
144
145 // Get current robot state
146 RCLCPP_INFO(
147 getLogger(),
148 "[CpJointSpaceTrajectoryPlanner] Getting current state for trajectory planning");
149 auto currentState = moveGroup->getCurrentState(100);
150 if (!currentState)
151 {
152 result.errorMessage = "Failed to get current robot state";
153 RCLCPP_ERROR(
154 getLogger(), "[CpJointSpaceTrajectoryPlanner] %s", result.errorMessage.c_str());
155 return result;
156 }
157
158 // Determine group name and tip link
159 std::string groupName = options.groupName.value_or(moveGroup->getName());
160 std::string tipLink = options.tipLink.value_or(moveGroup->getEndEffectorLink());
161
162 RCLCPP_INFO(
163 getLogger(), "[CpJointSpaceTrajectoryPlanner] Planning for group '%s' with tip link '%s'",
164 groupName.c_str(), tipLink.c_str());
165
166 // Get joint names
167 auto jointNames = currentState->getJointModelGroup(groupName)->getActiveJointModelNames();
168
169 // Initialize trajectory with current state
170 std::vector<double> jointPositions;
171 currentState->copyJointGroupPositions(groupName, jointPositions);
172
173 std::vector<std::vector<double>> trajectory;
174 std::vector<rclcpp::Duration> trajectoryTimeStamps;
175
176 trajectory.push_back(jointPositions);
177 trajectoryTimeStamps.push_back(rclcpp::Duration(0s));
178
179 // Reference time for trajectory timestamps
180 auto & first = waypoints.front();
181 rclcpp::Time referenceTime(first.header.stamp);
182
183 // Compute IK for each waypoint
184 int ikAttemptsRemaining = options.ikAttempts;
185 for (size_t k = 0; k < waypoints.size(); k++)
186 {
187 auto & pose = waypoints[k];
188
189 // Create IK request
190 auto req = std::make_shared<moveit_msgs::srv::GetPositionIK::Request>();
191 req->ik_request.ik_link_name = tipLink;
192 req->ik_request.robot_state.joint_state.name = jointNames;
193 req->ik_request.robot_state.joint_state.position = jointPositions;
194 req->ik_request.group_name = groupName;
195 req->ik_request.avoid_collisions = options.avoidCollisions;
196 req->ik_request.pose_stamped = pose;
197
198 RCLCPP_DEBUG(
199 getLogger(), "[CpJointSpaceTrajectoryPlanner] Computing IK for waypoint %lu/%lu", k + 1,
200 waypoints.size());
201
202 // Call IK service
203 auto resFuture = ikClient_->async_send_request(req);
204 auto status = resFuture.wait_for(options.ikTimeout);
205
206 if (status != std::future_status::ready)
207 {
208 result.errorMessage = "IK service timeout at waypoint " + std::to_string(k);
209 RCLCPP_ERROR(
210 getLogger(), "[CpJointSpaceTrajectoryPlanner] %s", result.errorMessage.c_str());
212 return result;
213 }
214
215 auto res = resFuture.get();
216 auto & prevTrajPoint = trajectory.back();
217
218 // Extract joint positions from IK solution
219 for (size_t j = 0; j < res->solution.joint_state.position.size(); j++)
220 {
221 auto & jointName = res->solution.joint_state.name[j];
222 auto it = std::find(jointNames.begin(), jointNames.end(), jointName);
223 if (it != jointNames.end())
224 {
225 int index = std::distance(jointNames.begin(), it);
226 jointPositions[index] = res->solution.joint_state.position[j];
227 }
228 }
229
230 // Continuity check
231 bool shouldCheck = k > 0 || !options.allowInitialDiscontinuity;
232 int discontinuityJointIndex = -1;
233 double discontinuityDelta = -1;
234
235 if (shouldCheck)
236 {
237 for (size_t jointIndex = 0; jointIndex < jointPositions.size(); jointIndex++)
238 {
239 double deltaJoint = jointPositions[jointIndex] - prevTrajPoint[jointIndex];
240 if (fabs(deltaJoint) > options.maxJointDiscontinuity)
241 {
242 discontinuityDelta = deltaJoint;
243 discontinuityJointIndex = jointIndex;
244 break;
245 }
246 }
247 }
248
249 // Handle discontinuity
250 if (ikAttemptsRemaining > 0 && discontinuityJointIndex != -1)
251 {
252 // Retry IK
253 k--;
254 ikAttemptsRemaining--;
255 RCLCPP_WARN(
256 getLogger(),
257 "[CpJointSpaceTrajectoryPlanner] IK discontinuity detected, retrying (%d attempts "
258 "remaining)",
259 ikAttemptsRemaining);
260 continue;
261 }
262 else
263 {
264 // Record discontinuity or accept trajectory point
265 if (ikAttemptsRemaining == 0 && discontinuityJointIndex != -1)
266 {
267 result.discontinuityIndexes.push_back(k);
268
269 RCLCPP_ERROR(
270 getLogger(),
271 "[CpJointSpaceTrajectoryPlanner] Joint discontinuity at waypoint %lu: joint '%s' "
272 "delta=%.3f rad",
273 k, jointNames[discontinuityJointIndex].c_str(), discontinuityDelta);
274
275 if (k == 0)
276 {
277 RCLCPP_ERROR(
278 getLogger(),
279 "[CpJointSpaceTrajectoryPlanner] Initial posture discontinuity detected");
280 }
281 }
282
283 // Reset retry counter
284 ikAttemptsRemaining = options.ikAttempts;
285
286 // Add point to trajectory
287 trajectory.push_back(jointPositions);
288 rclcpp::Duration durationFromStart = rclcpp::Time(pose.header.stamp) - referenceTime;
289 trajectoryTimeStamps.push_back(durationFromStart);
290 }
291 }
292
293 // Build RobotTrajectory message
294 result.trajectory.joint_trajectory.joint_names = jointNames;
295
296 // Skip first point (current state) to avoid discontinuity in some behaviors
297 for (size_t i = 1; i < trajectory.size(); i++)
298 {
299 trajectory_msgs::msg::JointTrajectoryPoint jp;
300 jp.positions = trajectory[i];
301 jp.time_from_start = trajectoryTimeStamps[i];
302 result.trajectory.joint_trajectory.points.push_back(jp);
303 }
304
305 // Determine success
306 if (!result.discontinuityIndexes.empty())
307 {
308 if (result.discontinuityIndexes[0] == 0)
309 {
311 result.errorMessage = "Incorrect initial state";
312 }
313 else
314 {
316 result.errorMessage = "Joint trajectory discontinuity detected";
317 }
318 result.success = false;
319 RCLCPP_WARN(getLogger(), "[CpJointSpaceTrajectoryPlanner] %s", result.errorMessage.c_str());
320 }
321 else
322 {
323 result.success = true;
324 result.errorCode = JointTrajectoryErrorCode::SUCCESS;
325 RCLCPP_INFO(
326 getLogger(),
327 "[CpJointSpaceTrajectoryPlanner] Successfully computed trajectory with %lu points",
328 result.trajectory.joint_trajectory.points.size());
329 }
330 }
331 catch (const std::exception & e)
332 {
333 result.success = false;
334 result.errorMessage = std::string("Exception during trajectory planning: ") + e.what();
335 RCLCPP_ERROR(getLogger(), "[CpJointSpaceTrajectoryPlanner] %s", result.errorMessage.c_str());
336 }
337
338 return result;
339 }
std::shared_ptr< moveit::planning_interface::MoveGroupInterface > moveGroupClientInterface

Referenced by cl_moveit2z::CbMoveEndEffectorTrajectory::computeJointSpaceTrajectory().

Here is the caller graph for this function:

Member Data Documentation

◆ ikClient_

rclcpp::Client<moveit_msgs::srv::GetPositionIK>::SharedPtr cl_moveit2z::CpJointSpaceTrajectoryPlanner::ikClient_
private

Definition at line 343 of file cp_joint_space_trajectory_planner.hpp.

Referenced by onInitialize().

◆ moveit2zClient_

ClMoveit2z* cl_moveit2z::CpJointSpaceTrajectoryPlanner::moveit2zClient_ = nullptr
private

Definition at line 342 of file cp_joint_space_trajectory_planner.hpp.

Referenced by onInitialize().


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