先鋒機器人學習筆記_1-1 ARIA開發者參考手冊

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 # action priority value of action's desired-velocity channel strength of action's desired-velocity channel current final velocity value current final velocity strength
1 A 4 -400 0.25 -400 0.25
2 B 3 -100 1.0 Combined for use in step 4
3 C 3 200 0.50
4 B&C 3 0 0.75 -100 1.0
5 D 1 500 0.50 no change no change
final result     -100 1.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:[email protected]
From: <your return e-mail address goes here>
Subject
(郵件主題): <從以下命令中選擇>
Help 
(回覆新聞組介紹)
Lists (回覆新聞組名單)
Subscribe (訂閱)
Unsubscribe (取消訂閱)
我們的名單服務器將自動回覆,在您訂閱之後,即可向新聞組全世界範圍內先鋒用戶社區發送您的信件、意見、問題等
 

To: [email protected]
From: <your return e-mail address goes here>
Subject
(郵件主題): <您希望發送的內容>

1.2. 技術支持

    當您在使用機器人過程中遇到困難,當您在附送的操作手冊中找不到解決方法,當您需要了解我們提供的最新的技術更新,請您訪問我們的網站:
http://robots.MobileRobots.com/techsupport 或者寫郵件給我們:[email protected] 與我們交流您的想法和問題。
注意:爲了更好的解答您提出的問題,我們需要了解您購買的產品型號。請您在發送問題時務必寫明您所購買的產品序列號(在主電源開關下方)。
 


2. 什麼是先鋒機器人

2.1  客戶機程序
    MobileRobots 機器人以服務器的方式運行在客戶機服務器環境下:其控制器處理機器人底層的細節問題,諸如保持平臺的驅動速度,越過不平坦的地形,讀傳感器信號——比如聲納,管理附件-如機械手臂。爲構成客戶機-服務器環境,通過串行口將PC計算機與機器人控制器連接,在PC計算機上運行上層的智能控制軟件,比如障礙規避、路經編制、人臉識別、定位、導航等等。

    MobileRobots 機器人的這種客戶機服務器運行方式有着顯著的優點,即不同的機器人服務器系統可以運行同一上層客戶機軟件。多用戶也可以在一臺機器人服務器上共同分擔各自的控制任務,這就可以完成分佈式的通訊、控制試驗、計劃等。 

2.2 聲納

    所有先鋒 3系列機型上的聲納環位置都是固定的:兩側各有一個,另外6個以20度間隔分佈在側邊。這種聲納陣的佈置可以爲機器人提供360度無縫檢測。


    聲納靈敏度調整很容易實現,以機體前方的聲納爲例,找到位於聲納環下面附近的小孔,透過小孔可以看到裏面的螺帽,即爲靈敏度調整分壓器件。用一柄小的直口螺絲刀,逆時針扭轉該調整螺帽即可降低聲納接收裝置對聲音和噪聲、回聲的敏感度。

    Note:如果敏感度設置較低將會影響機器人對小型物體的辨識能力。在某些環境下,這是允許和合適的,比如機器人運行在嘈雜的環境中,或者運行在不平坦的或高反射的路面如粗纖維地毯上,此時如果聲納的靈敏度過高,機器人將會把地毯辨識爲障礙物。順時針旋轉調整螺帽將增加聲納的靈敏度,這將使機器人更容易發現小的物體,或者更遠處的大的物體。如,當機器人運行於空曠安靜、路面平整的室外環境時,可以適當增加聲納的靈敏度。


3. ARCOS 

詳見機器人操作手冊。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章