Kuon  1.1.3
RoadNarrows Robotics Large Outdoor Mobile Robot Project
kuonRobot.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Kuon
4 //
5 // Library: libkuon
6 //
7 // File: kuonRobot.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2014-04-09 15:58:07 -0600 (Wed, 09 Apr 2014) $
12  * $Rev: 3638 $
13  *
14  * \brief Kuon Robot Class implementation.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  * \author Daniel Packard (daniel@roadnarrows.com)
18  *
19  * \copyright
20  * \h_copy 2013-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  *
27  * Permission is hereby granted, without written agreement and without
28  * license or royalty fees, to use, copy, modify, and distribute this
29  * software and its documentation for any purpose, provided that
30  * (1) The above copyright notice and the following two paragraphs
31  * appear in all copies of the source code and (2) redistributions
32  * including binaries reproduces these notices in the supporting
33  * documentation. Substantial modifications to this software may be
34  * copyrighted by their authors and need not follow the licensing terms
35  * described here, provided that the new terms are clearly indicated in
36  * all files where they apply.
37  *
38  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
39  * OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
40  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
41  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
42  * EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
43  * THE POSSIBILITY OF SUCH DAMAGE.
44  *
45  * THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
46  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
47  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
48  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
49  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
50  *
51  * @EulaEnd@
52  */
53 ////////////////////////////////////////////////////////////////////////////////
54 
55 #include <stdio.h>
56 #include <unistd.h>
57 #include <pthread.h>
58 #include <math.h>
59 
60 #include <string>
61 #include <vector>
62 #include <map>
63 
64 #include "rnr/rnrconfig.h"
65 #include "rnr/units.h"
66 #include "rnr/log.h"
67 
68 #include "Kuon/RS160DControl.h"
69 
70 #include "Kuon/kuon.h"
71 #include "Kuon/kuonUtils.h"
72 #include "Kuon/kuonSpec.h"
73 #include "Kuon/kuonDesc.h"
74 #include "Kuon/kuonJoint.h"
75 #include "Kuon/kuonTraj.h"
76 #include "Kuon/kuonStatus.h"
77 #include "Kuon/kuonRobot.h"
78 
79 using namespace std;
80 using namespace kuon;
81 
82 /*!
83  * \brief Test for no execute flag.
84  *
85  * Only works in KuonRobot methods.
86  *
87  * \return On true, return with KUON_OK.
88  */
89 #define KUON_TRY_NO_EXEC() \
90  do \
91  { \
92  if( m_bNoExec ) \
93  { \
94  return KUON_OK; \
95  } \
96  } while(0)
97 
98 /*!
99  * \brief Test for connection.
100  *
101  * Only works in KuonRobot methods.
102  *
103  * \return On failure, forces return from calling function with the appropriate
104  * error code.
105  */
106 #define KUON_TRY_CONN() \
107  do \
108  { \
109  if( !isConnected() ) \
110  { \
111  LOGERROR("Robot is not connected."); \
112  return -KUON_ECODE_NO_EXEC; \
113  } \
114  } while(0)
115 
116 /*!
117  * \brief Test for not estop.
118  *
119  * Only works in KuonRobot methods.
120  *
121  * \return On failure, forces return from calling function with the appropriate
122  * error code.
123  */
124 #define KUON_TRY_NOT_ESTOP() \
125  do \
126  { \
127  if( m_bIsEStopped ) \
128  { \
129  LOGERROR("Robot is emergency stopped."); \
130  return -KUON_ECODE_NO_EXEC; \
131  } \
132  } while(0)
133 
134 
135 // -----------------------------------------------------------------------------
136 // Class KuonRobot
137 // -----------------------------------------------------------------------------
138 
139 const float KuonRobot::GovernorDft = 0.20;
140 const float KuonRobot::BrakeDft = 0.20;
141 const float KuonRobot::SlewDft = 0.10;
142 
143 KuonRobot::KuonRobot(bool bNoExec)
144 {
145  // state
146  m_bNoExec = bNoExec;
147  m_eRobotMode = KuonRobotModeAuto;
148  m_bIsEStopped = false;
149  m_bAlarmState = false;
150  m_fBattery = 0.0;
151  m_fBrake = BrakeDft;
152  m_fSlew = SlewDft;
153  m_nSetPtSpeedLeft = 0;
154  m_nSetPtSpeedRight = 0;
155 
156  setGovernor(GovernorDft);
157 
158  // motor controllers i/f
159  m_fdMotorCtlr0 = -1; // front or rear (cannot tell with RS160D ctlrs)
160  m_fdMotorCtlr1 = -1; // front or rear (cannot tell with RS160D ctlrs)
161 
162  // asynchronous task control
163  m_eAsyncTaskState = KuonAsyncTaskStateIdle;
164  m_rcAsyncTask = KUON_OK;
165  m_eAsyncTaskId = AsyncTaskIdNone;
166  m_pAsyncTaskArg = NULL;
167 }
168 
169 KuonRobot::~KuonRobot()
170 {
171  disconnect();
172 }
173 
174 int KuonRobot::connect(const std::string &strDevMotorCtlr0,
175  const std::string &strDevMotorCtlr1,
176  int nBaudRateMotorCtlr)
177 {
178  string strDevName0; // real device name 0
179  string strDevName1; // real device name 1
180  int rc; // return code
181 
182  //
183  // Need a robot description before preceeding.
184  //
185  if( !m_descKuon.isDescribed() )
186  {
187  LOGERROR("Undefined Kuon description - "
188  "don't know how to initialized properly.");
189  return -KUON_ECODE_BAD_OP;
190  }
191 
192  // get the real device names, not any symbolic links
193  strDevName0 = getRealDeviceName(strDevMotorCtlr0);
194  strDevName1 = getRealDeviceName(strDevMotorCtlr1);
195 
196  // RDK Hack
197  // Possible race condition where controller is not fully powered on.
198  // Wait a little bit.
199  // RDK Hack
200  long usec = 3000000;
201  LOGDIAG2("Waiting for motor controllers to power-up");
202  usleep(usec);
203  // RDK Hack
204 
205  // Open motor controller 0.
206  //
207  if( RS160DOpenConnection(strDevName0.c_str(), &m_fdMotorCtlr0) < 0 )
208  {
209  LOGERROR("%s: Failed to open motor controller 0.", strDevName0.c_str());
210  rc = -KUON_ECODE_MOT_CTLR;
211  }
212 
213  //
214  // Configure motor controller 0.
215  //
216  else if( RS160DSetToSerial(m_fdMotorCtlr0) < 0 )
217  {
218  LOGERROR("%s: Failed to configure motor controller 0.",
219  strDevName0.c_str());
220  rc = -KUON_ECODE_MOT_CTLR;
221  }
222 
223  //
224  // Open motor controller 1.
225  //
226  if( RS160DOpenConnection(strDevName1.c_str(), &m_fdMotorCtlr1) < 0 )
227  {
228  LOGERROR("%s: Failed to open motor controller 1.", strDevName1.c_str());
229  rc = -KUON_ECODE_MOT_CTLR;
230  }
231 
232  //
233  // Configure motor controller 1.
234  //
235  else if( RS160DSetToSerial(m_fdMotorCtlr1) < 0 )
236  {
237  LOGERROR("%s: Failed to configure motor controller 1.",
238  strDevName1.c_str());
239  rc = -KUON_ECODE_MOT_CTLR;
240  }
241 
242  //
243  // Convert fixed specifications to operational parameters.
244  //
245  else if( (rc = convertSpecs()) < 0 )
246  {
247  LOGERROR("Failed to convert product specifications to "
248  "operational parameters.");
249  }
250 
251  //
252  // Configure for operation.
253  //
254  else if( (rc = configForOperation()) < 0 )
255  {
256  LOGERROR("Failed to configure for operation.");
257  }
258 
259  // success
260  else
261  {
262  LOGDIAG1("Connected to Kuon with controllers = (%s, %s).",
263  strDevMotorCtlr0.c_str(), strDevMotorCtlr1.c_str());
264 
265  rc = KUON_OK;
266  }
267 
268  // undo
269  if( rc < 0 )
270  {
271  disconnect();
272  }
273 
274  return rc;
275 }
276 
277 int KuonRobot::disconnect()
278 {
279  bool bWasConn = false;
280 
281  if( isConnected() )
282  {
283  bWasConn = true;
284  RS160DEStop(m_fdMotorCtlr0, m_fdMotorCtlr1);
285  }
286 
287  if( m_fdMotorCtlr0 >= 0 )
288  {
289  RS160DClose(m_fdMotorCtlr0);
290  m_fdMotorCtlr0 = -1;
291  }
292 
293  if( m_fdMotorCtlr1 >= 0 )
294  {
295  RS160DClose(m_fdMotorCtlr1);
296  m_fdMotorCtlr1 = -1;
297  }
298 
299  if( bWasConn )
300  {
301  LOGDIAG1("Disconnected from Kuon.");
302  }
303 
304  return KUON_OK;
305 }
306 
307 int KuonRobot::estop()
308 {
310  KUON_TRY_CONN();
311 
312  RS160DEStop(m_fdMotorCtlr0, m_fdMotorCtlr1);
313 
314  setBrake(1.0);
315 
316  m_bIsEStopped = true;
317  m_bAlarmState = true;
318 
319  m_lastTrajBase.clear();
320 
321  LOGDIAG3("Kuon emergency stopped.");
322 
323  return KUON_OK;
324 }
325 
326 int KuonRobot::freeze()
327 {
329  KUON_TRY_CONN();
330 
331  m_lastTrajBase.clear();
332 
333  // stop
334  setSpeed(0.0, 0.0);
335 
336  // set 'parking' brake
337  setBrake(1.0);
338 
339  LOGDIAG3("Kuon frozen at current position.");
340 
341  return KUON_OK;
342 }
343 
344 int KuonRobot::release()
345 {
347  KUON_TRY_CONN();
348 
349  m_lastTrajBase.clear();
350 
351  // stop
352  setSpeed(0.0, 0.0);
353 
354  // put in 'neutral'
355  setBrake(0.0);
356 
357  LOGDIAG3("Kuon servo drives released.");
358 
359  return KUON_OK;
360 }
361 
362 int KuonRobot::clearAlarms()
363 {
364  KUON_TRY_CONN();
365 
366  return KUON_OK;
367 }
368 
369 int KuonRobot::setBrake(float fBrake)
370 {
371  int raw;
372 
373  KUON_TRY_CONN();
375 
376  fBrake = (float)fcap(fBrake, 0.0, 1.0);
377 
378  raw = RS160D_MOTOR_BRAKE_MAX * fBrake;
379  raw = icap(raw, RS160D_MOTOR_BRAKE_MIN, RS160D_MOTOR_BRAKE_MAX);
380 
381  RS160DAlterBraking(raw, m_fdMotorCtlr0, RS160D_MOTOR_LEFT_ID);
382  RS160DAlterBraking(raw, m_fdMotorCtlr0, RS160D_MOTOR_RIGHT_ID);
383  RS160DAlterBraking(raw, m_fdMotorCtlr1, RS160D_MOTOR_LEFT_ID);
384  RS160DAlterBraking(raw, m_fdMotorCtlr1, RS160D_MOTOR_RIGHT_ID);
385 
386  m_fBrake = fBrake;
387 
388  m_bAreMotorsPowered = m_fBrake > 0.0? true: false;
389 
390  LOGDIAG3("Brakes set to %3.1f (raw=%d).", m_fBrake, raw);
391 
392  return KUON_OK;
393 }
394 
395 int KuonRobot::setSlew(float fSlew)
396 {
397  int raw;
398 
399  KUON_TRY_CONN();
401 
402  fSlew = (float)fcap(fSlew, 0.0, 1.0);
403 
404  raw = RS160D_MOTOR_SLEW_MAX * fSlew;
405  raw = icap(raw, RS160D_MOTOR_SLEW_MIN, RS160D_MOTOR_SLEW_MAX);
406 
407  RS160DAlterSlew(raw, m_fdMotorCtlr0, RS160D_MOTOR_LEFT_ID);
408  RS160DAlterSlew(raw, m_fdMotorCtlr0, RS160D_MOTOR_RIGHT_ID);
409  RS160DAlterSlew(raw, m_fdMotorCtlr1, RS160D_MOTOR_LEFT_ID);
410  RS160DAlterSlew(raw, m_fdMotorCtlr1, RS160D_MOTOR_RIGHT_ID);
411 
412  m_fSlew = fSlew;
413 
414  LOGDIAG3("Power slew set to %3.1f (raw=%d).", m_fSlew, raw);
415 
416  return KUON_OK;
417 }
418 
419 int KuonRobot::setSpeed(double fSpeedLeft, double fSpeedRight, units_t units)
420 {
421  int rawLeft;
422  int rawRight;
423 
424  KUON_TRY_CONN();
426 
427  rawLeft = velocityToRawSpeed(fSpeedLeft, units);
428  rawRight = velocityToRawSpeed(fSpeedRight, units);
429 
430  rawLeft = icap(rawLeft, m_nGovernSpeedMin, m_nGovernSpeedMax);
431  rawRight = icap(rawRight, m_nGovernSpeedMin, m_nGovernSpeedMax);
432 
433  RS160DUpdateMotorSpeeds(-rawLeft, m_fdMotorCtlr0, RS160D_MOTOR_LEFT_ID);
434  RS160DUpdateMotorSpeeds(rawRight, m_fdMotorCtlr0, RS160D_MOTOR_RIGHT_ID);
435  RS160DUpdateMotorSpeeds(-rawLeft, m_fdMotorCtlr1, RS160D_MOTOR_LEFT_ID);
436  RS160DUpdateMotorSpeeds(rawRight, m_fdMotorCtlr1, RS160D_MOTOR_RIGHT_ID);
437 
438  m_nSetPtSpeedLeft = rawLeft;
439  m_nSetPtSpeedRight = rawRight;
440 
441  LOGDIAG3("Speed raw_left=%d, raw_right=%d.", rawLeft, rawRight);
442 
443  return KUON_OK;
444 }
445 
446 int KuonRobot::move(KuonWheelTrajectoryPoint &trajectoryPoint)
447 {
448  // TBD
449  return KUON_OK;
450 }
451 
452 int KuonRobot::velocityToRawSpeed(double fVelocity, units_t units)
453 {
454  switch(units)
455  {
456  // [-1.0, 1.0] of max servo speed
457  case units_norm:
458  return (int)(RS160D_MOTOR_SPEED_MAX * fcap(fVelocity, -1.0, 1.0));
459 
460  // % of max motor speed
461  case units_percent:
462  return (int)(RS160D_MOTOR_SPEED_MAX *
463  fcap(fVelocity, -100.0, 100.0)/100.0);
464 
465  // %% of max motor speed
466  case units_permil:
467  return (int)(RS160D_MOTOR_SPEED_MAX *
468  fcap(fVelocity, -1000.0, 1000.0)/1000.0);
469 
470  // raw units
471  case units_raw:
472  return (int)fcap(fVelocity,
473  RS160D_MOTOR_SPEED_MIN, RS160D_MOTOR_SPEED_MAX);
474 
475  // future
476  case units_rad_per_s:
477  case units_m_per_s:
478  LOGWARN("%s velocity units not supported until encoders installed.",
479  units_shortname(units));
480  return 0;
481 
482  // bad units
483  default:
484  LOGWARN("%s velocity units not supported.", units_shortname(units));
485  return 0;
486  }
487 }
488 
489 void KuonRobot::getVelocitySetPoints(double &fSpeedLeft,
490  double &fSpeedRight,
491  units_t units)
492 {
493  switch(units)
494  {
495  // [-1.0, 1.0] of max servo speed
496  case units_norm:
497  fSpeedLeft = (double)m_nSetPtSpeedLeft / (double)RS160D_MOTOR_SPEED_MAX;
498  fSpeedRight = (double)m_nSetPtSpeedRight / (double)RS160D_MOTOR_SPEED_MAX;
499  break;
500 
501  // % of max motor speed
502  case units_percent:
503  fSpeedLeft = (double)m_nSetPtSpeedLeft / (double)RS160D_MOTOR_SPEED_MAX;
504  fSpeedRight = (double)m_nSetPtSpeedRight / (double)RS160D_MOTOR_SPEED_MAX;
505  fSpeedLeft *= 100.0;
506  fSpeedRight *= 100.0;
507  break;
508 
509  // %% of max motor speed
510  case units_permil:
511  fSpeedLeft = (double)m_nSetPtSpeedLeft / (double)RS160D_MOTOR_SPEED_MAX;
512  fSpeedRight = (double)m_nSetPtSpeedRight / (double)RS160D_MOTOR_SPEED_MAX;
513  fSpeedLeft *= 1000.0;
514  fSpeedRight *= 1000.0;
515  break;
516 
517  // raw
518  case units_raw:
519  default:
520  fSpeedLeft = (double)m_nSetPtSpeedLeft;
521  fSpeedRight = (double)m_nSetPtSpeedRight;
522  break;
523  }
524 }
525 
526 int KuonRobot::getRobotStatus(KuonRobotStatus &robotStatus)
527 {
528  MapRobotJoints::iterator iter; // kinematic chain iterator
529  int nMotorId; // motor id
530  bool bIsMoving; // robot is [not] moving
531  KuonMotorHealth health; // motor health
532 
533  robotStatus.clear();
534 
535  robotStatus.m_eRobotMode = m_eRobotMode;
536  robotStatus.m_eIsEStopped = m_bIsEStopped?
538  robotStatus.m_eAreDrivesPowered = m_bAreMotorsPowered?
540  robotStatus.m_eIsInMotion = isInMotion()?
542 
543  // alarmed statue
544  if( m_bAlarmState )
545  {
547  robotStatus.m_eIsInError = KuonTriStateTrue;
548  robotStatus.m_nErrorCode = m_bIsEStopped?
550  }
551 
552  // unalarmed state
553  else
554  {
555  robotStatus.m_eIsMotionPossible = m_bNoExec?
557  robotStatus.m_eIsInError = KuonTriStateFalse;
558  robotStatus.m_nErrorCode = KUON_OK;
559  }
560 
561  robotStatus.m_fGovernor = m_fGovernor;
562  robotStatus.m_fBattery = 0.0;
563 
564 
565  for(iter = m_kinBase.begin(); iter != m_kinBase.end(); ++iter)
566  {
567  health.m_strName = iter->second.m_strName;
568  health.m_nMotorId = iter->first;
569  health.m_fTemperature = 0.0;
570  health.m_fVoltage = 0.0;
571  health.m_uAlarms = 0;
572 
573  robotStatus.m_vecMotorHealth.push_back(health);
574  }
575 
576  return KUON_OK;
577 }
578 
579 int KuonRobot::getJointState(KuonJointStatePoint &jointStatePoint)
580 {
581  MapRobotJoints::iterator iter; // kinematic chain iterator
582  int nMotorId; // master servo id
583  KuonRobotJoint *pMotor; // robotic motor joint
584  KuonJointState jointState; // working joint state
585  byte_t uMask; // working bit mask
586  int i; // working index
587 
588  KUON_TRY_CONN();
589 
590  jointStatePoint.clear();
591 
592  jointStatePoint.setKinematicChainName("base");
593 
594  //
595  // Build joint state point.
596  //
597  for(iter = m_kinBase.begin(); iter != m_kinBase.end(); ++iter)
598  {
599  nMotorId = iter->first;
600  pMotor = &(iter->second);
601 
602  // identifiers
603  jointState.m_strName = pMotor->m_strName;
604  jointState.m_nMotorId = nMotorId;
605 
606  // positions (unknown without encoders)
607  jointState.m_fPosition = 0.0;
608  jointState.m_fOdometer = 0.0;
609  jointState.m_nEncoder = 0;
610 
611  // velocities
612  jointState.m_fVelocity = 0.0;
613  jointState.m_fVelocityMps = 0.0;
614  if( pMotor->m_nMotorIndex == RS160D_MOTOR_LEFT_ID )
615  {
616  jointState.m_nSpeed = m_nSetPtSpeedLeft;
617  }
618  else
619  {
620  jointState.m_nSpeed = m_nSetPtSpeedRight;
621  }
622 
623  // torques and powers
624  jointState.m_fEffort = 0.0;
625  jointState.m_fPe = 0.0;
626  jointState.m_fPm = 0.0;
627 
628  // braking and power-up slewing
629  jointState.m_fBrake = m_fBrake;
630  jointState.m_fSlew = m_fSlew;
631 
632  // add state
633  jointStatePoint.append(jointState);
634  }
635 
636  return KUON_OK;
637 }
638 
639 int KuonRobot::getTrajectoryState(KuonWheelTrajectoryFeedback &trajFeedback)
640 {
641  // TBD
642 
643  trajFeedback.clear();
644 
645  return KUON_OK;
646 }
647 
648 int KuonRobot::convertSpecs()
649 {
650  KuonDescBase *pDescBase;
651  KuonSpecMotor_T *pSpecMotor;
652  KuonRobotJoint *pMotor;
653  int i;
654  int rc;
655 
656  m_kinBase.clear();
657  m_imapBase.clear();
658 
659  pDescBase = m_descKuon.getBaseDesc();
660 
661  //
662  // Build up base kinematic chain.
663  //
664  for(i = 0; i < pDescBase->getNumMotors(); ++i)
665  {
666  // joint specification
667  pSpecMotor = pDescBase->m_spec.getMotorSpecAt(i);
668 
669  // add robotic 'joint'
670  if( (rc = addRobotJoint(pSpecMotor, m_kinBase, m_imapBase)) < 0 )
671  {
672  LOGERROR("Motor %d: Cannot add to kinematic chain.",
673  pSpecMotor->m_nMotorId);
674  return rc;
675  }
676  }
677 
678  return KUON_OK;
679 }
680 
681 int KuonRobot::addRobotJoint(KuonSpecMotor_T *pSpecMotor,
682  MapRobotJoints &kin,
683  IMapRobotJoints &imap)
684 {
685  int nMotorId; // master servo id
686  KuonRobotJoint joint; // robotic joint
687 
688  // master servo id associated with joint
689  nMotorId = pSpecMotor->m_nMotorId;
690 
691  //
692  // Populate joint data.
693  //
694  joint.m_strName = pSpecMotor->m_strName;
695  joint.m_nMotorId = nMotorId;
696  joint.m_nMotorCtlrId = pSpecMotor->m_nMotorCtlrId;
697  joint.m_nMotorIndex = pSpecMotor->m_nMotorIndex;
698  joint.m_nMotorDir = pSpecMotor->m_nDir;
700  joint.m_fGearRatio = pSpecMotor->m_fGearRatio;
701  joint.m_fTireRadius = pSpecMotor->m_fTireRadius;
702  joint.m_fTicksPerMotorRad = 0.0;
703  joint.m_fTicksPerWheelRad = 0.0;
704 
705  //
706  // Sanity checks.
707  //
708 
709  //
710  // Add to kinematic chain.
711  //
712  kin[nMotorId] = joint; // kinematic chain
713  imap[joint.m_strName] = nMotorId; // indirect map by joint name
714 
715  return KUON_OK;
716 }
717 
718 int KuonRobot::configForOperation()
719 {
720  m_eRobotMode = KuonRobotModeAuto;
721  m_bIsEStopped = false;
722  m_bAlarmState = false;
723  m_fBattery = 0.0;
724  m_fBrake = BrakeDft;
725  m_fSlew = SlewDft;
726  m_nSetPtSpeedLeft = 0;
727  m_nSetPtSpeedRight = 0;
728 
729  setGovernor(GovernorDft);
730  setBrake(BrakeDft);
731  setSlew(SlewDft);
732  setSpeed(0.0, 0.0);
733 
734  return KUON_OK;
735 }
736 
737 int KuonRobot::createAsyncThread()
738 {
739  int rc;
740 
741  m_eAsyncTaskState = KuonAsyncTaskStateWorking;
742 
743  rc = pthread_create(&m_threadAsync, NULL, KuonRobot::asyncThread, (void*)this);
744 
745  if( rc == 0 )
746  {
747  rc = KUON_OK;
748  }
749 
750  else
751  {
752  m_eAsyncTaskState = KuonAsyncTaskStateIdle;
753  LOGSYSERROR("pthread_create()");
754  m_rcAsyncTask = -KUON_ECODE_SYS;
755  m_eAsyncTaskId = AsyncTaskIdNone;
756  m_pAsyncTaskArg = NULL;
757  rc = m_rcAsyncTask;
758  }
759 
760  return rc;
761 }
762 
763 
764 void KuonRobot::cancelAsyncTask()
765 {
766  MapRobotJoints::iterator iter;
767 
768  if( m_eAsyncTaskState != KuonAsyncTaskStateIdle )
769  {
770  // cancel thread
771  pthread_cancel(m_threadAsync);
772  pthread_join(m_threadAsync, NULL);
773 
774  // cleanup
775  switch( m_eAsyncTaskId )
776  {
777  default:
778  break;
779  }
780 
781  // clear state
782  m_eAsyncTaskId = AsyncTaskIdNone;
783  m_pAsyncTaskArg = NULL;
784  m_rcAsyncTask = -KUON_ECODE_INTR;
785  m_eAsyncTaskState = KuonAsyncTaskStateIdle;
786  LOGDIAG3("Async task canceled.");
787  }
788 }
789 
790 void *KuonRobot::asyncThread(void *pArg)
791 {
792  KuonRobot *pThis = (KuonRobot *)pArg;
793  int oldstate;
794  int rc;
795 
796  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
797  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
798  //pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate);
799 
800  LOGDIAG3("Async robot task thread created.");
801 
802  //
803  // Execute asychronous task.
804  //
805  // For now, only calibrate task is supported asynchronously.
806  //
807  switch( pThis->m_eAsyncTaskId )
808  {
809  // Unknown task id.
810  default:
811  LOGERROR("Unknown async task id = %d.", (int)pThis->m_eAsyncTaskId);
812  rc = -KUON_ECODE_BAD_VAL;
813  break;
814  }
815 
816  // freeze robot at current calibrated or aborted position.
817  //pThis->freeze(); disable, so that goto zero pt in calibration finsishes
818 
819  pThis->m_eAsyncTaskId = AsyncTaskIdNone;
820  pThis->m_pAsyncTaskArg = NULL;
821  pThis->m_rcAsyncTask = rc;
823 
824  LOGDIAG3("Async robot task thread exited.");
825 
826  return NULL;
827 }
KuonTriState m_eIsMotionPossible
motion is [not] possible
Definition: kuonStatus.h:152
double m_fTicksPerMotorRad
encoder/odom. ticks per motor radian
Definition: kuonJoint.h:140
int m_nMotorIndex
motor controller unique motor index
Definition: kuonSpec.h:138
std::string m_strName
joint name
Definition: kuonJoint.h:132
KuonTriState m_eAreDrivesPowered
motor are [not] powered
Definition: kuonStatus.h:151
std::map< std::string, int > IMapRobotJoints
Indirect map of robot joints.
Definition: kuonRobot.h:111
double m_fVelocityMps
current wheel velocity (meters/second)
Definition: kuonJoint.h:195
std::string m_strName
motor joint name
Definition: kuonJoint.h:188
KuonSpec m_spec
fixed specification
Definition: kuonDescBase.h:221
Kuon common utilities.
double m_fPosition
current joint position (radians)
Definition: kuonJoint.h:190
static const int KUON_OK
not an error, success
Definition: kuon.h:80
int getNumMotors()
Get the number of expected and required motors.
Definition: kuonDescBase.h:176
uint_t m_uAlarms
motor alarms
Definition: kuonStatus.h:99
#define KUON_TRY_CONN()
Test for connection.
Definition: kuonRobot.cxx:106
float m_fGovernor
speed limiting governor (0-1)
Definition: kuonStatus.h:156
Kuon robotic mobile base escription class.
Definition: kuonDescBase.h:79
int m_nMotorIndex
motor controller unique motor index
Definition: kuonJoint.h:135
float m_fVoltage
motor voltage (volts)
Definition: kuonStatus.h:98
KuonTriState m_eIsInMotion
robot is [not] moving
Definition: kuonStatus.h:153
idle, no async task running
Definition: kuon.h:376
void append(const KuonJointState &jointState)
Append joint state to end of joint state point.
Definition: kuonJoint.h:302
double m_fGearRatio
motor gear ratio
Definition: kuonSpec.h:139
Kuon robotic manipulator plus accesories class.
Definition: kuonRobot.h:83
void * m_pAsyncTaskArg
asynchronous argument
Definition: kuonRobot.h:668
static const int KUON_ECODE_BAD_VAL
bad value general error
Definition: kuon.h:85
float m_fSlew
current motor power slewing (normalized)
Definition: kuonJoint.h:200
int m_nMotorId
motor id
Definition: kuonStatus.h:96
Kuon Robot Status classes interfaces.
Wheel trajectory point class.
Definition: kuonTraj.h:186
double m_fTicksPerWheelRad
encoder/odom. ticks per wheel radian
Definition: kuonJoint.h:141
The <b><i>Kuon</i></b> namespace encapsulates all <b><i>Kuon</i></b> related constructs.
Definition: kuon.h:66
double m_fGearRatio
joint gear ratio
Definition: kuonJoint.h:138
float m_fTemperature
motor temperature (Celsius)
Definition: kuonStatus.h:97
int m_nMotorCtlrId
motor controller id
Definition: kuonJoint.h:134
float m_fBrake
current motor braking (normalized)
Definition: kuonJoint.h:199
async task running
Definition: kuon.h:377
std::map< int, KuonRobotJoint > MapRobotJoints
Map of robot joints.
Definition: kuonRobot.h:101
Robotic motor specification.
Definition: kuonSpec.h:111
void setKinematicChainName(std::string strKinName)
Set the kinematic chain name.
Definition: kuonJoint.h:273
Kuon Robot Joint class interfaces.
AsyncTaskId m_eAsyncTaskId
asynchronous task id
Definition: kuonRobot.h:667
int m_nMotorDir
motor normalized direction
Definition: kuonJoint.h:136
int m_eJointType
joint type
Definition: kuonJoint.h:137
int m_nSpeed
current raw speed
Definition: kuonJoint.h:196
int m_nErrorCode
kuon error code
Definition: kuonStatus.h:155
double m_fPm
current motor output mechanical power (W)
Definition: kuonJoint.h:198
static const int KUON_ECODE_SYS
system (errno) error
Definition: kuon.h:83
int m_nMotorId
motor id
Definition: kuonJoint.h:133
int m_rcAsyncTask
last async task return code
Definition: kuonRobot.h:666
<b><i>Kuon</i></b> product specification base classes.
KuonTriState m_eIsEStopped
robot is [not] emergency stopped
Definition: kuonStatus.h:150
int icap(int a, int min, int max)
Cap value within limits [min, max].
Definition: kuonUtils.h:154
RoadNarrows Kuon robot top-level header file.
void clear()
Clear all state data.
Definition: kuonJoint.h:337
void clear()
Clear data.
Definition: kuonStatus.cxx:131
#define KUON_TRY_NO_EXEC()
Test for no execute flag.
Definition: kuonRobot.cxx:89
double m_fPe
current motor input electrical power (W)
Definition: kuonJoint.h:197
float m_fBattery
current battery energy (Wh)
Definition: kuonStatus.h:157
Trajectory classes interfaces.
static const int KUON_ECODE_MOT_CTLR
motor controller error
Definition: kuon.h:97
Kuon full robotic mobile platform descripition class interface.
std::string getRealDeviceName(const std::string &strDevName)
Get real device name.
#define KUON_TRY_NOT_ESTOP()
Test for not estop.
Definition: kuonRobot.cxx:124
KuonSpecMotor_T * getMotorSpecAt(int index)
Get motor spec at the given index.
Definition: kuonSpec.h:221
int m_nMotorCtlrId
motor controller id
Definition: kuonSpec.h:137
int m_nEncoder
current motor encoder position (ticks)
Definition: kuonJoint.h:194
int m_nDir
normalize cw/ccw direction.
Definition: kuonSpec.h:141
VecHealth m_vecMotorHealth
motors&#39; health
Definition: kuonStatus.h:158
static const int KUON_ECODE_ALARMED
robot is alarmed
Definition: kuon.h:103
double m_fOdometer
current wheel odometer reading (meters)
Definition: kuonJoint.h:193
Operational robotic joint class.
Definition: kuonJoint.h:83
Joint state point class.
Definition: kuonJoint.h:217
double fcap(double a, double min, double max)
Cap value within limits [min, max].
Definition: kuonUtils.h:140
Robot global status.
Definition: kuonStatus.h:110
int m_nMotorId
robot unique robot motor id
Definition: kuonSpec.h:136
void clear()
Clear data.
Definition: kuonTraj.h:403
std::string m_strName
motor name
Definition: kuonStatus.h:95
int m_nMotorId
motor id
Definition: kuonJoint.h:189
KuonRobotMode m_eRobotMode
robot operating mode
Definition: kuonStatus.h:149
double m_fTireRadius
tire radius
Definition: kuonJoint.h:139
Joint state class.
Definition: kuonJoint.h:159
static const int KUON_ECODE_ESTOP
robot emergency stopped
Definition: kuon.h:106
continuous rotation
Definition: kuonSpec.h:80
static const int KUON_ECODE_INTR
operation interrupted
Definition: kuon.h:104
KuonAsyncTaskState m_eAsyncTaskState
asynchronous task state
Definition: kuonRobot.h:665
std::string m_strName
motor name
Definition: kuonSpec.h:135
double m_fVelocity
current joint velocity (radians/second)
Definition: kuonJoint.h:191
double m_fTireRadius
tire radius (mm)
Definition: kuonSpec.h:140
static const int KUON_ECODE_BAD_OP
invalid operation error
Definition: kuon.h:89
KuonTriState m_eIsInError
robot is [not] in error condition
Definition: kuonStatus.h:154
Wheel trajectory feedback class.
Definition: kuonTraj.h:319
double m_fEffort
current joint torque (N-m)
Definition: kuonJoint.h:192
Kuon Robot Class interface.
fully available
Definition: kuon.h:368
Robot motor health.
Definition: kuonStatus.h:66