SMACC2
Loading...
Searching...
No Matches
cb_spiral_motion.cpp
Go to the documentation of this file.
1// Copyright 2025 Robosoft Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*****************************************************************************************************************
16 *
17 * Authors: Pablo Inigo Blasco, Brett Aldrich
18 *
19 ******************************************************************************************************************/
20
21#include <angles/angles.h>
23#include <geometry_msgs/msg/twist.hpp>
24#include <optional>
26
27namespace cl_nav2z
28{
29
30CbSpiralMotion::CbSpiralMotion(std::optional<CbSpiralMotionOptions> options)
31{
32 if (options)
33 {
34 options_ = *options;
35 }
36 else
37 {
38 // we use default options
40 }
41}
42
44{
45 auto linearVelocity = *(options_.linearVelocity);
46 auto maxLinearVelocity = *(options_.maxLinearVelocity);
47 auto initialAngularVelocity = *(options_.initialAngularVelocity);
48 auto spiralMotionDuration = *(options_.spiralMotionDuration);
49 auto finalRadius = *(options_.finalRadius);
50
51 float rate = 20.0f;
52 rclcpp::Rate r(rate);
53 cmdVelPub_ = getNode()->create_publisher<geometry_msgs::msg::Twist>("/cmd_vel", rclcpp::QoS(1));
54
55 rclcpp::Duration linearRamp = rclcpp::Duration::from_seconds(spiralMotionDuration.seconds());
56 float linearAceleration = (maxLinearVelocity - linearVelocity) / linearRamp.seconds();
57 float dt = 1.0f / rate;
58
59 // we know final radious and the constant linear velocity
60 float finalAngularVelocity = maxLinearVelocity / finalRadius;
61
62 float angularAcceleration =
63 (initialAngularVelocity - finalAngularVelocity) / spiralMotionDuration.seconds();
64
65 geometry_msgs::msg::Twist cmd_vel;
66
67 cmd_vel.linear.x = linearVelocity;
68 cmd_vel.angular.z = initialAngularVelocity;
69 auto start_time = getNode()->now();
70
71 RCLCPP_INFO_STREAM(
72 getLogger(), "[CbSpiralMotion]: initialAngularVelocity: "
73 << initialAngularVelocity << ", finalAngularVelocity: " << finalAngularVelocity
74 << ", angularAcceleration: " << angularAcceleration);
75 RCLCPP_INFO_STREAM(
76 getLogger(), "[CbSpiralMotion]: linearAceleration: "
77 << linearAceleration << ", maxLinearVelocity: " << maxLinearVelocity);
78
79 bool end_condition = false;
80
81 while (!end_condition)
82 {
83 auto current_time = getNode()->now() - start_time;
84
85 cmd_vel.linear.x += static_cast<double>(linearAceleration) * dt;
86 if (cmd_vel.linear.x > maxLinearVelocity)
87 {
88 cmd_vel.linear.x = maxLinearVelocity;
89 }
90
91 float elapsedTimeFactor = current_time.seconds() / spiralMotionDuration.seconds();
92 cmd_vel.angular.z = initialAngularVelocity * (1.0f - elapsedTimeFactor) +
93 finalAngularVelocity * elapsedTimeFactor;
94
95 RCLCPP_INFO(
96 getLogger(), "[CbSpiralMotion] cmd_vel.linear.x = %f, cmd_vel.angular.z = %f",
97 cmd_vel.linear.x, cmd_vel.angular.z);
98
99 cmdVelPub_->publish(cmd_vel);
100 r.sleep();
101
102 auto now = getNode()->now();
103
104 rclcpp::Duration elapsed = now - start_time;
105 RCLCPP_INFO_STREAM(
106 getLogger(), "[CbSpiralMotion] elapsed time: " << elapsed.seconds() << ", total duration: "
107 << spiralMotionDuration.seconds());
108 if (elapsed > spiralMotionDuration)
109 {
110 RCLCPP_INFO_STREAM(getLogger(), "[CbSpiralMotion] spiralMotionDuration reached");
111 end_condition = true;
112 }
113 }
114
115 // asynchronous client behaviors usually post a success event when they are done
116 // that is used in states to transition to the next state
117 this->postSuccessEvent();
118}
119
121
122} // namespace cl_nav2z
virtual rclcpp::Logger getLogger() const
virtual rclcpp::Node::SharedPtr getNode() const
std::optional< float > initialAngularVelocity
std::optional< float > linearVelocity
std::optional< rclcpp::Duration > spiralMotionDuration
std::optional< float > maxLinearVelocity
std::optional< float > finalRadius
CbSpiralMotionOptions options_
rclcpp::Publisher< geometry_msgs::msg::Twist >::SharedPtr cmdVelPub_
CbSpiralMotion(std::optional< CbSpiralMotionOptions > options=std::nullopt)