Get ACTIVE-IST Open Source Tools at SourceForge.net. Fast, secure and Free Open Source software downloads

JAUS++

Cross-Platform C++ Implementation of the Joint Architecture for Unmanned Systems (JAUS)

JAUS++ Version 1.5 - Implementation of Reference Architecture 3.3 (Deprecated)

NEWS (12/22/2010): Version 1.X of JAUS++ has been deprecated, please visit the JAUS++ 2.X page for details on the latest version which supports the current SAE JAUS standard. This page has been left as a reference for anyone who may need an implementation of the JAUS Reference Architecture.

Capabilities

Although there are other RA 3.3 JAUS options available for developers like OpenJAUS, JAUS++ offers additional capabilities for supporting simulation in addition to advanced component interfaces for handling events, subsystem configuration discovery, video streaming, and command and control just to name a few. JAUS++ has been tested for compliance with the JAUS Reference Architecture (RA) Version 3.3 using the JAUS Compliance Tool Suite (JCTS) at robotics competitions such as the Intelligent Ground Vehicle Competition (IGVC) and the International Aerial Robotics Competition (IARC). Additional interoperability tests have been performed with the Multi-robot Operator Control Unit (MOCU) developed by Space and Naval Warfare Systems Center, San Diego (SSC San Diego). During these test, MOCU was able to take control of a simulation and real unmanned system allowing full teleoperation with video streaming. Finally, JAUS++ has been proved to run in both Windows (XP/Vista/Mobile) and Linux environments. It is our belief that these capabilities, extensive documentation, several code examples, and BSD license make it a viable option for developers who want to quickly create advanced applications that support JAUS.

Platforms Using JAUS++

As of this writing JAUS++ has been used on multiple simulated and real unmanned systems. At the ACTIVE Laboratory alone we've simulated an Unmanned Ground Systems (UGS) and Unmanned Air System (UAS) in addition to three ground platforms, one of which is the Segway RMP 'P' Series. The Robotics Club at the University of Central Florida also uses JAUS++ on their robotic vehicles. The following are some links to papers related to projects using JAUS++.

System Architecture

The JAUS system architecture is, visualized in the image below, is a collection of Subsystems. A Subsystem can be best described as an Unmanned Vehicle (UV) or Operator Control Unit (OCU). Within a Subsystem are Nodes, which is any computing device with a physical address (e.g. computer with Ethernet port, micro-controller with serial connection). Within the Node are Components which provide services. A service is a capability that has been broken down to a pointer where it is not optimal to break it down further (e.g. Global Pose Sensor, Primitive Driver, Visual Sensor). Every component with JAUS is given an ID which is composed of the Subsystem, Node, Component, and Instance number. For example, if there is one Global Pose Sensor which has an ID of 38 on Subsystem 1, Node 1, then its' ID will be 1.1.38.1. If there was another Global Pose Sensor on the same node, it would have an ID of 1.1.38.2.

System Diagram

Every Node contains a component called the Node Manager. As shown in the previous image, all communication between Components on a Node and between Nodes within a Subsystem must go through the Node Manager. It is responsible for maintaining connections to Components on the Node, and connections to other Nodes on the Subsystem. Communication between Subsystems travels through the Communicator component. The Communicator component is the single point of entry to a Subsystem. The Communicator uses "Data Links" to connect to other subsystems.

Node Manager

One of the most important parts of JAUS++ is the Node Manager. The JAUS++ Node Manager communicates between components using Shared Memory, making it capable of transfering small and large messages with low latency. It also supports UDP, TCP, and R232 transports for communication with other Node Managers. Finally, through the use of Shared Memory it is possible to run more than one Node Manager on a single host machine for simulation purposes. This feature allows developers to simulate multiple Subsystems on a single host machine. The Node Manager also supports Dynamic Discover, Service Connections (which will be deprecated in future JAUS versions), and Events. These features allow components to dynamically discover a node, the configuration, and when configuration changes.

JAUS++ comes with a graphical version of the Node Manager written in wxWidgets. This application is easy to use, showing users what the current node and subsystem configuration is, and with the press of a button can generate a message log for review. As shown below, it has can be run on multiple platforms such as Windows (left) and Ubuntu (right). However, for those who want to embed a Node Manager within there own applications, it can be added with just a few lines of code, and configured manually or by loading an XML settings file as shown in the example below.

Node Manager and Video Streaming on Vista Video Streaming and NodeManager on Ubuntu

Example Code for Node Manager

NodeManager node;
// Try load using the example XML settings
// file.
if(node.Initialize("settings/nodesettings.xml"))
{
    cout << "JAUS Node Manager initialized." << endl;
}
// Initialize the Node Manager with a given
// subsystem and node number.  The third parameter is
// set to false because this example uses UDP for inter-node
// communication.  The fourth parameter is the size of
// the nodes Shared Memory buffer.  This buffer is used
// for receiving messages from components that need to
// be routed.  The default size is 2MB. Make this value
// larger or smaller depending on the volume of traffice you expect.
else if(node.Initialize(1, 2, JAUS_NODE_SM_DEFAULT_SIZE))
{
    cout << "JAUS Node Manager initialized." << endl;
}
else
{
    cout << "Failed to initialize Node Manager." << endl;
    return 0;
}

Communicator

Since the Communicator component performs tasks very similar to the Node Manager, it is included within the Node Manager application. The JAUS++ Communicator uses a default Data Link which transmits and receives over UDP using Multicast or Broadcast and Unicast. The JAUS++ SDK comes with an interface for creating new Data Links, making it easy for developers to support communications with encryption over any hardware interface.

Component

The Component class is the main interface for creation of JAUS components. Using this interface it is possible to create a component that supports the Core Subgroup of JAUS messages with a few lines of code.

////////////////////////////////////////////////////////////////////////////////////
///
///   \brief This is an example program testing/demonstrating the
///          component class.  It shows how to initialize a component, check if
///          it is connected to a Node Manager, how to send and receive messages.
///
////////////////////////////////////////////////////////////////////////////////////
int main(int argc , char *argv[])
{
    Address nodeID;     // ID of the node manager.
    Component component;// Component.

    cout << "Looking for node manager...";

    while(gExitFlag == false)
    {
        if(Component::IsNodeManagerPresent(&nodeID))
        {
            cout << "Success!\n";
            cout << "Node Manager ID is: ";
            nodeID.PrintID();
            break;
        }
        Sleep(100);
    }
    if(nodeID.IsValid() == false)
    {
        cout << "Failure.\n";
        cout << "Exiting...";
        return 0;
    }

    cout << "Initializing component...";
    // Initialize the component.  Every component has
    // a name associated with it, and an ID.  The third parameter
    // used here is the number of bytes to use for buffering incomming
    // messages.  Depending on the number of messages you expect to
    // receive or the size (like video) you may want to make this number larger.
    // by default the buffer is large enough to hold 10 JAUS_MAX_PACKET_SIZE messages.
    if(component.Initialize("My Example Component",
                            Address(nodeID.mSubsystem, nodeID.mNode, 2, 1),
                            JAUS_SHARED_MEMORY_DEFAULT_SIZE))
    {
        cout << "Success!\n";
        // Now lets wait until we are connected to the node manger.
        // Initialization only allocates memory, and verifies there is not
        // another component running with the same ID.  If the node manager is
        // already running (as is the case in this example if we got here) then we
        // should already be connected, however it is possible to initialize a component
        // and then start up a node manger later.  The node manger included with JAUS++ will
        // automatically identify running components and connect to them.
        while(!component.IsConnected())
        {
            Sleep(100);
        }

        // If the component is ready, set the status.
        component.SetPrimaryStatus(Component::Status::Ready);

        QueryServices queryServices;
        Receipt receipt;

        queryServices.SetAckNack(Header::AckNack::Request);
        queryServices.SetDestinationID(nodeID);
        queryServices.SetSourceID(component.GetID());

        // This example shows how you can send a message and
        // wait until the response is received.  The response
        // message is stored in a receipt structure.  Note: When the
        // receipt is deleted (or goes out of scope) the message
        // data stored within it will be deleted also.
        cout << "Sending Query message with receipt (blocking)...";
        if(component.Send(&queryServices, receipt) == JAUS_OK)
        {
            // At this point the response message is stored in
            // the Receipt (receipt) which has other information such
            // as how long it took to get the response, etc.

            // See if we received an Acknowledge message also, since
            // we set Ack/Nack to Request Acknowledge.  This is just a test
            // to verify interface performance.  If send count is how many times
            // the message was sent while attempting to get a response.  The
            // maximum send count will always be 3.
            if(receipt.ReceivedAcknowledge() && receipt.GetSendCount() == 1)
            {
                cout << "Success!\n";
                // Display received data to console.
                const ReportServices* report
			= dynamic_cast<const ReportServices*>(receipt.GetResponseMessage());
                report->Print();
            }
            else
            {
                cout << "Failure.\n";
            }
        }
        else
        {
            cout << "Failure.\n";
        }
    }
    else
    {
        cout << "Failure!\n";
        // Display the reason for failure.
        component.PrintJausError();
    }

    // Shutdown the component.
    component.Shutdown();

    return 0;
}

Video Streaming

The Visual Sensor library of JAUS++ includes software for fast creation of Visual Sensor Components that can stream video to multiple subscribers. Several examples of how to send and subscribe to image data come with the library. The current version of JAUS++ supports JPEG, PNG, PGM, and PPM image streaming out of the box, however the Visual Sensor and Client interfaces allow developers to add this capability themselves with ease. The Visual Sensor and Visual Sensor Client programs written with wxWidgets are available making it possible to share video data without writing a line of code as shown in this screen shot. The Visual Sensor application can be used with any Direct Show compatible camera in Windows or OpenCV compatible camera in Linux, allowing easy integration of a camera into your project.