Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
laeAlarms.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // Library: liblaelaps
6 //
7 // File: laeAlarms.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2016-04-08 15:42:39 -0600 (Fri, 08 Apr 2016) $
12  * $Rev: 4380 $
13  *
14  * \brief Laelaps alarm monitoring class implementation.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \par Copyright
19  * \h_copy 2016-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 /*
24  * @EulaBegin@
25  *
26  * Unless otherwise stated explicitly, all materials contained are copyrighted
27  * and may not be used without RoadNarrows LLC's written consent,
28  * except as provided in these terms and conditions or in the copyright
29  * notice (documents and software) or other proprietary notice provided with
30  * the relevant materials.
31  *
32  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
33  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
34  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
35  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
36  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
37  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
40  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
41  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
42  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
43  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
44  *
45  * @EulaEnd@
46  */
47 ////////////////////////////////////////////////////////////////////////////////
48 
49 #include "rnr/rnrconfig.h"
50 
51 #include "Laelaps/laelaps.h"
52 #include "Laelaps/laeSysDev.h"
53 #include "Laelaps/RoboClaw.h"
54 #include "Laelaps/laeMotor.h"
55 #include "Laelaps/laeTune.h"
56 #include "Laelaps/laeAlarms.h"
57 #include "Laelaps/laeDb.h"
58 
59 using namespace std;
60 using namespace laelaps;
61 using namespace motor::roboclaw;
62 
63 // -----------------------------------------------------------------------------
64 // Class LaeAlarms
65 // -----------------------------------------------------------------------------
66 
67 LaeAlarms::LaeAlarms()
68 {
69 }
70 
71 LaeAlarms::~LaeAlarms()
72 {
73 }
74 
75 bool LaeAlarms::isCritical()
76 {
77  return RtDb.m_alarms.m_system.m_bIsCritical;
78 }
79 
80 bool LaeAlarms::isBatteryCritical()
81 {
82  return RtDb.m_alarms.m_battery.m_bIsCritical;
83 }
84 
85 bool LaeAlarms::isSafeToOperate()
86 {
87  // no critical alarms
88  if( !RtDb.m_alarms.m_system.m_bIsCritical )
89  {
90  return true;
91  }
92  // only battery critical
93  else if( (RtDb.m_alarms.m_system.m_uAlarms & ~LAE_ALARM_BATT) ==
94  LAE_ALARM_NONE )
95  {
96  return true;
97  }
98  // bad robot
99  else
100  {
101  return false;
102  }
103 }
104 
105 void LaeAlarms::update()
106 {
107  LaeAlarmInfo sys; // system alarms
108  LaeAlarmInfo subsys; // subsystem alarms
109  LaeAlarmInfo mot1; // motor 1 subsystem alarms
110  LaeAlarmInfo mot2; // motor 2 subsystem alarms
111  LaeAlarmInfo sensors; // sensors subsytem alarms
112  u32_t uStatus; // subsystem status
113  int nCtlr; // motor controller index
114  int nMotor1, nMotor2; // motors 1 and 2 absolute indices
115 
116  // clear local copy of system alarms
117  clearAlarms(sys);
118 
119  //
120  // Determine motor controllers and motors alarm state.
121  //
122  for(nCtlr=0; nCtlr<LaeNumMotorCtlrs; ++nCtlr)
123  {
124  clearAlarms(subsys);
125  clearAlarms(mot1);
126  clearAlarms(mot2);
127 
128  uStatus = RtDb.m_motorctlr[nCtlr].m_uStatus;
129 
130  if( nCtlr == LaeMotorCtlrIdFront ) // front
131  {
132  nMotor1 = LaeMotorIdLF;
133  nMotor2 = LaeMotorIdRF;
134  }
135  else // rear
136  {
137  nMotor1 = LaeMotorIdLR;
138  nMotor2 = LaeMotorIdRR;
139  }
140 
141  // map controller status to controller alarms
142  if( uStatus & ParamStatusErrTemp )
143  {
144  subsys.m_uAlarms |= LAE_ALARM_TEMP;
145  }
146  if( uStatus & ParamStatusErrMainBattHigh )
147  {
148  subsys.m_uAlarms |= LAE_ALARM_MOTCTLR_BATT_V_HIGH;
149  }
150  if( uStatus & ParamStatusErrLogicBattHigh )
151  {
152  subsys.m_uAlarms |= LAE_ALARM_MOTCTLR_LOGIC_V_HIGH;
153  }
154  if( uStatus & ParamStatusErrLogicBattLow )
155  {
156  subsys.m_uAlarms |= LAE_ALARM_MOTCTLR_LOGIC_V_LOW;
157  }
158 
159  // map controller status to controller warnings
160  if( uStatus & ParamStatusWarnMainBattHigh )
161  {
162  subsys.m_uWarnings |= LAE_WARN_MOTCTLR_BATT_V_HIGH;
163  }
164  if( uStatus & ParamStatusWarnMainBattLow )
165  {
166  subsys.m_uWarnings |= LAE_WARN_MOTCTLR_BATT_V_LOW;
167  }
168  if( uStatus & ParamStatusWarnTemp )
169  {
170  subsys.m_uWarnings |= LAE_WARN_TEMP;
171  }
172 
173  // contoller critcal alarms
174  if( subsys.m_uAlarms & LAE_CRIT_MOTCTLR )
175  {
176  subsys.m_bIsCritical = true;
177  }
178 
179  // motor alarms
180  if( uStatus & ParamStatusErrMot1Fault )
181  {
182  mot1.m_uAlarms |= LAE_ALARM_MOT_FAULT;
183  }
184  if( uStatus & ParamStatusErrMot2Fault )
185  {
186  mot2.m_uAlarms |= LAE_ALARM_MOT_FAULT;
187  }
188 
189  // motor warnings
190  if( uStatus & ParamStatusWarnMot1OverCur )
191  {
192  mot1.m_uWarnings |= LAE_WARN_MOT_OVER_CUR;
193  }
194  if( uStatus & ParamStatusWarnMot2OverCur )
195  {
196  mot2.m_uWarnings |= LAE_WARN_MOT_OVER_CUR;
197  }
198 
199  // motor critcal alarms
200  if( mot1.m_uAlarms & LAE_CRIT_MOT )
201  {
202  mot1.m_bIsCritical = true;
203  }
204  if( mot2.m_uAlarms & LAE_CRIT_MOT )
205  {
206  mot2.m_bIsCritical = true;
207  }
208 
209  // copy to database
210  copyAlarms(subsys, RtDb.m_alarms.m_motorctlr[nCtlr]);
211  copyAlarms(mot1, RtDb.m_alarms.m_motor[nMotor1]);
212  copyAlarms(mot2, RtDb.m_alarms.m_motor[nMotor2]);
213 
214  // update system alarms from subsystem state
215  updateSysAlarms(subsys, sys);
216  updateSysAlarms(mot1, sys);
217  updateSysAlarms(mot2, sys);
218  }
219 
220  //
221  // Determine battery alarm state
222  //
223  clearAlarms(subsys);
224 
225  if( RtDb.m_energy.m_fBatterySoC < LAE_CRIT_BATT_SOC )
226  {
227  subsys.m_uAlarms |= LAE_ALARM_BATT;
228  subsys.m_bIsCritical = true;
229  }
230  if( RtDb.m_energy.m_fBatterySoC < LAE_WARN_BATT_SOC )
231  {
232  subsys.m_uWarnings |= LAE_WARN_BATT;
233  }
234 
235  // copy to database
236  copyAlarms(subsys, RtDb.m_alarms.m_battery);
237 
238  // update system alarms from subsystem state
239  updateSysAlarms(subsys, sys);
240 
241  //
242  // Determine senors alarm state
243  //
244  clearAlarms(subsys);
245 
246  if( !RtDb.m_enable.m_bImu )
247  {
248  subsys.m_uAlarms |= LAE_ALARM_IMU;
249  }
250  if( !RtDb.m_enable.m_bRange )
251  {
252  subsys.m_uAlarms |= LAE_ALARM_RANGE;
253  }
254  if( !RtDb.m_enable.m_bFCam )
255  {
256  subsys.m_uAlarms |= LAE_ALARM_FCAM;
257  }
258 
259  // copy to database
260  copyAlarms(subsys, RtDb.m_alarms.m_sensors);
261 
262  // update system alarms from subsystem state
263  updateSysAlarms(subsys, sys);
264 
265  //
266  // Other system alarms.
267  //
268  if( RtDb.m_robotstatus.m_bIsEStopped )
269  {
270  sys.m_uAlarms |= LAE_ALARM_ESTOP;
271  }
272 
273  // copy system alarms to database
274  copyAlarms(sys, RtDb.m_alarms.m_system);
275 
276  //
277  // Final settings
278  //
279  if( RtDb.m_alarms.m_system.m_uAlarms == LAE_ALARM_NONE )
280  {
281  RtDb.m_robotstatus.m_bAlarmState = false;
282  }
283  else
284  {
285  RtDb.m_robotstatus.m_bAlarmState = true;
286  }
287 
288  //fprintf(stderr, "DBG: isCrit=%d, alarms=0x%x, warns=0x%x\n",
289  // RtDb.m_alarms.m_system.m_bIsCritical,
290  // RtDb.m_alarms.m_system.m_uAlarms,
291  // RtDb.m_alarms.m_system.m_uWarnings);
292 }
293 
294 void LaeAlarms::updateSysAlarms(const LaeAlarmInfo &subsys, LaeAlarmInfo &sys)
295 {
296  //
297  // Any critically alarms subsystem propagates up to the system level.
298  //
299  if( subsys.m_bIsCritical )
300  {
301  sys.m_bIsCritical = true;
302  }
303 
304  //
305  // Subsytems alarms that propagate up to the system level.
306  //
307  if( subsys.m_uAlarms & LAE_ALARM_TEMP )
308  {
309  sys.m_uAlarms |= LAE_ALARM_TEMP;
310  }
311  if( subsys.m_uAlarms & LAE_ALARM_BATT )
312  {
313  sys.m_uAlarms |= LAE_ALARM_BATT;
314  }
315  if( subsys.m_uAlarms & LAE_ALARM_IMU )
316  {
317  sys.m_uAlarms |= LAE_ALARM_IMU;
318  }
319  if( subsys.m_uAlarms & LAE_ALARM_RANGE )
320  {
321  sys.m_uAlarms |= LAE_ALARM_RANGE;
322  }
323  if( subsys.m_uAlarms & LAE_ALARM_FCAM )
324  {
325  sys.m_uAlarms |= LAE_ALARM_FCAM;
326  }
327 
328  //
329  // Subsystem is [not] alarmed.
330  //
331  if( subsys.m_uAlarms != LAE_ALARM_NONE )
332  {
333  sys.m_uAlarms |= LAE_ALARM_SUBSYS;
334  }
335 
336  //
337  // Subsytems warnings that propagate up to the system level.
338  //
339  if( subsys.m_uWarnings & LAE_WARN_TEMP )
340  {
341  sys.m_uWarnings |= LAE_WARN_TEMP;
342  }
343 
344  if( subsys.m_uWarnings & LAE_WARN_BATT )
345  {
346  sys.m_uWarnings |= LAE_WARN_BATT;
347  }
348 
349  if( subsys.m_uWarnings != LAE_WARN_NONE )
350  {
351  sys.m_uWarnings |= LAE_WARN_SUBSYS;
352  }
353 }
354 
355 void LaeAlarms::clearAlarms(LaeAlarmInfo &info)
356 {
357  info.m_bIsCritical = false;
358  info.m_uAlarms = LAE_ALARM_NONE;
359  info.m_uWarnings = LAE_WARN_NONE;
360 }
361 
362 void LaeAlarms::copyAlarms(const LaeAlarmInfo &src, LaeAlarmInfo &dst)
363 {
364  dst.m_bIsCritical = src.m_bIsCritical;
365  dst.m_uAlarms = src.m_uAlarms;
366  dst.m_uWarnings = src.m_uWarnings;
367 }
logic battery under volt error
Definition: RoboClaw.h:322
u32_t m_uWarnings
warning or&#39;ed bits
Definition: laeAlarms.h:161
Alarm information state structure.
Definition: laeAlarms.h:157
RoboClaw motor controller class interface.
bool m_bIsCritical
is [not] critical alarm
Definition: laeAlarms.h:159
temperature out-of-range error
Definition: RoboClaw.h:318
main battery over voltage error
Definition: RoboClaw.h:320
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
temp out-of-range warning
Definition: RoboClaw.h:327
main battery over volt warning
Definition: RoboClaw.h:325
u32_t m_uAlarms
alarm or&#39;ed bits
Definition: laeAlarms.h:160
Laelaps tuning.
Laelaps system devices.
main battery under volt warning
Definition: RoboClaw.h:326
Laelaps motors, encoder, and controllers hardware abstraction interfaces.
Laelaps alarm monitoring class interface.
logic battery over volt error
Definition: RoboClaw.h:321
motor 1 over current warning
Definition: RoboClaw.h:315
motor 2 over current warning
Definition: RoboClaw.h:316
Laelaps real-time "database".
Top-level package include file.