rm_control
Loading...
Searching...
No Matches
heat_limit.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 qiayuan on 5/19/21.
36//
37
38#pragma once
39
40#include <ros/ros.h>
41#include <mutex>
42#include <rm_msgs/GameRobotStatus.h>
43#include <rm_msgs/PowerHeatData.h>
44#include <rm_msgs/ShootCmd.h>
45#include <rm_msgs/LocalHeatState.h>
46#include <rm_msgs/LocalHeatData.h>
47#include <std_msgs/Float64.h>
48
49namespace rm_common
50{
52{
53public:
54 HeatLimit(ros::NodeHandle& nh)
55
56 {
57 if (!nh.getParam("low_shoot_frequency", low_shoot_frequency_))
58 ROS_ERROR("Low shoot frequency no defined (namespace: %s)", nh.getNamespace().c_str());
59 if (!nh.getParam("high_shoot_frequency", high_shoot_frequency_))
60 ROS_ERROR("High shoot frequency no defined (namespace: %s)", nh.getNamespace().c_str());
61 if (!nh.getParam("burst_shoot_frequency", burst_shoot_frequency_))
62 ROS_ERROR("Burst shoot frequency no defined (namespace: %s)", nh.getNamespace().c_str());
63 if (!nh.getParam("minimal_shoot_frequency", minimal_shoot_frequency_))
64 ROS_ERROR("Minimal shoot frequency no defined (namespace: %s)", nh.getNamespace().c_str());
65 if (!nh.getParam("outpost_shoot_frequency", outpost_shoot_frequency_))
66 ROS_ERROR("Outpost shoot frequency no defined (namespace: %s)", nh.getNamespace().c_str());
67 if (!nh.getParam("safe_shoot_frequency", safe_shoot_frequency_))
68 ROS_ERROR("Safe shoot frequency no defined (namespace: %s)", nh.getNamespace().c_str());
69 if (!nh.getParam("heat_coeff", heat_coeff_))
70 ROS_ERROR("Heat coeff no defined (namespace: %s)", nh.getNamespace().c_str());
71 if (!nh.getParam("type", type_))
72 ROS_ERROR("Shooter type no defined (namespace: %s)", nh.getNamespace().c_str());
73 if (!nh.getParam("local_heat_protect_threshold", heat_protect_threshold_))
74 ROS_ERROR("Local heat protect threshold no defined (namespace: %s)", nh.getNamespace().c_str());
75 if (!nh.getParam("buff_offset", buff_offset_))
76 ROS_ERROR("Buff offset no defined (namespace: %s)", nh.getNamespace().c_str());
77 nh.param("use_local_heat", use_local_heat_, true);
78 if (type_ == "ID1_42MM")
79 bullet_heat_ = 100.;
80 else
81 bullet_heat_ = 10.;
82 local_heat_pub_ = nh.advertise<rm_msgs::LocalHeatData>("/local_heat_state/local_cooling_heat", 10);
83 shoot_state_sub_ =
84 nh.subscribe<rm_msgs::LocalHeatState>("/local_heat_state/shooter_state", 50, &HeatLimit::heatCB, this);
85 timer_ = nh.createTimer(ros::Duration(0.1), std::bind(&HeatLimit::timerCB, this));
86 fly_time_sub_ = nh.subscribe<std_msgs::Float64>("/controllers/gimbal_controller/bullet_solver/fly_time", 10,
88 }
89
90 typedef enum
91 {
92 LOW = 0,
93 HIGH = 1,
94 BURST = 2,
95 MINIMAL = 3
97
98 void heatCB(const rm_msgs::LocalHeatStateConstPtr& msg)
99 {
100 std::lock_guard<std::mutex> lock(heat_mutex_);
101 if (msg->has_shoot && last_shoot_state_ != msg->has_shoot)
102 {
103 local_shooter_cooling_heat_ += bullet_heat_;
104 if (local_shooter_cooling_heat_ > 0)
105 once_shoot_num_++;
106 }
107 last_shoot_state_ = msg->has_shoot;
108 }
109
110 void timerCB()
111 {
112 std::lock_guard<std::mutex> lock(heat_mutex_);
113 if (local_shooter_cooling_heat_ > 0.0)
114 local_shooter_cooling_heat_ -= shooter_cooling_rate_ * 0.1;
115 if (local_shooter_cooling_heat_ < 0.0)
116 {
117 local_shooter_cooling_heat_ = 0.0;
118 once_shoot_num_ = 0;
119 }
120 local_heat_pub_data_.once_shoot_num = once_shoot_num_;
121 local_heat_pub_data_.local_shooter_cooling_heat = local_shooter_cooling_heat_;
122 local_heat_pub_data_.desire_shoot_frequency = shoot_frequency_;
123 local_heat_pub_.publish(local_heat_pub_data_);
124 }
125
126 void setStatusOfShooter(const rm_msgs::GameRobotStatus data)
127 {
128 shooter_cooling_limit_ = data.shooter_cooling_limit - heat_protect_threshold_;
129 shooter_cooling_rate_ = data.shooter_cooling_rate;
130 }
131
132 void setCoolingHeatOfShooter(const rm_msgs::PowerHeatData data)
133 {
134 if (type_ == "ID1_17MM")
135 {
136 shooter_cooling_heat_ = data.shooter_id_1_17_mm_cooling_heat;
137 }
138 else if (type_ == "ID2_17MM")
139 {
140 // RoboMaster 2026 protocol only reports one 17mm barrel heat field.
141 shooter_cooling_heat_ = data.shooter_id_1_17_mm_cooling_heat;
142 }
143 else if (type_ == "ID1_42MM")
144 {
145 shooter_cooling_heat_ = data.shooter_id_1_42_mm_cooling_heat;
146 }
147 referee_status_change_ = true;
148 }
149
150 void setRefereeStatus(bool status)
151 {
152 referee_is_online_ = status;
153 }
154
156 {
157 std::lock_guard<std::mutex> lock(heat_mutex_);
158 if (!referee_is_online_)
159 return 5.0;
160 if (referee_status_change_ && abs(local_shooter_cooling_heat_ - shooter_cooling_heat_) > 10)
161 {
162 local_shooter_cooling_heat_ = shooter_cooling_heat_;
163 }
164 referee_status_change_ = false;
165 double shooter_cooling_heat =
166 (use_local_heat_ || !referee_is_online_) ? local_shooter_cooling_heat_ : shooter_cooling_heat_;
167 if (shooter_cooling_limit_ - shooter_cooling_heat < bullet_heat_)
168 return 0.0;
169 else if (shooter_cooling_limit_ - shooter_cooling_heat == bullet_heat_)
170 return shooter_cooling_rate_ / bullet_heat_;
171 else if (shooter_cooling_limit_ - shooter_cooling_heat <= bullet_heat_ * heat_coeff_)
172 return (shooter_cooling_limit_ - shooter_cooling_heat) / (bullet_heat_ * heat_coeff_) *
173 (shoot_frequency_ - shooter_cooling_rate_ / bullet_heat_) +
174 shooter_cooling_rate_ / bullet_heat_;
175 else
176 return shoot_frequency_;
177 }
178
180 {
181 updateExpectShootFrequency();
182 if (type_ == "ID1_17MM")
183 return rm_msgs::ShootCmd::SPEED_30M_PER_SECOND;
184 else if (type_ == "ID2_17MM")
185 return rm_msgs::ShootCmd::SPEED_30M_PER_SECOND;
186 else if (type_ == "ID1_42MM")
187 return rm_msgs::ShootCmd::SPEED_16M_PER_SECOND;
188 return -1; // TODO unsafe!
189 }
190
192 {
193 return shooter_cooling_limit_;
194 }
195
197 {
198 return shooter_cooling_heat_;
199 }
200
201 void setShootFrequency(uint8_t mode)
202 {
203 state_ = mode;
204 }
205
207 {
208 return state_;
209 }
210
211 void flyTimeCB(const std_msgs::Float64ConstPtr& msg)
212 {
213 buff_shoot_frequency_ = 1 / (msg->data + buff_offset);
214 }
215
216private:
217 void updateExpectShootFrequency()
218 {
219 if (state_ == HeatLimit::BURST)
220 {
221 shoot_frequency_ = burst_shoot_frequency_;
222 burst_flag_ = true;
223 }
224 else if (state_ == HeatLimit::LOW)
225 {
226 shoot_frequency_ = low_shoot_frequency_;
227 burst_flag_ = false;
228 }
229 else if (state_ == HeatLimit::HIGH)
230 {
231 shoot_frequency_ = high_shoot_frequency_;
232 burst_flag_ = false;
233 }
234 else if (state_ == HeatLimit::MINIMAL)
235 {
236 shoot_frequency_ = buff_shoot_frequency_;
237 // shoot_frequency_ = minimal_shoot_frequency_;
238 burst_flag_ = false;
239 }
240 else
241 {
242 shoot_frequency_ = safe_shoot_frequency_;
243 burst_flag_ = false;
244 }
245 }
246
247 uint8_t state_{};
248 std::string type_{};
249 bool burst_flag_ = false;
250 double bullet_heat_, safe_shoot_frequency_{}, heat_coeff_{}, shoot_frequency_{}, low_shoot_frequency_{},
251 high_shoot_frequency_{}, burst_shoot_frequency_{}, minimal_shoot_frequency_{}, outpost_shoot_frequency_{};
252
253 bool referee_is_online_, use_local_heat_, last_shoot_state_{};
254 int shooter_cooling_limit_, shooter_cooling_rate_, shooter_cooling_heat_;
255 double local_shooter_cooling_heat_{}, heat_protect_threshold_{};
256 double buff_shoot_frequency_{}, buff_offset_{};
257 int once_shoot_num_{};
258 bool referee_status_change_{};
259
260 ros::Publisher local_heat_pub_;
261 ros::Subscriber shoot_state_sub_;
262 ros::Subscriber fly_time_sub_;
263 ros::Timer timer_;
264
265 rm_msgs::LocalHeatData local_heat_pub_data_;
266
267 mutable std::mutex heat_mutex_;
268};
269
270} // namespace rm_common
Definition heat_limit.h:52
int getShootFrequencyMode() const
Definition heat_limit.h:206
int getCoolingLimit()
Definition heat_limit.h:191
void heatCB(const rm_msgs::LocalHeatStateConstPtr &msg)
Definition heat_limit.h:98
void setStatusOfShooter(const rm_msgs::GameRobotStatus data)
Definition heat_limit.h:126
ShootHz
Definition heat_limit.h:91
@ LOW
Definition heat_limit.h:92
@ HIGH
Definition heat_limit.h:93
@ BURST
Definition heat_limit.h:94
@ MINIMAL
Definition heat_limit.h:95
HeatLimit(ros::NodeHandle &nh)
Definition heat_limit.h:54
void setRefereeStatus(bool status)
Definition heat_limit.h:150
void setShootFrequency(uint8_t mode)
Definition heat_limit.h:201
int getCoolingHeat()
Definition heat_limit.h:196
void setCoolingHeatOfShooter(const rm_msgs::PowerHeatData data)
Definition heat_limit.h:132
double getShootFrequency()
Definition heat_limit.h:155
int getSpeedLimit()
Definition heat_limit.h:179
void timerCB()
Definition heat_limit.h:110
void flyTimeCB(const std_msgs::Float64ConstPtr &msg)
Definition heat_limit.h:211
Definition calibration_queue.h:44