1. Introduction

  You can access ARIA at different levels, from simply sending commands to the robot through ArRobot to development of higher-level intelligent behavior using Actions. (For a description of how to integrate parts of ARIA with your other code, see Piecemeal Use of ARIA.)
    An auxiliary library called ArNetworking is also included with ARIA. ArNetworking provides an easy to use, extensible framework for communication with remote programs over a network, such as MobileEyes.

  Click a class or function link to view its details. A selection of the most important ARIA classes is listed in Important Classes in the menu to the left, as well as Optional ClassesDevice Interface ClassesUtility Classes and Predefined ArAction Classes

   Important Classes:

These classes are essential far all programs using Aria to control a robot. More...

class   ArArgumentBuilder

This class is to build arguments for things that require argc and argv. More...
class   ArArgumentParser

Parse(解析) and store program command-line arguments for use by other ARIA classes. More...
class   ArFunctor

An object which allows storing a generalized reference to a method with an object instance to call later (used for callback functions) More...
一种对象,它允许将一个广义引用存储到对象实例之后调用的方法
class   Aria

Contains global initialization, deinitialization and other global functions. More...
   
class   ArLog

Logging utility class. More...
class   ArRangeDevice

The base class for all sensing devices which return range information from the device (mounted on a robot) to an object in the environment. More...
class   ArRobot

Central class for communicating with and operating the robot. More...
class   ArRobotConnector

Connect to robot or simulator based on program command line parameters. More...
class   ArSonarDevice

Keep track of recent sonar readings from a robot as an ArRangeDeviceMore...
class   ArUtil

Contains various utility functions, including cross-platform wrappers(封装) around common system functions. More...
  
   class   ArLaser

ArRangeDevice interface specialized for laser rangefinder sensors; see ArRangeDevice for more data access methods. More...
class   ArLaserConnector

Create laser interface objects (for any kind of laser supported by ARIA) and connect to lasers based on parameters from robot parameter file and command-line arguments. More...

2. Robot Communication

  

 ArRobotConnector also parses some command line arguments if supplied, which can explicitly specify a remote hostname and/or port to connect with via TCP, or to specify an alternate local serial port to use for robot connection, as well as other options. If a program uses ArRobotConnector, running it with the "-help" command line argument will print a list of options.


3. Specifying Details about Robot and Device Connections

    The device interface and connector classes (ArRobotConnectorArLaserConnector, etc.) need information about what devices are connected and how they are connected, especially if they vary from their defaults.

    This information is obtained from two sources: ARIA's parameter file(s) for the robot, and from program runtime arguments via ArArgumentParser (which reads default program argument values from /etc/Aria.args (on Linux) and the ARIAARGS environment variable (on both Linux and Windows), then reads current program arguments from the command line).

     Furthermore, if you are connecting to a robot over a wireless TCP connection from an offboard computer rather than an onboard computer, you must provide a runtime command line argument giving the robot network name (and optionally port number).

    Arguments are provided to other ARIA classes by an ArArgumentParser object. 

(1)All ARIA programs should create an ArArgumentParser, call ArArgumentParser::loadDefaultArguments() to load any arguments that appear in the /etc/Aria.args file or ARIAARGS environment variable, and provide that object to any class constructors that accept it. 

(2)Once all such objects are created, you can call Aria::logOptions() to print out a summary of all relevant options

 e.g. call Aria::logOptions(); and Aria::exit() if ArArgumentParser::checkHelpAndWarnUnparsed() returns true, because the user gave the --help option. 

       Finally, call Aria::parseArgs() to cause each of them to check the ArArgumentParser for their respective arguments.

    Here is an example which uses ArRobotConnector to connect the ArRobot and ArLaserConnector to connect to a laser rangefinder.

#include "Aria.h"
int main(int argc, char** argv)
{
  Aria::init();
  ArArgumentParser parser(&argc, argv);
  parser.loadDefaultArguments();
  ArRobot robot;
  ArRobotConnector robotConnector(&parser, &robot);

  // Try connecting to the robot.
  if(!robotConnector.connectRobot(&robot))
  {
    // Error!
    ArLog::log(ArLog::Terse, "Error, could not connect to robot.\n");
    robotConnector.logOptions();
    Aria::exit(1);
  }

  // Run the ArRobot processing/task cycle thread.
  robot.runAsync(true);

  ArLaserConnector laserConnector(&parser, &robot, &robotConnector);

  // Parse command line arguments (there may be arguments specifying 
  // what lasers to try to connect to)
  if(!Aria::parseArgs())
  {
    Aria::logOptions();
    Aria::exit(2);
  }

  // Try connecting to all lasers specified in the robot's parameter file
  // and in command line arguments
  if(!laserConnector.connectLasers())
  {
    ArLog::log(ArLog::Terse, "Error, could not connect to lasers.\n");
    Aria::logOptions();
    Aria::exit(3);
  }

  // Now we're connected, and the robot and laser objects are running in 
  // background threads reading and processing data. (You can get access
  // to the ArLaser objects using ArRobot::findLaser() or
  // ArRobot::getLaserMap().
  ...

4. ArRobot

    ArRobot (using the ArDeviceConnectionArRobotPacketReceiverArRobotPacketSenderArRobotPacket, and ArSerialConnection classes) handles the details of constructing and sending a command packets to the robot as well as receiving and decoding the packets recieved from the “robot server”(robot platform firmware).

Packet Handlers:

    Server Information Packets (SIPs) are packets sent by the robot server containing information updates about the robot and its accessories. The standard SIP is sent by the robot to a connected client automaticallyevery 100 milliseconds 毫秒(this frequency may be configured in the firmware parameters). It contains the robot's current position and estimates, current translational and rotational speeds, sonar reading updates, battery voltage, analog and digital I/O states, and more. These data are stored and used by ArRobot's State Reflection (see State Reflection below) and are accessible via methods of the ArRobot class. (Note, within the ArRobot source code the standard SIP is also called a "motor" packet.)

Command Packets:

    To control the robot platform, a client program sends command packets through the robot connection. This can be done using ArRobot's Motion Command Functions, using Actions, or at the most basic level, Direct Commands.

Robot Synchronization Cycle:


    To begin the processing cycle, call ArRobot::run() to enter the cycle synchronously, or ArRobot::runAsync() to run the cycle in a new background thread. ArRobot::stopRunning() stops the processing cycle.

    ArRobot provides methods to add your own sensor-interpretation and generic user task callbacks. To add a task callback, create an ArFunctor function object (see Functors) and then add it using ArRobot::addSensorInterpTask() or ArRobot::addUserTask(). These tasks can be removed using ArRobot::remSensorInterpTask() or ArRobot::remUserTask().

    ArRobot locks it's mutex (see ArRobot::lock() and ArRobot::unlock()) during each iteration of the task cycle, so your task callbacks must not lock this mutex--a deadlock will occur. (However, locks must still be used for safe access to any other thread or ArAsyncTask, such as lasers and other range devices, or ARNL's planning or localization tasks.) This mutex lock protects ArRobot data from modification by other threads (if they correctly use the lock during access), and interruption of the series of tasks. So if you access ArRobot from any other thread (including the main thread, if you used ArRobot::runAsync() to run the task cycle), you must use ArRobot::lock() and ArRobot::unlock() to lock and unlock the robot before and after any method call or use of any data in ArRobot.

    It is also possible to run the processing cycle without a connection to a robot, if desired. This alternative cycle is not triggered by receiving a packet, instead it has its own steady, "chained" cycle time (default is 100 milliseconds which you may examine and reset with ArRobot::getCycleTime() and ArRobot::setCycleTime()). You may also explicitly disassociate ArRobot's processing cycle from incoming SIP processing at any time by calling ArRobot::setCycleChained() ("Chained" means that it is the end of a previous cycle that triggers the next after suitable delay to meet the desired cycle frequency). However, in doing so, you may degrade performance, as the robot's cycle will only be run every ArRobot::getCycleTime() milliseconds, and each time only the most recently read (oldest) SIP is used (even if the robot has sent more than one since the last cycle).

    ArRobot's synchronization task list is ipmlemented as a tree, with five major branches. Though it is uncommon to do so, a client program may modify this tree or disable branch tasks of the tree. If a particular task is disabled, none of its children will be called. The root of the task tree can be obtained by calling ArRobot::getSyncTaskRoot(), which returns an ArSyncTask object.

    Warning:

    A user task or sensor interpretation task must run quickly. If one or more user tasks or actions runs such that the task cycle takes too long (more that 100ms) then the performance and behavior of the robot and of ARIA-robot communications will be negatively affected. In particular, do not call any functions that could block or wait for an unknown amount of time (such as locking a mutex that could be locked for a long time by another thread) or do any long loops waiting for a condition. Long-running activity can be performed in a separate asynchronous thread (See ArASyncTask) instead, and results can be shared with the user task via storage which is protected by a mutex only during immediate reading and writing of the storage variables.

    State Reflection

    State reflection in the ArRobot class is the way ARIA maintains a snapshot of the robot's operating conditions and values, such as estimated pose, current velocity, battery voltage, etc. as extracted from the latest standard SIP. ArRobot methods for examining these values include 

ArRobot::getPose()ArRobot::getX()ArRobot::getY()ArRobot::getTh(),

ArRobot::getVel()ArRobot::getRotVel()ArRobot::getBatteryVoltage()

ArRobot::isLeftMotorStalled()ArRobot::isRightMotorStalled()

ArRobot::getCompass()ArRobot::getAnalogPortSelected()ArRobot::getAnalog()ArRobot::getDigIn()ArRobot::getDigOut().

    The standard SIP also contains sonar reading updates, which are reflected in ArRobot and examined with the methods:

ArRobot::getNumSonar()ArRobot::getSonarRange()ArRobot::isSonarNew()ArRobot::getSonarReading()

ArRobot::getClosestSonarRange()ArRobot::getClosestSonarNumber()

    The sonar interface class, ArSonarDevice, also receives this information (see Range Devices).

Robot Callbacks

    There are a number of useful callbacks invoked by ArRobot on connection events. You can add and remove them with the functions 

ArRobot::addConnectCB()ArRobot::remConnectCB()ArRobot::addFailedConnectCB()ArRobot::remFailedConnectCB()

ArRobot::addDisconnectNormallyCB()ArRobot::remDisconnectNormallyCB()ArRobot::addDisconnectOnErrorCB()

ArRobot::remDisconnectOnErrorCB()ArRobot::addRunExitCB()ArRobot::remRunExitCB()

  Read their individual documentation pages for details.

   See also:   robotConnectionCallbacks::cpp


5. Controlling the robot with Commands and Actions

    Motion Command Functions:

    These are explicit simple movement commands sent by ArRobot's state reflection task. For example, ArRobot::setVel() to set the translational velocity, ArRobot::setRotVel to set rotational velocity, ArRobot::setVel2() to or set each wheel speeds separately, ArRobot::setHeading() to set a global heading angle to turn to, ArRobot::move() to drive a given distance, or ArRobot::stop() to stop all motion. ArRobot also provides methods for setting speed limits beyond the limits set in the firmware configuration. These motion functions work at part of with State Reflection, and ArRobot may resend commands each cycle to try to achieve the desired state.

     Be aware that a Direct or a Motion Command may conflict with controls from Actions or other upper-level processes and lead to unexpected consequences. Use ArRobot::clearDirectMotion() to cancel the overriding effect of a previously set Motion Command so that your Action is able to regain control the robot. Or limit the time a Motion Command prevents other motion actions with ArRobot::setDirectMotionPrecedenceTime(). Otherwise, the Motion Command will prevent actions forever. Use ArRobot::getDirectMotionPrecedenceTime() to see how long a Motion Command takes precedence once set.

   Actions:

    Actions are defined by creating a subclass of the ArAction the base class which overloads the ArAction::fire() method. See the actionExample::cpp example program. ARIA also includes some useful pre-made action classes (see Predefined ArAction Classes for a list). Include these in your programs, or use them as examples when creating your own custom ArAction subclass.

    Actions are attached to an ArRobot object with ArRobot::addAction(), along with a priority which determines its position in the action list. ArAction::setRobot() is called on an action object when it is added to a robot. You can override this in your action subclass. (For example, this would be useful to add a connection callback, if there were some calculations you wished to do upon connection to the robot.)

    Actions are evaluated by ArRobot's action resolver in descending order of priority (highest priority first, lowest priority last) in each task cycle just prior to State Reflection. The action resolver invokes each action's fire() method, combining their desired motion commands (the ArActionDesired objects they return) to a single ArActionDesired object, which is then used in state reflection to send motion commands to the robot.

   Action Desired:

     ArActionDesired objects are used to pass desired action channel values and strengths out of an ArAction::fire() method back to the resolver. An ArActionDesired object should always be reset (ArActionDesired::reset()) before it is reused.

    There are six action channels: velocity (ArActionDesired::setVel), heading (ArActionDesired::setDeltaHeading or ArActionDesired::setHeading for absolute heading), maximum forward translational velocity (ArActionDesired::setMaxVel), maximum reverse translational velocity (ArActionDesired::setMaxNegVel), and maximum rotational velocity (ArActionDesired::setMaxRotVel).

    An action gives each channel a strength between 0.0, the lowest, and 1.0, the highest. Strengths are used by the resolver to compute the relative effect of the associated channel when combining multiple actions' desired movements.

    The maximum velocity, maximum negative velocity, and maximum rotational velocity channels simply impose speed limits and thereby indirectly control the robot.

    For more advanced usage, ArActionDesired objects can be merged (ArActionDesired::merge) and averaged (ArActionDesired::startAverageArActionDesired::addAverageArActionDesired::endAverage).

The Action Resolver:

    ArResolver is the base action resolver class. ArPriorityResolver is the default resolver used by ArRobot.

The resolver used by ArRobot may be changed by calling ArRobot::setResolver, if you wish to create an alternative ArResolver implementation. There may only be one resolver per ArRobot object. (Though a resolver could contain within it multiple resolvers of its own.) Note that although a robot has one particular resolver bound to it, a resolver instance is not tied to any robot.

    The priority resolver works by iterating through the action list in descending priority (from greatest priority value to lowest), setting each robot movement channel (trans. velocity, heading, max. velocity, etc.) based on the contributing actions' desired values (as returned from their fire() methods) in proportion to their respective strengths as well as the actions' priorities, updating each movement channel until its strength becomes 1.0 or the action list is exhausted. Once a channel's accumulated strength reaches 1.0, no more changes may be made to that channel (this is how higher priority actions can prevent lower priority actions from changing a channel). Same-priority actions are averaged together if they both provide outputs for the same channel.

    As an example, the following table illustrates at each step an action's desired value and strength for the velocity channel, and the resulting change to the resolver's final velocity channel value and strength decision, for four fictional actions (A, B, C and D):

step #actionpriorityvalue of action's desired-velocity channelstrength of action's desired-velocity channelcurrent final velocity valuecurrent final velocity strength
1A4-4000.25-4000.25
2B3-1001.0Combined for use in step 4
3C32000.50
4B&C300.75-1001.0
5D15000.50no changeno change
final result  -1001.0

    Notice in the example that the same-priority actions B and C are averaged before being combined with the previously computed values from step 1. The resulting combination is: ( (B desired velocity: -100) X (B velocity strength: 1.0) + (C desired velocity: 200) X (C velocity strength: 0.5) ) / 2 => (-100 + 100) / 2 => 0 Therefore actions B and C end up cancelling each other out. Combining this result with the "currentDesired" values computed in step 1 gives (step 1 desired velocity: -400) X (step 1 velocity strength: 0.25) + (step 4 desired velocity: 0) X (step 4 velocity strength: 0.75) => -100.

    In this example, it turns out that at step 5, action D has no effect since the strength for this channel has reached 1.0 at step 4, before that action was considered by the resolver.

    The same method is used for all of the other channels.

Now learn  teleopActionsExample::cpp  and  wander::cpp

Action Groups

    Action groups allow you to easily enable (activate) or disable (de-activate) a set of actions at once. You must first create an ArActionGroup attached to an ArRobot. Then, when you add an ArAction to the ArActionGroup, it is automatically added to the ArRobot, as well as to the group.

6. Range Devices

    Range devices are connected to a specific ArRobot instance, to obtain position and other information from the robot when readings are received and stored, and also to provide a way to find all range devices attached to the robot. Some range devices use the robot connection to communicate to their device (e.g. ArSonarDeviceArBumpersArIRs). Attach an ArRangeDevice to your ArRobot object with ArRobot::addRangeDevice() and remove it with ArRobot::remRangeDevice(). The list of all attached devices can be queried using ArRobot::findRangeDevice() and ArRobot::hasRangeDevice(). The list can be obtained by calling ArRobot::getRangeDeviceList().

    ArRangeDevice also includes some methods to help find the closest reading to the robot within a selected box, or a polar sector: ArRangeDevice::currentReadingPolar()ArRangeDevice::currentReadingBox()ArRangeDevice::cumulativeReadingPolar()ArRangeDevice::cumulativeReadingBox().

    ArRobot also includes similar methods to do common operations on all attached range devices, including ArRobot::checkRangeDevicesCurrentPolar()ArRobot::checkRangeDevicesCurrentBox(), ArRobot::checkRangesDevicesCumulativePolar(), and ArRobot::checkRangeDevicesCumulativeBox() to find the closest range reading to the robot within some region.

    Each range device has a mutex 互斥锁(Use ArRangeDevice::lockDevice() and ArRangeDevice::unlockDevice() to lock and unlock it) so that it can be accessed safely by multiple threads. For example, ArLMS2xx uses a thread to read data from a laser, but the checkRangeDevice functions in ArRobot lockDevice() so they can read the data without conflicting with ArLMS2xx's data-reading thread, then use unlockDevice() when done. See Threading for more about threading in ARIA.

7. Functors

  Functor is short for function pointer. A Functor lets you call a function without knowing the declaration of the function. Instead, the compiler and linker figure out how to properly call the function.

When creating a functor object, however, you must also provide the type and instance of an object to invoke the method of; or explicitly state that the function is a class-less global function. Do this by using one of the concrete base classes of ArFunctor instead of the abstract classes: ArFunctorCArFunctor1CArFunctor2CArRetFunctorCArRetFunctor1CArRetFunctor2CArGlobalFunctorArGlobalFunctor1, etc.

Example:

    class ExampleClass {
    public:
        void aFunction(int n);
    };
  
    ...
      
    ExampleClass obj;
    ArFunctor1C<ExampleClass, int> functor(&obj, &ExampleClass::aFunction);

    ...

    functor.invoke(42);

  ExampleClass is a class which contains a function called aFunction(). The functor functor is declared as an ArFunctor1C, a functor which invokes a class method and takes one argument. The template parameters specify the type of the class (ExampleClass) and the type of the method argument (int). functor is then initialized with a pointer to the ExampleClass instance to call the method on, and a pointer to the class method to call. When a functor is contained within the class, it is typcially initialized in the constructor, giving this as the object instance.

    A functor must be initialized with the method to call and, if a "C" functor, a class instance. An unitilialized functor will crash at runtime when invoked.

    It is also possible to give values for the method arguments in the functor initialization, see ArFunctor documentation for details.

Once the functor object is created in this fashion, it can now be passed to another function or object that wants a callback functor. And the method ExampleClass::aFunction() will be called on the object obj when the functor is invoked.

    To invoke a functor, simply call the invoke() function on the functor. If it takes arguments, call invoke() with those arguments. If the functor has a return value, call invokeR. The return value of the function will be passed back through the invokeR() function. If the functor was initialized with argument values, and invoke() is called without argument values, the argument values provided at initialization are passed.

8. Keyboard and Joystick Input

    ARIA provides several classes getting live joystick and keyboard input, and action classes (see Actions) that use that input to drive the robot.

    ArJoyHandler is a cross-platform interface to joystick data. It's key functions are ArJoyHandler::getButtons, ArJoyHandler::getAdjustedArJoyHandler::setSpeeds, and ArJoyHandler::getDoubles.

    ArKeyHandler is a cross-platform interface for recieving single keystroke events (instead of buffered lines of text). It's key function is ArKeyHandler::addKeyHandler, which binds a specific key to a given functor. It contains an enum ArKeyHandler::KEY that contains values for special keys. You can also attach a key handler to a robot with ArRobot::attachKeyHandler(), which adds some default key handlers, including a handler for Escape that disconnects and exits the program (especially useful on Windows, where Ctrl-C or the terminal close box won't properly clean up). Since a PC can only have ony keyboard, ARIA keeps an ArKeyHandler pointer globally, which may be queried with Aria::getKeyHandler().

Note:
if you are using Linux, creating a key handler will make the program hang if put into the background with Ctrl-Z.

    ARIA provides two simple actions, ArActionKeydrive and ArActionJoydrive, to drive a robot from keyboard and joystick input. These actions are used by the teleopActionsExample::cpp example program. ARIA also provides a more flexible ArActionRatioInput, which can combine several input sources (such as keyboard, computer joystick, robot-platform (microcontroller) joystick, or teleoperation commands recieved via ArNetworking) in a more consistent and configurable manner. See the class documentation for more details.

9. Threading

    Thread-safe code mostly means proper coordination between threads when handling the same data. You want to avoid the problem of one or more threads reading or writing the data at the same time that other threads read or write the data. data. To prevent this problem from happening, the data needs to be protected with synchronization objects.

Thread Syncronizing Objects:

    In ARIA, the synchronization objects are ArMutex and ArConditionArMutex is the most useful one. ArMutex (mutex is short for mutual exclusion.) provides a wrapper around system calls (pthreads functions on Linux and CriticalSection functions on Windows) that exclude other threads from continuing while the mutex object is "locked". When threads lock a mutex while accessing shared data, it is ensured that only one thread is accessing that shared data at a time. 

    ArCondition is an occasionally used utility that puts the current thread to sleep until another thread signals it to wake up and continue executing. This can be used to wait in a thread for an indefinite amount of time until some event occurs in a another thread which signals the ArCondition.

10. Global Data

    The static Aria class contains miscellaneous global data in ARIA.

ARIA contains a list of all the ArRobot instances. Use the Aria::findRobot() to find a robot by name, or use Aria::getRobotList() to get a list of the robots.

    Use Aria::getDirectory() to find ARIA's top-level path (Usually either C:\Program Files\MobileRobots\Aria on Windows, or /usr/local/Aria on Linux). This is useful, for instance, to locate robot parameter files for individual operational details. Use Aria::setDirectory() to change this path for the run of the program if you feel the need to override what ARIA has decided.

    Call Aria::init() at program start to perform global initialization, and use Aria::exit() to exit all ARIA threads before exiting your program.

    The Aria class also contains global objects for sharing configuration parameters and other information: see ArConfig and Shared Info Groups sections below.

11. Maps

    In mobile robot applications, you will often need to store a map of the robot's environment to use in navigation, localization, etc. ARIA provides the ArMap class for reading map data from a file, obtaining and modifying its contents in your application, and writing it back to file. An ArMap contains data about the sensed/sensable environment (walls, obstacles, etc.), and human-provided objects such as goal points.

The Map File Format page describes the map file format in detail.

ARNL, SONARNL and MobileSim all use ArMap format map files.

12. Sockets

    The ArSocket class is a wrapper around the socket network communication layer of your operating system. ARIA mostly uses ArSocket to open a server port and to connect to another server port.

To connect to a port, simply construct a socket containing the hostname or IP address of the host, a port number, and the ARIA socket type (TCP or UDP). For example:

     ArSocket sock("host.name.com", 4040, ArSocket::TCP);

Or call the ArSocket::connect() function, such as:

     ArSocket sock;
     sock.connect("host.name.com", 4040, ArSocket::TCP);

To open a server on (for example) port 4040, simply construct a socket:

     ArSocket sock(4040, true, ArSocket::TCP);

Or call open(4040, ArSocket::TCP) on an ArSocket object constructed with the default constructor.

13. !! ArNetworking !!

For a more advanced networking infrastructure, see the ArNetworking companion library, distributed with ARIA. ArNetworking provides an extensible system of data requests and updates between client and server applications via TCP or UDP, using the same base "packet" concept as robot communication. For example, use ArNetworking to connect multiple robots working together, off-board user interfaces to on-board control servers, or robot control programs to off-board data resources.

14. use of C++

    ARIA uses some features of C++ that some programmers may not be aware of yet, and includes some workarounds for platform differences.

Standard Template Library

    ARIA makes heavy use of the C++ standard template library (STL). So you should understand the STL in order to get the best use from some of the more advanced parts of ARIA.

Default Arguments

    In the function declaration a default value for an argument may be specified. Arguments with default values may then be omitted from the function call.

For example, after declaring this function with a default value for its integer argument:

     void foo(int number = 3);

it can be used in two different ways:

     // Use the default value for the argument:
     foo();

     // Or, use don't use the default:
     foo(99);   

    This behavior is quite useful for having defaults for more obscure options you will usually not need to change, but still allowing you to change them if necessary without making ARIA more complex.

    Also note that the function definition must not have the assignment in it, only the declaration. Therefore the definition if our example function would look like this:

  void foo(int number)
  { 
    //...
  }

Constructor Chaining

    Constructor chaining is quite simple though sometimes not used by C++ programmers. Each constructor can give arguments to the constructors of the member variables it contains and to the constructors of classes from which it inherits. For example if you have:

     class BaseClass
     {
     public:
       BaseClass(int someNumber);
     };

and

     class SubClass : public BaseClass
     {
     public:
       SubClass(void);
       int anotherNumber;
     };

When you write your constructor for SubClass you can initialize both baseClass and anotherNumber:

     SubClass::SubClass(void) : BaseClass(3), anotherNumber(37)
     {
         // ...
     }

    Note how the constructors to be initialized must follow a colon (:) after the constructor, and be separated by commas. Member variables must be initialized in the order they are in the class. Note that initializing integers is not all that unique or useful, but using this to initialize callback Functors is quite useful.

    Constructor chaining is used in many many places by ARIA, thus it must be understood in order to understand ARIA, but the above is all that really needs to be known.

Chars and Strings, Win workaround

    During development problems were encountered with Windows if a std::string was passed into a DLL. Thus for all input to ARIA const char * is used, but for all internal storage and all reporting std::strings are passed back out of ARIA.

15. Connecting with a Robot or the Simulator the hard way

    ArDeviceConnection is ARIA's communications object; ArSerialConnection and ArTcpConnection are its built-in children most commonly used to manage communication between a MobileRobots or ActivMedia robot or the robot simulator, respectively. These classes are not device-specific, however, so use ArSerialConnection, for instance, to also configure a serial port and establish a connection with a robot accessory, such as with the SICK laser range finder.

Opening the Connection

After creating and opening a device connection, associate it with its ARIA device handlers, most commonly with ArRobot::setDeviceConnection for the robot or the simulator.

For example, early in an ARIA program, specify the connection device and associate it with the robot:

  ArTcpConnection con;
  ArRobot robot;

Later in the program, after initializing the ARIA system (Aria::init(); is mandatory), set the Connection port to its default values (for TCP, host is "localhost" and port number is 8101), and then open the port:

 con.setPort();
 if (!con.openSimple())
  {
    printf("Open failed.");
    Aria::shutdown();
    return 1;
  }

TCP and Serial connections have their own implementation of open which is not inherited, but has default arguments that make the generic open work for the all default cases. And open returns a status integer which can be passed to the re-implemented and inherited ArDeviceConnection::getOpenMessage in order to retrieve related status string, which is useful in reporting errors to the user without having to know about the underlying device.

Robot Client-Server Connection

After associating the device with the robot, now connect with the robot's servers, ArRobot::blockingConnect or ArRobot::asyncConnect, for example, to establish the client-server connection between ARIA ArRobot and the robot microcontroller or robot simulator. The blockingConnect method doesn't return from the call until a connection succeeds or fails:

  robot.setDeviceConnection(&con);
  if (!robot.blockingConnect())
  {
    printf("Could not connect to robot... Exiting.");
    Aria::shutdown();
    return 1;
  }

The previous examples connect with the simulator through a TCP socket on your PC. Use tcpConn.setPort(host, port) to set the TCP hostname or IP address and related socket number to another machine on the network. For instance, use tcpConn.setPort("bill", 8101); to connect to the simulator which is running on the networked computer "bill" through port 8101.

Replace ArTcpConnection con; with ArSerialConnection con; to connect with a robot through the default serial port (/dev/ttyS0 or COM1), or another you specify with ArSerialConnection::setPort(), such as con.setPort("COM3");.

At some point, you may want to open the port with the more verbose con.open().

Connection Read, Write, Close and Timestamping

The two main functions of a device connection are ArDeviceConnection::read and ArDeviceConnection::write. Simple enough. ArDeviceConnection::close also is inherited and important. You probably won't use direct read or write to the robot device, although you could. Rather, ArRobot provides a host of convenient methods that package your robot commands, and gather and distribute the various robot information packets, so that you don't have to attend those mundane details. See the next section for details.

All ArDeviceConnection subclasses have support for timestamping (ArDeviceConnection::getTimeRead). With the robot connection, timestamping merely says what time a robot SIP came in, which can be useful for interpolating the robot's location more precisely.

=================================================

1. 支持

1.1  新闻组

    我们建立了若干用户邮件地址组成的新闻组,通过它用户可以交流意见、软件、关于机器人的各种问题等。请访问以下站点:
http://robots.MobileRobots.com 以获得更多的信息。
注册成为该新闻组的先锋用户,请发送邮件信息到新闻组服务器,如下:
To: mailto:pioneer-users-requests@mobilerobots.com
From: <your return e-mail address goes here>
Subject
(邮件主题): <从以下命令中选择>
Help 
(回复新闻组介绍)
Lists (回复新闻组名单)
Subscribe (订阅)
Unsubscribe (取消订阅)
我们的名单服务器将自动回复,在您订阅之后,即可向新闻组全世界范围内先锋用户社区发送您的信件、意见、问题等
 

To: pioneer-users-requests@mobilerobots.com
From: <your return e-mail address goes here>
Subject
(邮件主题): <您希望发送的内容>

1.2. 技术支持

    当您在使用机器人过程中遇到困难,当您在附送的操作手册中找不到解决方法,当您需要了解我们提供的最新的技术更新,请您访问我们的网站:
http://robots.MobileRobots.com/techsupport 或者写邮件给我们:support@MobileRobots.com 与我们交流您的想法和问题。
注意:为了更好的解答您提出的问题,我们需要了解您购买的产品型号。请您在发送问题时务必写明您所购买的产品序列号(在主电源开关下方)。
 


2. 什么是先锋机器人

2.1  客户机程序
    MobileRobots 机器人以服务器的方式运行在客户机服务器环境下:其控制器处理机器人底层的细节问题,诸如保持平台的驱动速度,越过不平坦的地形,读传感器信号——比如声纳,管理附件-如机械手臂。为构成客户机-服务器环境,通过串行口将PC计算机与机器人控制器连接,在PC计算机上运行上层的智能控制软件,比如障碍规避、路经编制、人脸识别、定位、导航等等。

    MobileRobots 机器人的这种客户机服务器运行方式有着显著的优点,即不同的机器人服务器系统可以运行同一上层客户机软件。多用户也可以在一台机器人服务器上共同分担各自的控制任务,这就可以完成分布式的通讯、控制试验、计划等。 

2.2 声纳

    所有先锋 3系列机型上的声纳环位置都是固定的:两侧各有一个,另外6个以20度间隔分布在侧边。这种声纳阵的布置可以为机器人提供360度无缝检测。


    声纳灵敏度调整很容易实现,以机体前方的声纳为例,找到位于声纳环下面附近的小孔,透过小孔可以看到里面的螺帽,即为灵敏度调整分压器件。用一柄小的直口螺丝刀,逆时针扭转该调整螺帽即可降低声纳接收装置对声音和噪声、回声的敏感度。

    Note:如果敏感度设置较低将会影响机器人对小型物体的辨识能力。在某些环境下,这是允许和合适的,比如机器人运行在嘈杂的环境中,或者运行在不平坦的或高反射的路面如粗纤维地毯上,此时如果声纳的灵敏度过高,机器人将会把地毯辨识为障碍物。顺时针旋转调整螺帽将增加声纳的灵敏度,这将使机器人更容易发现小的物体,或者更远处的大的物体。如,当机器人运行于空旷安静、路面平整的室外环境时,可以适当增加声纳的灵敏度。


3. ARCOS 

详见机器人操作手册。


Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐