SMACC2
Loading...
Searching...
No Matches
cb_spiral_up.cpp
Go to the documentation of this file.
1// Copyright 2026 RobosoftAI 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
18
19namespace cl_px4_mr
20{
21
22CbSpiralUp::CbSpiralUp(SpiralUpParams params) : params_(params) {}
23
25{
26 const float dx = localPosition_->getX() - params_.centerX;
27 const float dy = localPosition_->getY() - params_.centerY;
28 startAngle_ = std::atan2(dy, dx);
33 lastUpdateTime_ = std::chrono::steady_clock::now();
34
35 RCLCPP_INFO(
36 getLogger(),
37 "CbSpiralUp: helix about NED (%.1f, %.1f), radius %.1f m, from %.1f m up %.1f m at %.1f m per "
38 "orbit (%.1f orbits), %.2f rad/s",
39 static_cast<double>(params_.centerX), static_cast<double>(params_.centerY),
40 static_cast<double>(params_.radiusM), static_cast<double>(startAltitude_),
41 static_cast<double>(params_.climbTotalM), static_cast<double>(params_.climbPerOrbitM),
42 static_cast<double>(params_.climbTotalM / params_.climbPerOrbitM),
43 static_cast<double>(params_.angularVelocityRadS));
44 command();
45}
46
48{
49 const float turned = currentAngle_ - startAngle_;
50 const float orbits = std::fabs(turned) / (2.0f * static_cast<float>(M_PI));
51 const float climb = std::min(orbits * params_.climbPerOrbitM, params_.climbTotalM);
52 const float x = params_.centerX + params_.radiusM * std::cos(currentAngle_);
53 const float y = params_.centerY + params_.radiusM * std::sin(currentAngle_);
54 const float z = -(startAltitude_ + climb); // NED: up is negative
55 const float yaw = currentAngle_ + static_cast<float>(M_PI); // nose toward the axis
57
58 const int orbit = static_cast<int>(orbits);
59 if (orbit != lastReportedOrbit_)
60 {
61 lastReportedOrbit_ = orbit;
62 RCLCPP_INFO(
63 getLogger(), "CbSpiralUp: orbit %d, commanding %.1f m up", orbit,
64 static_cast<double>(startAltitude_ + climb));
65 }
66}
67
69{
71
72 const auto now = std::chrono::steady_clock::now();
73 const double dt = std::chrono::duration<double>(now - lastUpdateTime_).count();
74 lastUpdateTime_ = now;
75 currentAngle_ += params_.angularVelocityRadS * static_cast<float>(dt);
76 command();
77
78 const float turned = std::fabs(currentAngle_ - startAngle_);
79 const float needed =
80 params_.climbTotalM / params_.climbPerOrbitM * 2.0f * static_cast<float>(M_PI);
81 if (turned >= needed)
82 {
83 RCLCPP_INFO(
84 getLogger(), "CbSpiralUp: %.1f m gained over %.1f orbits - posting success",
85 static_cast<double>(params_.climbTotalM), static_cast<double>(turned / (2.0f * M_PI)));
86 this->postPx4Success();
87 }
88}
89
90} // namespace cl_px4_mr
std::chrono::steady_clock::time_point lastUpdateTime_
void onEntry() override
CbSpiralUp(SpiralUpParams params={})
SpiralUpParams params_
void update() override
void setPositionNED(float x, float y, float z, float yaw=std::numeric_limits< float >::quiet_NaN())
virtual rclcpp::Logger getLogger() const