89 const double RADS_PER_SAMPLE = 0.02;
90 const double METERS_PER_SAMPLE = 0.01;
92 int totalSamplesCount =
93 std::max(totallineardist / METERS_PER_SAMPLE, totalangulardist / RADS_PER_SAMPLE);
95 double linearSecondsPerSample;
96 double angularSecondsPerSamples;
97 double secondsPerSample;
101 linearSecondsPerSample = METERS_PER_SAMPLE / (*linearSpeed_m_s_);
105 linearSecondsPerSample = std::numeric_limits<double>::max();
110 angularSecondsPerSamples = RADS_PER_SAMPLE / (*angularSpeed_rad_s_);
114 angularSecondsPerSamples = std::numeric_limits<double>::max();
119 secondsPerSample = 0.5;
123 secondsPerSample = std::min(linearSecondsPerSample, angularSecondsPerSamples);
126 double currentAngle = initialAngle;
128 double angleStep =
deltaRadians_ / (double)totalSamplesCount;
130 tf2::Transform tfBasePose;
135 "[" <<
getName() <<
"] generated trajectory, total samples: " << totalSamplesCount);
136 for (
int i = 0; i < totalSamplesCount; i++)
139 double y = radius * cos(currentAngle);
140 double z = radius * sin(currentAngle);
142 geometry_msgs::msg::Pose relativeCurrentPose;
145 relativeCurrentPose.position.y = y;
146 relativeCurrentPose.position.z = z;
148 tf2::Quaternion localquat;
149 localquat.setEuler(currentAngle, 0, 0);
153 relativeCurrentPose.orientation.w = 1;
155 tf2::Transform tfRelativeCurrentPose;
156 tf2::fromMsg(relativeCurrentPose, tfRelativeCurrentPose);
158 tf2::Transform tfGlobalPose = tfRelativeCurrentPose * tfBasePose;
160 tfGlobalPose.setRotation(tfGlobalPose.getRotation() * localquat);
162 geometry_msgs::msg::PoseStamped globalPose;
163 tf2::toMsg(tfGlobalPose, globalPose.pose);
166 rclcpp::Duration::from_seconds(i * secondsPerSample);
169 "[" <<
getName() <<
"]" << rclcpp::Time(globalPose.header.stamp).nanoseconds());
172 currentAngle += angleStep;
180 tf2::Transform localdirection;
181 localdirection.setIdentity();
182 localdirection.setOrigin(tf2::Vector3(0.12, 0, 0));
185 visualization_msgs::msg::Marker marker;
186 marker.header.frame_id = frameid;
187 marker.header.stamp =
getNode()->now();
188 marker.ns =
"trajectory";
190 marker.type = visualization_msgs::msg::Marker::ARROW;
191 marker.action = visualization_msgs::msg::Marker::ADD;
192 marker.scale.x = 0.01;
193 marker.scale.y = 0.02;
194 marker.scale.z = 0.02;
195 marker.color.a = 1.0;
196 marker.color.r = 0.0;
198 marker.color.b = 1.0;
200 geometry_msgs::msg::Point start, end;
205 tf2::Transform basetransform;
207 tf2::Transform endarrow = localdirection * basetransform;
209 end.x = endarrow.getOrigin().x();
210 end.y = endarrow.getOrigin().y();
211 end.z = endarrow.getOrigin().z();
213 marker.pose.orientation.w = 1;
214 marker.points.push_back(start);
215 marker.points.push_back(end);
233 tf2::Stamped<tf2::Transform> endEffectorInPivotFrame;
246 if (tfListener !=
nullptr)
254 tf2::fromMsg(transformOpt.value(), endEffectorInPivotFrame);
269 <<
"] CpTfListener component not available, using legacy TF2 (consider "
270 "adding CpTfListener component)");
271 tf2_ros::Buffer tfBuffer(
getNode()->get_clock());
272 tf2_ros::TransformListener tfListenerLegacy(tfBuffer);
275 tfBuffer.lookupTransform(
277 endEffectorInPivotFrame);
280 catch (
const std::exception & e)
285 <<
"] Exception in computeCurrentEndEffectorPoseRelativeToPivot: " << e.what());
296 tf2::Transform pivotTransform;
298 tf2::Transform invertedNewReferenceFrame = pivotTransform.inverse();
300 tf2::Transform currentPoseRelativeToPivot = invertedNewReferenceFrame * endEffectorInPivotFrame;
302 geometry_msgs::msg::Pose finalEndEffectorRelativePose;
303 tf2::toMsg(currentPoseRelativeToPivot, finalEndEffectorRelativePose);