1 ////////////////////////////////////////////////////////////////////////////////////

    2 ///

    3 ///  \file tutorial_03.cpp

    4 ///  \brief This file is part of a set of tutorials for learning how to use

    5 ///        JAUS++.  This program demonstrates an alternative method to

    6 ///        discover components and receives messages than

    7 ///        tutorial_02.cpp demonstrates.

    8 ///

    9 ///  <br>Author(s): Daniel Barber

   10 ///  <br>Created: 3 July 2010

   11 ///  <br>Copyright (c) 2010

   12 ///  <br>Applied Cognition and Training in Immersive Virtual Environments

   13 ///  <br>(ACTIVE) Laboratory

   14 ///  <br>Institute for Simulation and Training (IST)

   15 ///  <br>University of Central Florida (UCF)

   16 ///  <br>All rights reserved.

   17 ///  <br>Email: dbarber@ist.ucf.edu

   18 ///  <br>Web:  http://active.ist.ucf.edu

   19 ///

   20 ///  Redistribution and use in source and binary forms, with or without

   21 ///  modification, are permitted provided that the following conditions are met:

   22 ///      * Redistributions of source code must retain the above copyright

   23 ///        notice, this list of conditions and the following disclaimer.

   24 ///      * Redistributions in binary form must reproduce the above copyright

   25 ///        notice, this list of conditions and the following disclaimer in the

   26 ///        documentation and/or other materials provided with the distribution.

   27 ///      * Neither the name of the ACTIVE LAB, IST, UCF, nor the

   28 ///        names of its contributors may be used to endorse or promote products

   29 ///        derived from this software without specific prior written permission.

   30 ///

   31 ///  THIS SOFTWARE IS PROVIDED BY THE ACTIVE LAB''AS IS'' AND ANY

   32 ///  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

   33 ///  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

   34 ///  DISCLAIMED. IN NO EVENT SHALL UCF BE LIABLE FOR ANY

   35 ///  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

   36 ///  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

   37 ///  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

   38 ///  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

   39 ///  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

   40 ///  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

   41 ///

   42 ////////////////////////////////////////////////////////////////////////////////////

   43 #include <jaus/core/component.h>

   44 #include <cxutils/keyboard.h>

   45 #include <iostream>

   46 

   47 // NOTE - Run another JAUS program like tutorial_01

   48 // so that this program can talk to it.

   49 

   50 // An altnernative method to get the

   51 // current system information and receive messages

   52 // is to use a callback.  This can be done through

   53 // inheritance of the Discovery::Callback class as

   54 // show below:

   55 

   56 // Question:  Modify this program to receive the following

   57 // messages via Callbacks:

   58 //      ReportConfiguration (Already queried by Discovery)

   59 //      ReportIdentification (Already queried by Discovery)

   60 //      QueryIdentification (Already queried by Discovery)

   61 //      Any others you want to add (remember, you may have to query)

   62 

   63 class TutorialCallback : public JAUS::Discovery::Callback

   64 {

   65 public:

   66     TutorialCallback()

   67     {

   68     }

   69     ~TutorialCallback()

   70     {

   71     }

   72     ////////////////////////////////////////////////////////////////////////////////////

   73     ///

   74     ///   \brief This method is called whenver the transport service receives a

   75     ///          message you have registered the callback for.

   76     ///

   77     ///   You must use the transport service to register this callback for specific

   78     ///   types of messages you want to receive.

   79     ///

   80     ///   \param[in] message Pointer to a JAUS message receives.

   81     ///

   82     ////////////////////////////////////////////////////////////////////////////////////

   83     virtual void ProcessMessage(const JAUS::Message* message)

   84     {

   85         if(message->GetMessageCode() == JAUS::REPORT_HEARTBEAT_PULSE)

   86         {

   87             const JAUS::ReportHeartbeatPulse* report =

   88                 dynamic_cast<const JAUS::ReportHeartbeatPulse*>(message);

   89 

   90             std::cout << "\tReceived Message!\n\t";

   91             report->Print();

   92         }

   93     }

   94     ////////////////////////////////////////////////////////////////////////////////////

   95     ///

   96     ///   \brief This method is called whenever the Discovery service recieves

   97     ///          updated information about a subsystem, node, or component.  Updated

   98     ///          information includes services, identification, new and lost

   99     ///          connections to components.

  100     ///

  101     ///   \param[in] system The current known JAUS system information.

  102     ///

  103     ////////////////////////////////////////////////////////////////////////////////////

  104     virtual void ProcessSystemState(const JAUS::Subsystem::Map& system)

  105     {

  106         std::cout << "======================================================\n";

  107 

  108         JAUS::Subsystem::Map::const_iterator subsystem;

  109         // The map is indexed by the subsystem number.

  110         for(subsystem = system.begin();

  111             subsystem != system.end();

  112             subsystem++)

  113         {

  114             std::cout << "Subsystem: "

  115                       << subsystem->first

  116                       << " Identification: "

  117                       << subsystem->second->mIdentification

  118                       << std::endl;

  119 

  120             JAUS::Address::List componentsWithLiveness;

  121             componentsWithLiveness = subsystem->second->GetComponentsWithService(JAUS::Liveness::Name);

  122             JAUS::Address::List::iterator c;

  123             for(c = componentsWithLiveness.begin();

  124                 c != componentsWithLiveness.end();

  125                 c++)

  126             {

  127                 if( (*c) != mpComponent->GetComponentID())

  128                 {

  129                     // Setup the query message to send.

  130                     JAUS::QueryHeartbeatPulse query;

  131                     query.SetDestinationID( (*c) );

  132                     query.SetSourceID(mpComponent->GetComponentID());

  133 

  134                     std::cout << "\tSending Query to " << c->ToString() << std::endl;

  135                     mpComponent->Send(&query);

  136                 }

  137             }

  138         }

  139     }

  140 

  141     JAUS::Component* mpComponent;   ///<  Pointer to the component to use.

  142 };

  143 

  144 

  145 int main(int argc, char* argv[])

  146 {

  147     JAUS::Component component;

  148 

  149     // Setup identification info.  For questions about this,

  150     // see the previous tutorial(s).

  151     JAUS::Discovery* discoveryService = NULL;

  152     discoveryService = component.DiscoveryService();

  153     discoveryService->SetSubsystemIdentification(JAUS::Subsystem::Vehicle,

  154                                                 "Robot");

  155     discoveryService->SetNodeIdentification("Primary Computer");

  156     discoveryService->SetComponentIdentification("Baseline");

  157 

  158     // Always register callbacks before initialization.

  159 

  160     // Create a callback object, and register it with the

  161     // two services we want to use (Transport and Discovery).

  162     TutorialCallback callback;

  163 

  164     callback.mpComponent = &component;

  165     // Register the callback to be triggered when

  166     // Report Heartbeat Pulse messages are received.

  167     component.TransportService()->RegisterCallback(JAUS::REPORT_HEARTBEAT_PULSE,

  168                                                    &callback);

  169     // Register with Discovery to be notified of system changes.

  170     component.DiscoveryService()->RegisterCallback(&callback);

  171 

  172     JAUS::Address componentID(1000, 1, 3);

  173     // Initialize!

  174     std::cout << "Initializing component...";

  175     if(component.Initialize(componentID) == false)

  176     {

  177         std::cout << "Failed to initialize component [" << componentID.ToString() << "]\n";

  178         return 0;

  179     }

  180     std::cout << "Success!\n";

  181 

  182     // Now go into your main computer loop until the

  183     // component has been told to shutdown.

  184     JAUS::Time::Stamp displayStatusTimeMs = JAUS::Time::GetUtcTimeMs();

  185     while(true)

  186     {

  187         JAUS::Management* managementService = NULL;

  188         managementService = component.ManagementService();

  189         if(managementService->GetStatus() == JAUS::Management::Status::Shutdown)

  190         {

  191             // Exit program.

  192             break;

  193         }

  194 

  195         if(CxUtils::GetChar() == 27)

  196         {

  197             break;

  198         }

  199 

  200         CxUtils::SleepMs(1);

  201     }

  202 

  203     // Shutdown your component completely.  Any

  204     // services added or belonging to the component

  205     // will be deleted.

  206     component.Shutdown();

  207 

  208     return 0;

  209 }

  210 

  211 

  212 

  213 /* End of File */

  214