SMACC2
Loading...
Searching...
No Matches
cp_vehicle_local_position.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
16
17namespace cl_px4_mr
18{
19
21
23
25{
26 auto node = this->getNode();
27 subscriber_ = node->create_subscription<px4_msgs::msg::VehicleLocalPosition>(
28 "/fmu/out/vehicle_local_position", rclcpp::SensorDataQoS(),
29 std::bind(&CpVehicleLocalPosition::onPositionMessage, this, std::placeholders::_1));
30 RCLCPP_INFO(getLogger(), "CpVehicleLocalPosition: subscribed to /fmu/out/vehicle_local_position");
31}
32
34 const px4_msgs::msg::VehicleLocalPosition::SharedPtr msg)
35{
36 bool resetDetected = false;
37
38 {
39 std::lock_guard<std::mutex> lock(mutex_);
40 x_ = msg->x;
41 y_ = msg->y;
42 z_ = msg->z;
43 heading_ = msg->heading;
44 valid_ = msg->xy_valid && msg->z_valid;
45 headingGoodForControl_ = msg->heading_good_for_control;
46 velocityValid_ = msg->v_xy_valid && msg->v_z_valid;
47
48 // global reference of the local frame
49 xyGlobal_ = msg->xy_global;
50 zGlobal_ = msg->z_global;
51 refAlt_ = msg->ref_alt;
52 if (msg->xy_global && (!projection_.isInitialized() || msg->ref_timestamp != refTimestamp_))
53 {
54 refLat_ = msg->ref_lat;
55 refLon_ = msg->ref_lon;
56 refTimestamp_ = msg->ref_timestamp;
58 RCLCPP_INFO(
59 getLogger(),
60 "CpVehicleLocalPosition: global reference set - NED origin at lat=%.7f lon=%.7f "
61 "alt=%.1f m AMSL",
62 refLat_, refLon_, static_cast<double>(refAlt_));
63 }
64
65 // EKF origin resets
66 if (!firstMessage_)
67 {
68 if (msg->xy_reset_counter != xyResetCounter_)
69 {
70 RCLCPP_WARN(
71 getLogger(),
72 "CpVehicleLocalPosition: local XY reset #%u (delta_xy=[%.2f, %.2f]); running paths "
73 "are NOT re-projected",
74 msg->xy_reset_counter, static_cast<double>(msg->delta_xy[0]),
75 static_cast<double>(msg->delta_xy[1]));
76 resetDetected = true;
77 }
78 if (msg->z_reset_counter != zResetCounter_)
79 {
80 RCLCPP_WARN(
81 getLogger(),
82 "CpVehicleLocalPosition: local Z reset #%u (delta_z=%.2f); running paths are NOT "
83 "re-projected",
84 msg->z_reset_counter, static_cast<double>(msg->delta_z));
85 resetDetected = true;
86 }
87 }
88 xyResetCounter_ = msg->xy_reset_counter;
89 zResetCounter_ = msg->z_reset_counter;
90 firstMessage_ = false;
91 }
92
93 if (resetDetected)
94 {
96 }
98}
99
101{
102 std::lock_guard<std::mutex> lock(mutex_);
103 return x_;
104}
105
107{
108 std::lock_guard<std::mutex> lock(mutex_);
109 return y_;
110}
111
113{
114 std::lock_guard<std::mutex> lock(mutex_);
115 return z_;
116}
117
119{
120 std::lock_guard<std::mutex> lock(mutex_);
121 return heading_;
122}
123
125{
126 std::lock_guard<std::mutex> lock(mutex_);
127 return valid_;
128}
129
131{
132 std::lock_guard<std::mutex> lock(mutex_);
134}
135
137{
138 std::lock_guard<std::mutex> lock(mutex_);
139 return velocityValid_;
140}
141
143{
144 std::lock_guard<std::mutex> lock(mutex_);
146}
147
149{
150 std::lock_guard<std::mutex> lock(mutex_);
151 return refLat_;
152}
153
155{
156 std::lock_guard<std::mutex> lock(mutex_);
157 return refLon_;
158}
159
161{
162 std::lock_guard<std::mutex> lock(mutex_);
163 return refAlt_;
164}
165
167{
168 std::lock_guard<std::mutex> lock(mutex_);
169 return refTimestamp_;
170}
171
173{
174 std::lock_guard<std::mutex> lock(mutex_);
175 return xyResetCounter_;
176}
177
179{
180 std::lock_guard<std::mutex> lock(mutex_);
181 return zResetCounter_;
182}
183
184bool CpVehicleLocalPosition::projectToNed(double lat, double lon, float & x, float & y) const
185{
186 std::lock_guard<std::mutex> lock(mutex_);
188 {
189 return false;
190 }
191 projection_.project(lat, lon, x, y);
192 return true;
193}
194
195bool CpVehicleLocalPosition::reprojectFromNed(float x, float y, double & lat, double & lon) const
196{
197 std::lock_guard<std::mutex> lock(mutex_);
199 {
200 return false;
201 }
202 projection_.reproject(x, y, lat, lon);
203 return true;
204}
205
206} // namespace cl_px4_mr
bool reprojectFromNed(float x, float y, double &lat, double &lon) const
smacc2::SmaccSignal< void()> onPositionReceived_
void onPositionMessage(const px4_msgs::msg::VehicleLocalPosition::SharedPtr msg)
smacc2::SmaccSignal< void()> onLocalPositionReset_
rclcpp::Subscription< px4_msgs::msg::VehicleLocalPosition >::SharedPtr subscriber_
bool projectToNed(double lat, double lon, float &x, float &y) const
void initReference(double lat0, double lon0, uint64_t timestamp=0)
Definition geo_utils.hpp:79
bool isInitialized() const
Definition geo_utils.hpp:89
void reproject(float x, float y, double &lat, double &lon) const
void project(double lat, double lon, float &x, float &y) const
Definition geo_utils.hpp:95
rclcpp::Logger getLogger() const
rclcpp::Node::SharedPtr getNode()