converters.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2023 RaccoonLab.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, version 3.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Author: Dmitry Ponomarev <ponomarevda96@gmail.com>
17  */
18 
19 #include "converters.hpp"
20 #include <algorithm>
21 #include <chrono>
22 
23 float clamp_float(float value, float min, float max) {
24  if (value < min) {
25  value = min;
26  } else if (value > max) {
27  value = max;
28  }
29 
30  return value;
31 }
32 
37  if (uavcan_msg.commands.size() <= 0 || uavcan_msg.commands.size() > 15) {
38  return;
39  }
40 
41  sensor_msgs::Joy ros_msg;
42  ros_msg.header.stamp = ros::Time::now();
43  for (auto command : uavcan_msg.commands) {
44  ros_msg.axes.push_back(clamp_float(command.command_value, -1.0, +1.0));
45  }
46  ros_pub_.publish(ros_msg);
47 }
48 
50  if (uavcan_msg.cmd.size() <= 0 || uavcan_msg.cmd.size() > 20) {
51  return;
52  }
53 
54  sensor_msgs::Joy ros_msg;
55  ros_msg.header.stamp = ros::Time::now();
56  for (auto cmd : uavcan_msg.cmd) {
57  ros_msg.axes.push_back(cmd >= 0 ? (cmd / 8091.0) : (cmd / 8092.0));
58  }
59  ros_pub_.publish(ros_msg);
60 }
61 
62 
64  ros_msg_.header.stamp = ros::Time::now();
65 
66  ros_msg_.orientation.x = uavcan_msg.orientation_xyzw[0];
67  ros_msg_.orientation.y = uavcan_msg.orientation_xyzw[1];
68  ros_msg_.orientation.z = uavcan_msg.orientation_xyzw[2];
69  ros_msg_.orientation.w = uavcan_msg.orientation_xyzw[3];
70 
71  ros_msg_.angular_velocity.x = uavcan_msg.angular_velocity[0];
72  ros_msg_.angular_velocity.y = uavcan_msg.angular_velocity[1];
73  ros_msg_.angular_velocity.z = uavcan_msg.angular_velocity[2];
74 
75  ros_msg_.linear_acceleration.x = uavcan_msg.linear_acceleration[0];
76  ros_msg_.linear_acceleration.y = uavcan_msg.linear_acceleration[1];
77  ros_msg_.linear_acceleration.z = uavcan_msg.linear_acceleration[2];
78 
80 }
81 
82 
84  constexpr const uint8_t STATUS_FULLY_ARMED = 255;
85  ros_msg_.data = (uavcan_msg.status == STATUS_FULLY_ARMED);
87 }
88 
89 
91  ros_msg_.header.frame_id = std::to_string(uavcan_msg.circuit_id);
92  ros_msg_.voltage = uavcan_msg.voltage;
93  ros_msg_.current = uavcan_msg.current;
95 }
96 
97 
99  ros_msg_.temperature = uavcan_msg.temperature;
100  ros_msg_.voltage = uavcan_msg.voltage;
101  ros_msg_.current = uavcan_msg.current;
102  ros_msg_.totalcurrent = 0;
103  ros_msg_.rpm = uavcan_msg.rpm;
104  ros_msg_.count = uavcan_msg.esc_index;
106 }
107 
108 
109 void BaroStaticPressureRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
110  out_uavcan_msg_.static_pressure = in_ros_msg->data;
111  out_uavcan_msg_.static_pressure_variance = 1;
112  broadcast();
113 }
114 
115 
116 void BaroStaticTemperatureRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
117  out_uavcan_msg_.static_temperature = in_ros_msg->data;
118  out_uavcan_msg_.static_temperature_variance = 1;
119  broadcast();
120 }
121 
122 
123 void DiffPressureRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
124  out_uavcan_msg_.static_air_temperature = _temperature.out_uavcan_msg_.static_temperature;
125  out_uavcan_msg_.static_pressure = _pressure.out_uavcan_msg_.static_pressure;
126  out_uavcan_msg_.differential_pressure = in_ros_msg->data;
127  broadcast();
128 }
129 
130 // Unix time (used by std::chrono) started at 00:00 UTC on January 1, 1970
132  auto now = std::chrono::system_clock::now();
133  auto duration_since_epoch = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch());
134  return duration_since_epoch.count();
135 }
136 
137 void GpsRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
138  out_uavcan_msg_.gnss_timestamp.usec = simulate_gnss_utc_timestamp_usec();
139  out_uavcan_msg_.gnss_time_standard = 2; // 2 stands for UTC
140 
141  out_uavcan_msg_.latitude_deg_1e8 = in_ros_msg->latitude * 1e8;
142  out_uavcan_msg_.longitude_deg_1e8 = in_ros_msg->longitude * 1e8;
143  out_uavcan_msg_.height_ellipsoid_mm = in_ros_msg->altitude * 1e3;
144  out_uavcan_msg_.height_msl_mm = in_ros_msg->altitude * 1e3;
145  broadcast();
146 }
147 
148 void GpsRosToUavcan::ros_velocity_callback(geometry_msgs::Twist::Ptr in_ros_msg) {
149  out_uavcan_msg_.ned_velocity[0] = in_ros_msg->linear.x;
150  out_uavcan_msg_.ned_velocity[1] = in_ros_msg->linear.y;
151  out_uavcan_msg_.ned_velocity[2] = in_ros_msg->linear.z;
152 }
153 
154 
155 void ImuRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
156  out_uavcan_msg_.rate_gyro_latest[0] = in_ros_msg->angular_velocity.x;
157  out_uavcan_msg_.rate_gyro_latest[1] = in_ros_msg->angular_velocity.y;
158  out_uavcan_msg_.rate_gyro_latest[2] = in_ros_msg->angular_velocity.z;
159 
160  out_uavcan_msg_.accelerometer_latest[0] = in_ros_msg->linear_acceleration.x;
161  out_uavcan_msg_.accelerometer_latest[1] = in_ros_msg->linear_acceleration.y;
162  out_uavcan_msg_.accelerometer_latest[2] = in_ros_msg->linear_acceleration.z;
163 
164  broadcast();
165 }
166 
167 
168 void MagnetometerRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
169  out_uavcan_msg_.magnetic_field_ga[0] = in_ros_msg->magnetic_field.x;
170  out_uavcan_msg_.magnetic_field_ga[1] = in_ros_msg->magnetic_field.y;
171  out_uavcan_msg_.magnetic_field_ga[2] = in_ros_msg->magnetic_field.z;
172  broadcast();
173 }
174 
175 void EscStatusRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
176  out_uavcan_msg_.error_count = 0;
177  out_uavcan_msg_.voltage = in_ros_msg->voltage;
178  out_uavcan_msg_.current = in_ros_msg->current;
179  out_uavcan_msg_.temperature = in_ros_msg->temperature;
180  out_uavcan_msg_.rpm = in_ros_msg->rpm;
181  out_uavcan_msg_.power_rating_pct = 0;
182  out_uavcan_msg_.esc_index = in_ros_msg->count;
183  broadcast();
184 }
185 
186 void IceReciprocatingStatusRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
187  out_uavcan_msg_.engine_speed_rpm = in_ros_msg->rpm;
188  broadcast();
189 }
190 
192  out_uavcan_msg_.state = in_ros_msg.data;
193 }
194 
195 
196 void IceFuelTankStatusRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
197  out_uavcan_msg_.available_fuel_volume_percent = in_ros_msg->data;
198  broadcast();
199 }
200 
201 void BatteryInfoRosToUavcan::ros_callback(IN_ROS_MSG_PTR in_ros_msg) {
203  out_uavcan_msg_.voltage = in_ros_msg->voltage;
204  out_uavcan_msg_.current = in_ros_msg->current;
205  out_uavcan_msg_.full_charge_capacity_wh = in_ros_msg->design_capacity;
206  out_uavcan_msg_.state_of_charge_pct = in_ros_msg->percentage * 100;
207  out_uavcan_msg_.status_flags = 1;
208  out_uavcan_msg_.model_instance_id = 1;
209  out_uavcan_msg_.temperature = 300;
210 
212  out_uavcan_msg_.remaining_capacity_wh = in_ros_msg->capacity;
213  out_uavcan_msg_.average_power_10sec = 0;
214  out_uavcan_msg_.hours_to_full_charge = 0;
215  out_uavcan_msg_.state_of_health_pct = 127;
216  out_uavcan_msg_.state_of_charge_pct_stdev = 0;
217  out_uavcan_msg_.battery_id = 0;
218  out_uavcan_msg_.model_name = "simulated_battery";
219 
220  broadcast();
221 }
222 
223 std::unique_ptr<Converter> instantiate_converter(std::string converter_name,
224  ros::NodeHandle& ros_node,
225  UavcanNode& uavcan_node,
226  const char* ros_topic) {
227  std::unique_ptr<Converter> converter(nullptr);
228  if (converter_name.compare("RawCommandUavcanToRos") == 0) {
229  converter = std::unique_ptr<Converter>(new RawCommandUavcanToRos(ros_node, uavcan_node, ros_topic));
230  } else if (converter_name.compare("ArrayCommandUavcanToRos") == 0) {
231  converter = std::unique_ptr<Converter>(new ArrayCommandUavcanToRos(ros_node, uavcan_node, ros_topic));
232  } else if (converter_name.compare("AhrsSolutionUavcanToRos") == 0) {
233  converter = std::unique_ptr<Converter>(new AhrsSolutionUavcanToRos(ros_node, uavcan_node, ros_topic));
234  } else if (converter_name.compare("ArmUavcanToRos") == 0) {
235  converter = std::unique_ptr<Converter>(new ArmUavcanToRos(ros_node, uavcan_node, ros_topic));
236  } else if (converter_name.compare("CircuitStatusUavcanToRos") == 0) {
237  converter = std::unique_ptr<Converter>(new CircuitStatusUavcanToRos(ros_node, uavcan_node, ros_topic));
238  } else if (converter_name.compare("EscStatusUavcanToRos") == 0) {
239  converter = std::unique_ptr<Converter>(new EscStatusUavcanToRos(ros_node, uavcan_node, ros_topic));
240  } else if (converter_name.compare("BaroStaticPressureRosToUavcan") == 0) {
241  converter = std::unique_ptr<Converter>(new BaroStaticPressureRosToUavcan(ros_node, uavcan_node, ros_topic));
242  } else if (converter_name.compare("BaroStaticTemperatureRosToUavcan") == 0) {
243  converter = std::unique_ptr<Converter>(new BaroStaticTemperatureRosToUavcan(ros_node, uavcan_node, ros_topic));
244  } else if (converter_name.compare("DiffPressureRosToUavcan") == 0) {
245  converter = std::unique_ptr<Converter>(new DiffPressureRosToUavcan(ros_node, uavcan_node, ros_topic));
246  } else if (converter_name.compare("GpsRosToUavcan") == 0) {
247  converter = std::unique_ptr<Converter>(new GpsRosToUavcan(ros_node, uavcan_node, ros_topic));
248  } else if (converter_name.compare("ImuRosToUavcan") == 0) {
249  converter = std::unique_ptr<Converter>(new ImuRosToUavcan(ros_node, uavcan_node, ros_topic));
250  } else if (converter_name.compare("MagnetometerRosToUavcan") == 0) {
251  converter = std::unique_ptr<Converter>(new MagnetometerRosToUavcan(ros_node, uavcan_node, ros_topic));
252  } else if (converter_name.compare("EscStatusRosToUavcan") == 0) {
253  converter = std::unique_ptr<Converter>(new EscStatusRosToUavcan(ros_node, uavcan_node, ros_topic));
254  } else if (converter_name.compare("IceReciprocatingStatusRosToUavcan") == 0) {
255  converter = std::unique_ptr<Converter>(new IceReciprocatingStatusRosToUavcan(ros_node, uavcan_node, ros_topic));
256  } else if (converter_name.compare("IceFuelTankStatusRosToUavcan") == 0) {
257  converter = std::unique_ptr<Converter>(new IceFuelTankStatusRosToUavcan(ros_node, uavcan_node, ros_topic));
258  } else if (converter_name.compare("BatteryInfoRosToUavcan") == 0) {
259  converter = std::unique_ptr<Converter>(new BatteryInfoRosToUavcan(ros_node, uavcan_node, ros_topic));
260  } else {
261  std::cout << "\033[1;31m" << "ERROR: instantiate_converter, wrong converter name" << "\033[0m" << std::endl;
262  }
263 
264  return converter;
265 }
CircuitStatusUavcanToRos::uavcan_callback
void uavcan_callback(const uavcan::ReceivedDataStructure< IN_UAVCAN_MSG > &uavcan_msg) override
Definition: converters.cpp:90
uavcan::uint64_t
std::uint64_t uint64_t
Definition: std.hpp:27
ImuRosToUavcan
Definition: converters.hpp:228
IceReciprocatingStatusRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:186
UavcanToRosConverter< uavcan::equipment::ahrs::Solution, sensor_msgs::Imu >::ros_msg_
OUT_ROS_MSG ros_msg_
Definition: converters.hpp:70
converters.hpp
DiffPressureRosToUavcan::_pressure
BaroStaticPressureRosToUavcan _pressure
Definition: converters.hpp:198
IceFuelTankStatusRosToUavcan
Definition: converters.hpp:270
BaroStaticTemperatureRosToUavcan
Definition: converters.hpp:184
command
ROSLIB_DECL std::string command(const std::string &cmd)
BatteryInfoRosToUavcan
Definition: converters.hpp:280
GpsRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:137
RawCommandUavcanToRos
Definition: converters.hpp:112
MagnetometerRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:168
uavcan::ReceivedDataStructure
Definition: generic_subscriber.hpp:39
MagnetometerRosToUavcan
Definition: converters.hpp:238
AhrsSolutionUavcanToRos
Definition: converters.hpp:131
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
DiffPressureRosToUavcan
Definition: converters.hpp:194
CircuitStatusUavcanToRos
Definition: converters.hpp:163
ImuRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:155
ArrayCommandUavcanToRos::uavcan_callback
void uavcan_callback(const uavcan::ReceivedDataStructure< IN_UAVCAN_MSG > &uavcan_msg) override
Definition: converters.cpp:36
RosToUavcanConverter< std_msgs::Float32, uavcan::equipment::air_data::StaticPressure >::broadcast
void broadcast()
Definition: converters.hpp:100
RawCommandUavcanToRos::uavcan_callback
void uavcan_callback(const uavcan::ReceivedDataStructure< IN_UAVCAN_MSG > &uavcan_msg) override
Definition: converters.cpp:49
EscStatusUavcanToRos::uavcan_callback
void uavcan_callback(const uavcan::ReceivedDataStructure< IN_UAVCAN_MSG > &uavcan_msg) override
Definition: converters.cpp:98
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
EscStatusRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:175
uavcan::max
const UAVCAN_EXPORT T & max(const T &a, const T &b)
Definition: templates.hpp:291
AhrsSolutionUavcanToRos::uavcan_callback
void uavcan_callback(const uavcan::ReceivedDataStructure< IN_UAVCAN_MSG > &uavcan_msg) override
Definition: converters.cpp:63
uavcan::min
const UAVCAN_EXPORT T & min(const T &a, const T &b)
Definition: templates.hpp:281
BaroStaticPressureRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:109
UavcanToRosConverter< uavcan::equipment::actuator::ArrayCommand, sensor_msgs::Joy >::ros_pub_
ros::Publisher ros_pub_
Definition: converters.hpp:68
IceFuelTankStatusRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:196
BatteryInfoRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:201
ArmUavcanToRos
Definition: converters.hpp:141
ArmUavcanToRos::uavcan_callback
void uavcan_callback(const uavcan::ReceivedDataStructure< IN_UAVCAN_MSG > &uavcan_msg) override
Definition: converters.cpp:83
EscStatusUavcanToRos
Definition: converters.hpp:152
IceReciprocatingStatusRosToUavcan
Definition: converters.hpp:257
EscStatusRosToUavcan
Definition: converters.hpp:247
GpsRosToUavcan::ros_velocity_callback
void ros_velocity_callback(geometry_msgs::Twist::Ptr in_ros_msg)
Definition: converters.cpp:148
GpsRosToUavcan
Definition: converters.hpp:211
BaroStaticTemperatureRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:116
simulate_gnss_utc_timestamp_usec
uint64_t simulate_gnss_utc_timestamp_usec()
Definition: converters.cpp:131
DiffPressureRosToUavcan::ros_callback
void ros_callback(IN_ROS_MSG_PTR in_ros_msg) override
Definition: converters.cpp:123
clamp_float
float clamp_float(float value, float min, float max)
Definition: converters.cpp:23
DiffPressureRosToUavcan::_temperature
BaroStaticTemperatureRosToUavcan _temperature
Definition: converters.hpp:199
IceReciprocatingStatusRosToUavcan::ros_status_callback
void ros_status_callback(std_msgs::UInt8 in_ros_msg)
Definition: converters.cpp:191
RosToUavcanConverter< std_msgs::Float32, uavcan::equipment::air_data::StaticPressure >::out_uavcan_msg_
OUT_UAVCAN_MSG out_uavcan_msg_
Definition: converters.hpp:84
instantiate_converter
std::unique_ptr< Converter > instantiate_converter(std::string converter_name, ros::NodeHandle &ros_node, UavcanNode &uavcan_node, const char *ros_topic)
Definition: converters.cpp:223
uavcan::Node
Definition: node.hpp:38
BaroStaticPressureRosToUavcan
Definition: converters.hpp:174
ros::NodeHandle
ArrayCommandUavcanToRos
Definition: converters.hpp:121
ros::Time::now
static Time now()


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02