64 #include "rnr/rnrconfig.h" 65 #include "rnr/units.h" 68 #include "Kuon/RS160DControl.h" 89 #define KUON_TRY_NO_EXEC() \ 106 #define KUON_TRY_CONN() \ 109 if( !isConnected() ) \ 111 LOGERROR("Robot is not connected."); \ 112 return -KUON_ECODE_NO_EXEC; \ 124 #define KUON_TRY_NOT_ESTOP() \ 127 if( m_bIsEStopped ) \ 129 LOGERROR("Robot is emergency stopped."); \ 130 return -KUON_ECODE_NO_EXEC; \ 139 const float KuonRobot::GovernorDft = 0.20;
140 const float KuonRobot::BrakeDft = 0.20;
141 const float KuonRobot::SlewDft = 0.10;
143 KuonRobot::KuonRobot(
bool bNoExec)
148 m_bIsEStopped =
false;
149 m_bAlarmState =
false;
153 m_nSetPtSpeedLeft = 0;
154 m_nSetPtSpeedRight = 0;
156 setGovernor(GovernorDft);
165 m_eAsyncTaskId = AsyncTaskIdNone;
166 m_pAsyncTaskArg = NULL;
169 KuonRobot::~KuonRobot()
174 int KuonRobot::connect(
const std::string &strDevMotorCtlr0,
175 const std::string &strDevMotorCtlr1,
176 int nBaudRateMotorCtlr)
185 if( !m_descKuon.isDescribed() )
187 LOGERROR(
"Undefined Kuon description - " 188 "don't know how to initialized properly.");
201 LOGDIAG2(
"Waiting for motor controllers to power-up");
207 if( RS160DOpenConnection(strDevName0.c_str(), &m_fdMotorCtlr0) < 0 )
209 LOGERROR(
"%s: Failed to open motor controller 0.", strDevName0.c_str());
216 else if( RS160DSetToSerial(m_fdMotorCtlr0) < 0 )
218 LOGERROR(
"%s: Failed to configure motor controller 0.",
219 strDevName0.c_str());
226 if( RS160DOpenConnection(strDevName1.c_str(), &m_fdMotorCtlr1) < 0 )
228 LOGERROR(
"%s: Failed to open motor controller 1.", strDevName1.c_str());
235 else if( RS160DSetToSerial(m_fdMotorCtlr1) < 0 )
237 LOGERROR(
"%s: Failed to configure motor controller 1.",
238 strDevName1.c_str());
245 else if( (rc = convertSpecs()) < 0 )
247 LOGERROR(
"Failed to convert product specifications to " 248 "operational parameters.");
254 else if( (rc = configForOperation()) < 0 )
256 LOGERROR(
"Failed to configure for operation.");
262 LOGDIAG1(
"Connected to Kuon with controllers = (%s, %s).",
263 strDevMotorCtlr0.c_str(), strDevMotorCtlr1.c_str());
277 int KuonRobot::disconnect()
279 bool bWasConn =
false;
284 RS160DEStop(m_fdMotorCtlr0, m_fdMotorCtlr1);
287 if( m_fdMotorCtlr0 >= 0 )
289 RS160DClose(m_fdMotorCtlr0);
293 if( m_fdMotorCtlr1 >= 0 )
295 RS160DClose(m_fdMotorCtlr1);
301 LOGDIAG1(
"Disconnected from Kuon.");
307 int KuonRobot::estop()
312 RS160DEStop(m_fdMotorCtlr0, m_fdMotorCtlr1);
316 m_bIsEStopped =
true;
317 m_bAlarmState =
true;
319 m_lastTrajBase.clear();
321 LOGDIAG3(
"Kuon emergency stopped.");
326 int KuonRobot::freeze()
331 m_lastTrajBase.clear();
339 LOGDIAG3(
"Kuon frozen at current position.");
344 int KuonRobot::release()
349 m_lastTrajBase.clear();
357 LOGDIAG3(
"Kuon servo drives released.");
362 int KuonRobot::clearAlarms()
369 int KuonRobot::setBrake(
float fBrake)
376 fBrake = (float)
fcap(fBrake, 0.0, 1.0);
378 raw = RS160D_MOTOR_BRAKE_MAX * fBrake;
379 raw =
icap(raw, RS160D_MOTOR_BRAKE_MIN, RS160D_MOTOR_BRAKE_MAX);
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);
388 m_bAreMotorsPowered = m_fBrake > 0.0?
true:
false;
390 LOGDIAG3(
"Brakes set to %3.1f (raw=%d).", m_fBrake, raw);
395 int KuonRobot::setSlew(
float fSlew)
402 fSlew = (float)
fcap(fSlew, 0.0, 1.0);
404 raw = RS160D_MOTOR_SLEW_MAX * fSlew;
405 raw =
icap(raw, RS160D_MOTOR_SLEW_MIN, RS160D_MOTOR_SLEW_MAX);
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);
414 LOGDIAG3(
"Power slew set to %3.1f (raw=%d).", m_fSlew, raw);
419 int KuonRobot::setSpeed(
double fSpeedLeft,
double fSpeedRight, units_t units)
427 rawLeft = velocityToRawSpeed(fSpeedLeft, units);
428 rawRight = velocityToRawSpeed(fSpeedRight, units);
430 rawLeft =
icap(rawLeft, m_nGovernSpeedMin, m_nGovernSpeedMax);
431 rawRight =
icap(rawRight, m_nGovernSpeedMin, m_nGovernSpeedMax);
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);
438 m_nSetPtSpeedLeft = rawLeft;
439 m_nSetPtSpeedRight = rawRight;
441 LOGDIAG3(
"Speed raw_left=%d, raw_right=%d.", rawLeft, rawRight);
452 int KuonRobot::velocityToRawSpeed(
double fVelocity, units_t units)
458 return (
int)(RS160D_MOTOR_SPEED_MAX *
fcap(fVelocity, -1.0, 1.0));
462 return (
int)(RS160D_MOTOR_SPEED_MAX *
463 fcap(fVelocity, -100.0, 100.0)/100.0);
467 return (
int)(RS160D_MOTOR_SPEED_MAX *
468 fcap(fVelocity, -1000.0, 1000.0)/1000.0);
472 return (
int)
fcap(fVelocity,
473 RS160D_MOTOR_SPEED_MIN, RS160D_MOTOR_SPEED_MAX);
476 case units_rad_per_s:
478 LOGWARN(
"%s velocity units not supported until encoders installed.",
479 units_shortname(units));
484 LOGWARN(
"%s velocity units not supported.", units_shortname(units));
489 void KuonRobot::getVelocitySetPoints(
double &fSpeedLeft,
497 fSpeedLeft = (double)m_nSetPtSpeedLeft / (
double)RS160D_MOTOR_SPEED_MAX;
498 fSpeedRight = (double)m_nSetPtSpeedRight / (
double)RS160D_MOTOR_SPEED_MAX;
503 fSpeedLeft = (double)m_nSetPtSpeedLeft / (
double)RS160D_MOTOR_SPEED_MAX;
504 fSpeedRight = (double)m_nSetPtSpeedRight / (
double)RS160D_MOTOR_SPEED_MAX;
506 fSpeedRight *= 100.0;
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;
520 fSpeedLeft = (double)m_nSetPtSpeedLeft;
521 fSpeedRight = (double)m_nSetPtSpeedRight;
528 MapRobotJoints::iterator iter;
565 for(iter = m_kinBase.begin(); iter != m_kinBase.end(); ++iter)
567 health.
m_strName = iter->second.m_strName;
581 MapRobotJoints::iterator iter;
590 jointStatePoint.
clear();
597 for(iter = m_kinBase.begin(); iter != m_kinBase.end(); ++iter)
599 nMotorId = iter->first;
600 pMotor = &(iter->second);
616 jointState.
m_nSpeed = m_nSetPtSpeedLeft;
620 jointState.
m_nSpeed = m_nSetPtSpeedRight;
625 jointState.
m_fPe = 0.0;
626 jointState.
m_fPm = 0.0;
633 jointStatePoint.
append(jointState);
643 trajFeedback.
clear();
648 int KuonRobot::convertSpecs()
659 pDescBase = m_descKuon.getBaseDesc();
670 if( (rc = addRobotJoint(pSpecMotor, m_kinBase, m_imapBase)) < 0 )
672 LOGERROR(
"Motor %d: Cannot add to kinematic chain.",
712 kin[nMotorId] = joint;
718 int KuonRobot::configForOperation()
721 m_bIsEStopped =
false;
722 m_bAlarmState =
false;
726 m_nSetPtSpeedLeft = 0;
727 m_nSetPtSpeedRight = 0;
729 setGovernor(GovernorDft);
737 int KuonRobot::createAsyncThread()
743 rc = pthread_create(&m_threadAsync, NULL, KuonRobot::asyncThread, (
void*)
this);
753 LOGSYSERROR(
"pthread_create()");
755 m_eAsyncTaskId = AsyncTaskIdNone;
756 m_pAsyncTaskArg = NULL;
764 void KuonRobot::cancelAsyncTask()
766 MapRobotJoints::iterator iter;
771 pthread_cancel(m_threadAsync);
772 pthread_join(m_threadAsync, NULL);
775 switch( m_eAsyncTaskId )
782 m_eAsyncTaskId = AsyncTaskIdNone;
783 m_pAsyncTaskArg = NULL;
786 LOGDIAG3(
"Async task canceled.");
790 void *KuonRobot::asyncThread(
void *pArg)
796 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
797 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
800 LOGDIAG3(
"Async robot task thread created.");
811 LOGERROR(
"Unknown async task id = %d.", (
int)pThis->
m_eAsyncTaskId);
824 LOGDIAG3(
"Async robot task thread exited.");
KuonTriState m_eIsMotionPossible
motion is [not] possible
double m_fTicksPerMotorRad
encoder/odom. ticks per motor radian
int m_nMotorIndex
motor controller unique motor index
std::string m_strName
joint name
KuonTriState m_eAreDrivesPowered
motor are [not] powered
std::map< std::string, int > IMapRobotJoints
Indirect map of robot joints.
double m_fVelocityMps
current wheel velocity (meters/second)
std::string m_strName
motor joint name
KuonSpec m_spec
fixed specification
double m_fPosition
current joint position (radians)
static const int KUON_OK
not an error, success
int getNumMotors()
Get the number of expected and required motors.
uint_t m_uAlarms
motor alarms
#define KUON_TRY_CONN()
Test for connection.
float m_fGovernor
speed limiting governor (0-1)
Kuon robotic mobile base escription class.
int m_nMotorIndex
motor controller unique motor index
float m_fVoltage
motor voltage (volts)
KuonTriState m_eIsInMotion
robot is [not] moving
idle, no async task running
void append(const KuonJointState &jointState)
Append joint state to end of joint state point.
double m_fGearRatio
motor gear ratio
Kuon robotic manipulator plus accesories class.
void * m_pAsyncTaskArg
asynchronous argument
static const int KUON_ECODE_BAD_VAL
bad value general error
float m_fSlew
current motor power slewing (normalized)
Kuon Robot Status classes interfaces.
Wheel trajectory point class.
double m_fTicksPerWheelRad
encoder/odom. ticks per wheel radian
The <b><i>Kuon</i></b> namespace encapsulates all <b><i>Kuon</i></b> related constructs.
double m_fGearRatio
joint gear ratio
float m_fTemperature
motor temperature (Celsius)
int m_nMotorCtlrId
motor controller id
float m_fBrake
current motor braking (normalized)
std::map< int, KuonRobotJoint > MapRobotJoints
Map of robot joints.
Robotic motor specification.
void setKinematicChainName(std::string strKinName)
Set the kinematic chain name.
Kuon Robot Joint class interfaces.
AsyncTaskId m_eAsyncTaskId
asynchronous task id
int m_nMotorDir
motor normalized direction
int m_eJointType
joint type
int m_nSpeed
current raw speed
int m_nErrorCode
kuon error code
double m_fPm
current motor output mechanical power (W)
static const int KUON_ECODE_SYS
system (errno) error
int m_rcAsyncTask
last async task return code
<b><i>Kuon</i></b> product specification base classes.
KuonTriState m_eIsEStopped
robot is [not] emergency stopped
int icap(int a, int min, int max)
Cap value within limits [min, max].
RoadNarrows Kuon robot top-level header file.
void clear()
Clear all state data.
#define KUON_TRY_NO_EXEC()
Test for no execute flag.
double m_fPe
current motor input electrical power (W)
float m_fBattery
current battery energy (Wh)
Trajectory classes interfaces.
static const int KUON_ECODE_MOT_CTLR
motor controller error
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.
KuonSpecMotor_T * getMotorSpecAt(int index)
Get motor spec at the given index.
int m_nMotorCtlrId
motor controller id
int m_nEncoder
current motor encoder position (ticks)
int m_nDir
normalize cw/ccw direction.
VecHealth m_vecMotorHealth
motors' health
static const int KUON_ECODE_ALARMED
robot is alarmed
double m_fOdometer
current wheel odometer reading (meters)
Operational robotic joint class.
double fcap(double a, double min, double max)
Cap value within limits [min, max].
int m_nMotorId
robot unique robot motor id
std::string m_strName
motor name
KuonRobotMode m_eRobotMode
robot operating mode
double m_fTireRadius
tire radius
static const int KUON_ECODE_ESTOP
robot emergency stopped
static const int KUON_ECODE_INTR
operation interrupted
KuonAsyncTaskState m_eAsyncTaskState
asynchronous task state
std::string m_strName
motor name
double m_fVelocity
current joint velocity (radians/second)
double m_fTireRadius
tire radius (mm)
static const int KUON_ECODE_BAD_OP
invalid operation error
KuonTriState m_eIsInError
robot is [not] in error condition
Wheel trajectory feedback class.
double m_fEffort
current joint torque (N-m)
Kuon Robot Class interface.