rm_control
Loading...
Searching...
No Matches
data.h
Go to the documentation of this file.
1/*******************************************************************************
2 * BSD 3-Clause License
3 *
4 * Copyright (c) 2021, Qiayuan Liao
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * * Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * * Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *******************************************************************************/
33
34//
35// Created by peter on 2021/7/17.
36//
37
38#pragma once
39
40#include <array>
41#include <vector>
42#include <ros/ros.h>
43#include <unistd.h>
44#include <serial/serial.h>
45#include <nav_msgs/Odometry.h>
46#include <sensor_msgs/JointState.h>
47#include <std_msgs/Float64.h>
48#include <std_msgs/Int8MultiArray.h>
49#include <tf2_ros/buffer.h>
50#include <tf2_ros/transform_listener.h>
51#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
52#include "std_msgs/UInt32.h"
53#include "rm_msgs/VisualizeStateData.h"
54
56
57#include <rm_msgs/ShootCmd.h>
58#include <rm_msgs/ShootState.h>
59#include <rm_msgs/DbusData.h>
60#include <rm_msgs/StateCmd.h>
61#include <rm_msgs/EventData.h>
62#include <rm_msgs/GimbalCmd.h>
63#include <rm_msgs/RobotHurt.h>
64#include <rm_msgs/ShootData.h>
65#include <rm_msgs/DartStatus.h>
66#include <rm_msgs/ChassisCmd.h>
67#include <rm_msgs/GameStatus.h>
68#include <rm_msgs/RfidStatus.h>
69#include <rm_msgs/EngineerUi.h>
70#include <rm_msgs/GameRobotHp.h>
71#include <rm_msgs/BalanceState.h>
72#include <rm_msgs/DartClientCmd.h>
73#include <rm_msgs/ActuatorState.h>
74#include <rm_msgs/MapSentryData.h>
75#include <rm_msgs/RadarMarkData.h>
76#include <rm_msgs/PowerHeatData.h>
77#include <rm_msgs/GimbalDesError.h>
78#include <rm_msgs/BulletAllowance.h>
79#include <rm_msgs/GameRobotStatus.h>
80#include <rm_msgs/ManualToReferee.h>
81#include <rm_msgs/ClientMapSendData.h>
82#include <rm_msgs/RobotsPositionData.h>
83#include <rm_msgs/DartInfo.h>
84#include <rm_msgs/StatusChangeRequest.h>
85#include <rm_msgs/ClientMapReceiveData.h>
86#include <rm_msgs/SupplyProjectileAction.h>
87#include <rm_msgs/IcraBuffDebuffZoneStatus.h>
88#include <rm_msgs/GameRobotPosData.h>
89#include "rm_msgs/SentryInfo.h"
90#include "rm_msgs/SentryCmd.h"
91#include "rm_msgs/RadarInfo.h"
92#include "rm_msgs/RadarCmd.h"
93#include "rm_msgs/Buff.h"
94#include "rm_msgs/TrackData.h"
95#include "rm_msgs/SentryAttackingTarget.h"
96#include "rm_msgs/RadarToSentry.h"
97#include <rm_msgs/PowerManagementSampleAndStatusData.h>
98#include <rm_msgs/PowerManagementSystemExceptionData.h>
99#include <rm_msgs/PowerManagementInitializationExceptionData.h>
100#include <rm_msgs/PowerManagementProcessStackOverflowData.h>
101#include <rm_msgs/PowerManagementUnknownExceptionData.h>
102
103namespace rm_referee
104{
106{
110 double cap_power;
111 bool is_online = false;
112};
113
114class Base
115{
116public:
117 static constexpr size_t kMaxSerialPorts = 2;
118
120 {
121 serial::Serial serial;
122 std::string device;
125 bool configured = false;
126 };
127
128 std::array<SerialPortState, kMaxSerialPorts> serial_ports_{};
131 ros::Duration reopen_interval_{ 1.0 };
132
133 int client_id_ = 0; // recipient's id
134 int robot_id_ = 0; // recent robot's id
136 std::string robot_color_;
138
139 void initSerial(ros::NodeHandle& nh)
140 {
141 std::vector<std::string> devices;
142 if (!nh.getParam("serial_ports", devices) || devices.empty())
143 devices = { "/dev/usbReferee" };
144 if (devices.size() > kMaxSerialPorts)
145 {
146 ROS_WARN("rm_referee serial_ports size %zu exceeds max %zu, truncating", devices.size(), kMaxSerialPorts);
147 devices.resize(kMaxSerialPorts);
148 }
150 for (const auto& device : devices)
151 {
152 if (device.empty())
153 continue;
154 auto& port = serial_ports_[serial_port_count_++];
155 port.device = device;
156 port.configured = true;
157 port.last_valid_frame_time = ros::Time();
158 port.next_open_attempt_time = ros::Time();
159 }
160 if (serial_port_count_ == 0)
161 {
162 auto& port = serial_ports_[0];
163 port.device = "/dev/usbReferee";
164 port.configured = true;
166 }
167 for (size_t i = 0; i < serial_port_count_; ++i)
168 ensurePortOpen(i, ros::Time::now());
169 }
170
171 bool ensurePortOpen(size_t index, const ros::Time& now)
172 {
173 if (index >= serial_port_count_)
174 return false;
175 auto& port = serial_ports_[index];
176 if (!port.configured)
177 return false;
178 if (port.serial.isOpen())
179 return true;
180 if (!port.next_open_attempt_time.isZero() && now < port.next_open_attempt_time)
181 return false;
182
183 serial::Timeout timeout = serial::Timeout::simpleTimeout(50);
184 port.serial.setPort(port.device);
185 port.serial.setBaudrate(115200);
186 port.serial.setTimeout(timeout);
187 try
188 {
189 port.serial.open();
190 port.next_open_attempt_time = ros::Time();
191 ROS_INFO_STREAM("Opened referee port: " << port.device);
192 return true;
193 }
194 catch (const std::exception& e)
195 {
196 port.next_open_attempt_time = now + reopen_interval_;
197 ROS_WARN_STREAM("Cannot open referee port " << port.device << ": " << e.what());
198 return false;
199 }
200 }
201
202 void handlePortIoFailure(size_t index, const ros::Time& now, const std::string& action, const std::exception& e)
203 {
204 if (index >= serial_port_count_)
205 return;
206 auto& port = serial_ports_[index];
207 if (port.serial.isOpen())
208 port.serial.close();
209 port.last_valid_frame_time = ros::Time();
210 if (active_port_index_ == static_cast<int>(index))
212 port.next_open_attempt_time = now + reopen_interval_;
213 ROS_WARN_STREAM("Referee port " << port.device << " " << action << " failed: " << e.what());
214 }
215
216 bool isPortFresh(size_t index, const ros::Time& now, const ros::Duration& freshness) const
217 {
218 if (index >= serial_port_count_)
219 return false;
220 const auto& port = serial_ports_[index];
221 return !port.last_valid_frame_time.isZero() && (now - port.last_valid_frame_time) <= freshness;
222 }
223
224 bool isActivePortFresh(const ros::Time& now, const ros::Duration& freshness) const
225 {
226 return active_port_index_ >= 0 && isPortFresh(static_cast<size_t>(active_port_index_), now, freshness);
227 }
228
229 bool shouldProcessPort(size_t index, const ros::Time& now, const ros::Duration& freshness) const
230 {
231 if (index >= serial_port_count_)
232 return false;
233 if (active_port_index_ < 0)
234 return true;
235 return static_cast<size_t>(active_port_index_) == index || !isActivePortFresh(now, freshness);
236 }
237
238 void activatePort(size_t index)
239 {
240 if (index >= serial_port_count_)
241 return;
242 if (active_port_index_ == static_cast<int>(index))
243 return;
244 const std::string from =
245 active_port_index_ >= 0 ? serial_ports_[static_cast<size_t>(active_port_index_)].device : std::string("<none>");
246 active_port_index_ = static_cast<int>(index);
247 ROS_INFO_STREAM("Switched active referee port from " << from << " to " << serial_ports_[index].device);
248 }
249
250 void markValidFrame(size_t index, const ros::Time& stamp, const ros::Duration& freshness)
251 {
252 if (index >= serial_port_count_)
253 return;
254 serial_ports_[index].last_valid_frame_time = stamp;
255 if (active_port_index_ < 0 || !isActivePortFresh(stamp, freshness) || active_port_index_ == static_cast<int>(index))
256 activatePort(index);
258 }
259
260 void refreshOnlineState(const ros::Time& now, const ros::Duration& freshness)
261 {
263 for (size_t i = 0; i < serial_port_count_; ++i)
264 {
265 if (isPortFresh(i, now, freshness))
266 {
268 break;
269 }
270 }
271 }
272
273 bool writeActive(const uint8_t* data, size_t data_len)
274 {
275 if (active_port_index_ < 0)
276 return false;
277 const size_t active_index = static_cast<size_t>(active_port_index_);
278 if (active_index >= serial_port_count_)
279 return false;
280 auto& port = serial_ports_[active_index];
281 if (!port.serial.isOpen())
282 return false;
283 port.serial.write(data, data_len);
284 return true;
285 }
286
287 // CRC check
288 uint8_t getCRC8CheckSum(unsigned char* pch_message, unsigned int dw_length, unsigned char uc_crc_8)
289 {
290 unsigned char uc_index;
291 while (dw_length--)
292 {
293 uc_index = uc_crc_8 ^ (*pch_message++);
294 uc_crc_8 = rm_referee::kCrc8Table[uc_index];
295 }
296 return (uc_crc_8);
297 }
298
299 uint32_t verifyCRC8CheckSum(unsigned char* pch_message, unsigned int dw_length)
300 {
301 unsigned char uc_expected;
302 if ((pch_message == nullptr) || (dw_length <= 2))
303 return 0;
304 uc_expected = getCRC8CheckSum(pch_message, dw_length - 1, rm_referee::kCrc8Init);
305 return (uc_expected == pch_message[dw_length - 1]);
306 }
307
308 void appendCRC8CheckSum(unsigned char* pch_message, unsigned int dw_length)
309 {
310 unsigned char uc_crc;
311 if ((pch_message == nullptr) || (dw_length <= 2))
312 return;
313 uc_crc = getCRC8CheckSum((unsigned char*)pch_message, dw_length - 1, rm_referee::kCrc8Init);
314 pch_message[dw_length - 1] = uc_crc;
315 }
316
317 uint16_t getCRC16CheckSum(uint8_t* pch_message, uint32_t dw_length, uint16_t w_crc)
318 {
319 uint8_t chData;
320 if (pch_message == nullptr)
321 return 0xFFFF;
322 while (dw_length--)
323 {
324 chData = *pch_message++;
325 (w_crc) = (static_cast<uint16_t>(w_crc) >> 8) ^
326 rm_referee::wCRC_table[(static_cast<uint16_t>(w_crc) ^ static_cast<uint16_t>(chData)) & 0x00ff];
327 }
328 return w_crc;
329 }
330
331 uint32_t verifyCRC16CheckSum(uint8_t* pch_message, uint32_t dw_length)
332 {
333 uint16_t w_expected;
334 if ((pch_message == nullptr) || (dw_length <= 2))
335 return 0;
336 w_expected = getCRC16CheckSum(pch_message, dw_length - 2, rm_referee::kCrc16Init);
337 return ((w_expected & 0xff) == pch_message[dw_length - 2] &&
338 ((w_expected >> 8) & 0xff) == pch_message[dw_length - 1]);
339 }
340
341 void appendCRC16CheckSum(uint8_t* pch_message, uint32_t dw_length)
342 {
343 uint16_t wCRC;
344 if ((pch_message == nullptr) || (dw_length <= 2))
345 return;
346 wCRC = getCRC16CheckSum(static_cast<uint8_t*>(pch_message), dw_length - 2, rm_referee::kCrc16Init);
347 pch_message[dw_length - 2] = static_cast<uint8_t>((wCRC & 0x00ff));
348 pch_message[dw_length - 1] = static_cast<uint8_t>(((wCRC >> 8) & 0x00ff));
349 }
350};
351} // namespace rm_referee
Definition data.h:115
bool ensurePortOpen(size_t index, const ros::Time &now)
Definition data.h:171
size_t serial_port_count_
Definition data.h:129
int capacity_recent_mode_
Definition data.h:135
bool writeActive(const uint8_t *data, size_t data_len)
Definition data.h:273
int client_id_
Definition data.h:133
uint8_t getCRC8CheckSum(unsigned char *pch_message, unsigned int dw_length, unsigned char uc_crc_8)
Definition data.h:288
std::string robot_color_
Definition data.h:136
int active_port_index_
Definition data.h:130
bool shouldProcessPort(size_t index, const ros::Time &now, const ros::Duration &freshness) const
Definition data.h:229
void appendCRC8CheckSum(unsigned char *pch_message, unsigned int dw_length)
Definition data.h:308
void handlePortIoFailure(size_t index, const ros::Time &now, const std::string &action, const std::exception &e)
Definition data.h:202
void appendCRC16CheckSum(uint8_t *pch_message, uint32_t dw_length)
Definition data.h:341
uint32_t verifyCRC8CheckSum(unsigned char *pch_message, unsigned int dw_length)
Definition data.h:299
bool isPortFresh(size_t index, const ros::Time &now, const ros::Duration &freshness) const
Definition data.h:216
std::array< SerialPortState, kMaxSerialPorts > serial_ports_
Definition data.h:128
void activatePort(size_t index)
Definition data.h:238
void initSerial(ros::NodeHandle &nh)
Definition data.h:139
bool referee_data_is_online_
Definition data.h:137
int robot_id_
Definition data.h:134
uint16_t getCRC16CheckSum(uint8_t *pch_message, uint32_t dw_length, uint16_t w_crc)
Definition data.h:317
int capacity_expect_mode_
Definition data.h:135
void markValidFrame(size_t index, const ros::Time &stamp, const ros::Duration &freshness)
Definition data.h:250
ros::Duration reopen_interval_
Definition data.h:131
static constexpr size_t kMaxSerialPorts
Definition data.h:117
void refreshOnlineState(const ros::Time &now, const ros::Duration &freshness)
Definition data.h:260
bool isActivePortFresh(const ros::Time &now, const ros::Duration &freshness) const
Definition data.h:224
uint32_t verifyCRC16CheckSum(uint8_t *pch_message, uint32_t dw_length)
Definition data.h:331
Definition data.h:104
const uint8_t kCrc8Init
Definition protocol.h:749
const uint8_t kCrc8Table[256]
Definition protocol.h:750
const uint16_t kCrc16Init
Definition protocol.h:766
const uint16_t wCRC_table[256]
Definition protocol.h:767
ros::Time last_valid_frame_time
Definition data.h:123
bool configured
Definition data.h:125
serial::Serial serial
Definition data.h:121
std::string device
Definition data.h:122
ros::Time next_open_attempt_time
Definition data.h:124
Definition data.h:106
double chassis_power
Definition data.h:107
double limit_power
Definition data.h:108
double cap_power
Definition data.h:110
bool is_online
Definition data.h:111
double buffer_power
Definition data.h:109