/*
Adept MobileRobots Robotics Interface for Applications (ARIA)
Copyright (C) 2004, 2005 ActivMedia Robotics LLC
Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc.
Copyright (C) 2011, 2012, 2013 Adept Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
If you wish to redistribute ARIA under different terms, contact
Adept MobileRobots for information about a commercial version of ARIA at
robots@mobilerobots.com or
Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960
*/
#ifndef ARMTXIO_H
#define ARMTXIO_H
#include "ariaTypedefs.h"
#include "ArRobot.h"
/** @brief Interface to digital and analog I/O and switched power outputs on MTX
* core (used in Pioneer LX and other MTX-based robots).
On Linux this class uses the mtx
driver to interface with the
MTX digital and analog IO, and control switched power outputs.
The mtx
driver module must be loaded for this interface to work.
The mtx
interface (/dev/mtx
) is opened automatically
in the ArMTXIO constructor. If successful, isEnabled() will then return true.
The MTX IO is organized as two sets of 8-bit "banks" of inputs, and two 8-bit
"banks" of outputs.
To read the state input, use getDigitalIOInputMon1() and
getDigitalIOInputMon2(), or getDigitalBankInputs() with bank index 0 or 1.
To set state of output, use setDigitalOutputControl1() and
setDigitalOutputControl2(), or setDigitalBankOutputs() with bank index 2 or
3.
Multile ArMTXIO objects may be instatiated; a shared may be
locked and unlocked by calling lock() and unlock().
@ingroup OptionalClasses
@ingroup DeviceClasses
@ingroup MTX
@linuxonly
*/
class ArMTXIO
{
public:
enum Direction
{
DIGITAL_INPUT,
DIGITAL_OUTPUT,
INVALID
};
/// Constructor
AREXPORT ArMTXIO(const char * dev = "/dev/mtx");
/// Destructor
AREXPORT virtual ~ArMTXIO(void);
/// tries to close the device. Returns false if operation failed
AREXPORT bool closeIO(void);
/// returns true if the device is opened and operational
bool isEnabled(void) { return myEnabled; }
/// returns true if analog values are supported
AREXPORT bool isAnalogSupported(void) { return myAnalogEnabled; }
/// @note not yet implemented.
bool getAnalogValue(int port, double *val) { return true; }
/// @note not yet implemented
bool getAnalogValueRaw(int port, int *val) { return true; }
/// Get/set value of digital IO banks (see class description above)
/// Banks are 0-indexed.
/// @{
AREXPORT Direction getDigitalBankDirection(int bank);
AREXPORT bool setDigitalBankOutputs(int bank, unsigned char val);
AREXPORT bool getDigitalBankInputs(int bank, unsigned char *val);
AREXPORT bool getDigitalBankOutputs(int bank, unsigned char *val);
/// @}
/// Set one bit of an output bank. @a bank and @a bit are 0-indexed.
bool setDigitalOutputBit(int bank, int bit) {
unsigned char val;
if(!getDigitalBankOutputs(bank, &val))
return false;
return setDigitalBankOutputs( bank, val | (1 << bit) );
}
/// Get one bit of an input bank. @a bank and @a bit are 0-indexed.
bool getDigitalInputBit(int bank, int bit) {
unsigned char val = 0;
getDigitalBankInputs(bank, &val);
return val & (1 << bit);
}
/// get/set value of power output controls (see robot manual for information
/// on what components and user outputs are controlled). Banks are 0-indexed.
/// @{
AREXPORT bool setPeripheralPowerBankOutputs(int bank, unsigned char val);
AREXPORT bool getPeripheralPowerBankOutputs(int bank, unsigned char *val);
/// @}
/// Set one power output. @a bank and @a bit are 0-indexed.
bool setPowerOutput(int bank, int bit, bool on) {
unsigned char val = 0;
if(!getPeripheralPowerBankOutputs(bank, &val))
return false;
if (on)
return setPeripheralPowerBankOutputs(bank, val & (1 << bit));
else
return setPeripheralPowerBankOutputs(bank, val ^ (1 << bit));
}
/// Lock global (shared) mutex for all ArMTXIO instances.
/// This allows multiple access to MTX IO (through multiple ArMTXIO objects).
AREXPORT int lock(void){ return(ourMutex.lock()); }
/// Unlock global (shared) mutex for all ArMTXIO instances.
/// This allows multiple access to MTX IO (through multiple ArMTXIO objects).
AREXPORT int unlock(void){ return(ourMutex.unlock()); }
/// Try to lock without blocking (see ArMutex::tryLock())
AREXPORT int tryLock() {return(ourMutex.tryLock());}
/// gets the Firmware Revision
AREXPORT unsigned char getFirmwareRevision()
{ return myFirmwareRevision; }
/// gets the Firmware Version
AREXPORT unsigned char getFirmwareVersion()
{ return myFirmwareVersion; }
/// gets the Compatibility Code
AREXPORT unsigned char getCompatibilityCode()
{ return myCompatibilityCode; }
/// gets the MTX FPGA Type
AREXPORT unsigned char getFPGAType()
{ return myFPGAType; }
/// gets the values of digital input/output monitoring registers 1 & 2
/// @{
AREXPORT bool getDigitalIOInputMon1(unsigned char *val);
AREXPORT bool getDigitalIOInputMon2(unsigned char *val);
AREXPORT bool getDigitalIOOutputMon1(unsigned char *val);
AREXPORT bool getDigitalIOOutputMon2(unsigned char *val);
/// @}
/// get the Light Pole IO Output Control Register
AREXPORT bool getLightPole(unsigned char *val);
/// sets the Light Pole IO Output Control Register
AREXPORT bool setLightPole(unsigned char *val);
/// @internal
AREXPORT bool getLPCTimeUSec(ArTypes::UByte4 *timeUSec);
/// @internal
AREXPORT ArRetFunctor1 *getLPCTimeUSecCB(void)
{ return &myLPCTimeUSecCB; }
/// gets/sets the Semaphore Registers
/// @internal
//@{
AREXPORT bool setSemaphore1(unsigned char *val);
AREXPORT bool getSemaphore1(unsigned char *val);
AREXPORT bool setSemaphore2(unsigned char *val);
AREXPORT bool getSemaphore2(unsigned char *val);
AREXPORT bool setSemaphore3(unsigned char *val);
AREXPORT bool getSemaphore3(unsigned char *val);
AREXPORT bool setSemaphore4(unsigned char *val);
AREXPORT bool getSemaphore4(unsigned char *val);
//@}
/// gets the bumper Input Monitoring Reg
/// @internal
AREXPORT bool getBumperInput(unsigned char *val);
/// gets the Power Status Register
/// @internal
AREXPORT bool getPowerStatus1(unsigned char *val);
/// gets the Power Status Register 2
/// @internal
AREXPORT bool getPowerStatus2(unsigned char *val);
/// gets the LIDAR Safety Status Register
AREXPORT bool getLIDARSafety(unsigned char *val);
/// gets the ESTOP status Registers
/// @internal
//@{
AREXPORT bool getESTOPStatus1(unsigned char *val);
AREXPORT bool getESTOPStatus2(unsigned char *val);
AREXPORT bool getESTOPStatus3(unsigned char *val);
AREXPORT bool getESTOPStatus4(unsigned char *val);
/// Compares the high nibble of this byte against the passed in val, returns true if it matches
AREXPORT bool compareESTOPStatus4HighNibbleAgainst(int val);
//@}
/// gets/sets Digital IO Output Control Registers 1 & 2
//@{
AREXPORT bool getDigitalOutputControl1(unsigned char *val);
AREXPORT bool setDigitalOutputControl1(unsigned char *val);
AREXPORT bool getDigitalOutputControl2(unsigned char *val);
AREXPORT bool setDigitalOutputControl2(unsigned char *val);
//@}
/// gets/sets the Peripheral Power Control Regs 1 & 2
/// These control power to core and robot components, and to user/auxilliary
/// power outputs. Refer to robot manual for information on which components
/// and outputs are controlled by which bits in the peripheral power bitmasks.
//@{
AREXPORT bool getPeripheralPower1(unsigned char *val);
AREXPORT bool setPeripheralPower1(unsigned char *val);
AREXPORT bool getPeripheralPower2(unsigned char *val);
AREXPORT bool setPeripheralPower2(unsigned char *val);
AREXPORT bool getPeripheralPower3(unsigned char *val);
AREXPORT bool setPeripheralPower3(unsigned char *val);
//@}
/// gets the motion power status
AREXPORT bool getMotionPowerStatus(unsigned char *val);
/// gets/sets the LIDAR Control Reg
/// @internal
//@{
AREXPORT bool getLIDARControl(unsigned char *val);
AREXPORT bool setLIDARControl(unsigned char *val);
//@}
/// gets analog Block 1 & 2
//@{
AREXPORT bool getAnalogIOBlock1(int analog, unsigned short *val);
AREXPORT bool getAnalogIOBlock2(int analog, unsigned short *val);
AREXPORT bool setAnalogIOBlock2(int analog, unsigned short *val);
//@}
/// This returns a conversion of the bits to a decimal value,
/// currently assumed to be in the 0-5V range
/// @internal
AREXPORT bool getAnalogValue(double *val);
/// @internal
AREXPORT bool getAnalogValueRaw(int *val);
protected:
bool getLPCTimer0(unsigned char *val);
bool getLPCTimer1(unsigned char *val);
bool getLPCTimer2(unsigned char *val);
bool getLPCTimer3(unsigned char *val);
static ArMutex ourMutex;
int myFD;
bool myEnabled;
bool myAnalogEnabled;
unsigned char myFirmwareRevision;
unsigned char myFirmwareVersion;
unsigned char myCompatibilityCode;
unsigned char myFPGAType;
struct MTX_IOREQ{
unsigned short myReg;
unsigned short mySize;
union {
unsigned int myVal;
unsigned int myVal32;
unsigned short myVal16;
unsigned char myVal8;
//unsigned char myVal128[16];
} myData;
};
int myNumBanks;
unsigned char myDigitalBank1;
unsigned char myDigitalBank2;
unsigned char myDigitalBank3;
unsigned char myDigitalBank4;
ArRetFunctorC myDisconnectCB;
ArRetFunctor1C myLPCTimeUSecCB;
};
//#endif // SWIG
#endif // ARMTXIO_H