rc.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, James Jackson and Daniel Koch, BYU MAGICC Lab
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 
33 #include <cstring>
34 
35 #include "rc.h"
36 #include "rosflight.h"
37 
38 namespace rosflight_firmware
39 {
40 
42  RF_(_rf)
43 {}
44 
45 void RC::init()
46 {
47  init_rc();
48  RF_.params_.add_callback([this](uint16_t param_id)
49  {
50  this->param_change_callback(param_id);
51  }, PARAM_RC_TYPE);
52  RF_.params_.add_callback([this](uint16_t param_id)
53  {
54  this->param_change_callback(param_id);
56  RF_.params_.add_callback([this](uint16_t param_id)
57  {
58  this->param_change_callback(param_id);
60  RF_.params_.add_callback([this](uint16_t param_id)
61  {
62  this->param_change_callback(param_id);
64  RF_.params_.add_callback([this](uint16_t param_id)
65  {
66  this->param_change_callback(param_id);
68  RF_.params_.add_callback([this](uint16_t param_id)
69  {
70  this->param_change_callback(param_id);
72  RF_.params_.add_callback([this](uint16_t param_id)
73  {
74  this->param_change_callback(param_id);
76  RF_.params_.add_callback([this](uint16_t param_id)
77  {
78  this->param_change_callback(param_id);
80  RF_.params_.add_callback([this](uint16_t param_id)
81  {
82  this->param_change_callback(param_id);
84  RF_.params_.add_callback([this](uint16_t param_id)
85  {
86  this->param_change_callback(param_id);
88  RF_.params_.add_callback([this](uint16_t param_id)
89  {
90  this->param_change_callback(param_id);
92  RF_.params_.add_callback([this](uint16_t param_id)
93  {
94  this->param_change_callback(param_id);
96  RF_.params_.add_callback([this](uint16_t param_id)
97  {
98  this->param_change_callback(param_id);
100  new_command_ = false;
101 }
102 
104 {
105  RF_.board_.rc_init(static_cast<Board::rc_type_t>(RF_.params_.get_param_int(PARAM_RC_TYPE)));
106  init_sticks();
107  init_switches();
108 }
109 
110 void RC::param_change_callback(uint16_t param_id)
111 {
112  (void) param_id; // suppress unused parameter warning
113  init_rc();
114 }
115 
116 float RC::stick(Stick channel)
117 {
118  return stick_values[channel];
119 }
120 
121 bool RC::switch_on(Switch channel)
122 {
123  return switch_values[channel];
124 }
125 
127 {
128  return switches[channel].mapped;
129 }
130 
131 
132 void RC::init_sticks(void)
133 {
135  sticks[STICK_X].one_sided = false;
136 
138  sticks[STICK_Y].one_sided = false;
139 
141  sticks[STICK_Z].one_sided = false;
142 
144  sticks[STICK_F].one_sided = true;
145 }
146 
148 {
149  for (uint8_t chan = 0; chan < static_cast<uint8_t>(SWITCHES_COUNT); chan++)
150  {
151  char channel_name[18];
152  switch (chan)
153  {
154  case SWITCH_ARM:
155  strcpy(channel_name, "ARM");
157  break;
158  case SWITCH_ATT_OVERRIDE:
159  strcpy(channel_name, "ATTITUDE OVERRIDE");
161  break;
163  strcpy(channel_name, "THROTTLE OVERRIDE");
165  break;
166  case SWITCH_ATT_TYPE:
167  strcpy(channel_name, "ATTITUDE TYPE");
169  break;
170  default:
171  strcpy(channel_name, "INVALID");
172  switches[chan].channel = 255;
173  break;
174  }
175 
176  switches[chan].mapped = switches[chan].channel > 3
178 
179  switch (switches[chan].channel)
180  {
181  case 4:
183  break;
184  case 5:
186  break;
187  case 6:
189  break;
190  case 7:
192  break;
193  default:
194  switches[chan].direction = 1;
195  break;
196  }
197 
198  if (switches[chan].mapped)
199  RF_.comm_manager_.log(CommLink::LogSeverity::LOG_INFO, "%s switch mapped to RC channel %d", channel_name,
200  switches[chan].channel);
201  else
202  RF_.comm_manager_.log(CommLink::LogSeverity::LOG_INFO, "%s switch not mapped", channel_name);
203  }
204 }
205 
207 {
208  bool failsafe = false;
209 
210  // If the board reports that we have lost RC, tell the state manager
211  if (RF_.board_.rc_lost())
212  {
213  failsafe = true;
214  }
215  else
216  {
217  // go into failsafe if we get an invalid RC command for any channel
218  for (int8_t i = 0; i<RF_.params_.get_param_int(PARAM_RC_NUM_CHANNELS); i++)
219  {
220  float pwm = RF_.board_.rc_read(i);
221  if (pwm < -0.25 || pwm > 1.25)
222  {
223  failsafe = true;
224  }
225  }
226  }
227 
228  if (failsafe)
229  // set the RC Lost error flag
231  else
232  // Clear the RC Lost Error
234 
235  return failsafe;
236 }
237 
239 {
240  uint32_t now_ms = RF_.board_.clock_millis();
241  uint32_t dt = now_ms - prev_time_ms;
242  prev_time_ms = now_ms;
243  // check for arming switch
245  {
246  if (!RF_.state_manager_.state().armed) // we are DISARMED
247  {
248  // if left stick is down and to the right
251  {
253  }
254  else
255  {
257  }
259  {
261  }
262  }
263  else // we are ARMED
264  {
265  // if left stick is down and to the left
268  {
270  }
271  else
272  {
274  }
276  {
279  }
280  }
281  }
282  else // ARMING WITH SWITCH
283  {
285  {
286  if (!RF_.state_manager_.state().armed)
288  }
289  else
290  {
292  }
293  }
294 }
295 
296 
297 bool RC::run()
298 {
299  uint32_t now = RF_.board_.clock_millis();
300 
301  // if it has been more than 20ms then look for new RC values and parse them
302  if (now - last_rc_receive_time < 20)
303  {
304  return false;
305  }
306  last_rc_receive_time = now;
307 
308 
309  // Check for rc lost
310  if (check_rc_lost())
311  return false;
312 
313 
314  // read and normalize stick values
315  for (uint8_t channel = 0; channel < static_cast<uint8_t>(STICKS_COUNT); channel++)
316  {
317  float pwm = RF_.board_.rc_read(sticks[channel].channel);
318  if (sticks[channel].one_sided) //generally only F is one_sided
319  {
320  stick_values[channel] = pwm;
321  }
322  else
323  {
324  stick_values[channel] = 2.0 * (pwm - 0.5);
325  }
326  }
327 
328  // read and interpret switch values
329  for (uint8_t channel = 0; channel < static_cast<uint8_t>(SWITCHES_COUNT); channel++)
330  {
331  if (switches[channel].mapped)
332  {
333  if (switches[channel].direction < 0)
334  {
335  switch_values[channel] = RF_.board_.rc_read(switches[channel].channel) < 0.2;
336  }
337  else
338  {
339  switch_values[channel] = RF_.board_.rc_read(switches[channel].channel) >= 0.8;
340  }
341  }
342  else
343  {
344  switch_values[channel] = false;
345  }
346  }
347 
348  // Look for arming and disarming signals
350 
351  // Signal to the mux that we need to compute a new combined command
352  new_command_ = true;
353  return true;
354 }
355 
357 {
358  if (new_command_)
359  {
360  new_command_ = false;
361  return true;
362  }
363  else
364  return false;;
365 }
366 
367 }
bool switch_mapped(Switch channel)
Definition: rc.cpp:126
virtual float rc_read(uint8_t channel)=0
virtual bool rc_lost()=0
bool new_command_
Definition: rc.h:91
rc_switch_config_t switches[SWITCHES_COUNT]
Definition: rc.h:99
void init_switches()
Definition: rc.cpp:147
rc_stick_config_t sticks[STICKS_COUNT]
Definition: rc.h:98
bool switch_on(Switch channel)
Definition: rc.cpp:121
ROSflight & RF_
Definition: rc.h:76
float stick(Stick channel)
Definition: rc.cpp:116
void init_sticks()
Definition: rc.cpp:132
RC(ROSflight &_rf)
Definition: rc.cpp:41
uint32_t time_sticks_have_been_in_arming_position_ms
Definition: rc.h:94
float get_param_float(uint16_t id) const
Get the value of a floating point parameter by id.
Definition: param.h:326
void add_callback(std::function< void(int)> callback, uint16_t param_id)
Definition: param.cpp:308
const State & state() const
Definition: state_manager.h:82
uint32_t prev_time_ms
Definition: rc.h:95
volatile float stick_values[STICKS_COUNT]
Definition: rc.h:102
void log(CommLink::LogSeverity severity, const char *fmt,...)
void param_change_callback(uint16_t param_id)
Definition: rc.cpp:110
virtual uint32_t clock_millis()=0
int get_param_int(uint16_t id) const
Get the value of an integer parameter by id.
Definition: param.h:316
volatile bool switch_values[SWITCHES_COUNT]
Definition: rc.h:101
uint32_t last_rc_receive_time
Definition: rc.h:96
virtual void rc_init(rc_type_t rc_type)=0
void look_for_arm_disarm_signal()
Definition: rc.cpp:238
bool new_command()
Definition: rc.cpp:356
bool check_rc_lost()
Definition: rc.cpp:206


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Wed Jul 3 2019 19:59:25