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

    2 ///

    3 ///  \file tutorial_04.cpp

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

    5 ///        JAUS++.  This program demonstrates how to use the Access

    6 ///        Control Service.  Access Control is used to take control

    7 ///        of another component for exclusive operations.  Finally, this

    8 ///        example also shows how to change the state of a

    9 ///        controlled component.

   10 ///

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

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

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

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

   15 ///  <br>(ACTIVE) Laboratory

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

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

   18 ///  <br>All rights reserved.

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

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

   21 ///

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

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

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

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

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

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

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

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

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

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

   32 ///

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

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

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

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

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

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

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

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

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

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

   43 ///

   44 ////////////////////////////////////////////////////////////////////////////////////

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

   46 #include <cxutils/keyboard.h>

   47 #include <iostream>

   48 

   49 // NOTE - Run another JAUS program like tutorial_01

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

   51 

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

   53 {

   54     JAUS::Component component;

   55 

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

   57     // see the previous tutorial(s).

   58     JAUS::Discovery* discoveryService = NULL;

   59     discoveryService = component.DiscoveryService();

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

   61                                                 "Robot");

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

   63     discoveryService->SetComponentIdentification("Baseline");

   64 

   65     // The Access Control service manages what other components

   66     // are allowed to control this component, and what

   67     // components our component is in control of. Taking control

   68     // of a component allows for exclusive access to its services,

   69     // blocking any other commands from other services (except for

   70     // event commands).  If we take control of a component, we

   71     // will have it until we release control, or another component

   72     // with higher authority takes it from us.

   73 

   74     // Let's change options for the Access Control service of our

   75     // component.  In this tutorial I am saving a pointer

   76     // to the Access Control service, just like in the previous

   77     // tutorials for Discovery and Management.  This is not

   78     // necessary, and is only done to show users that you can

   79     // do this if you want, but you can just as easily keep

   80     // calling component.AccessControlService() method to get the

   81     // pointer and call the related methods if you want.

   82     JAUS::AccessControl* accessControlService = NULL;

   83     accessControlService = component.AccessControlService();

   84 

   85     // Use the SetAuthorityCode method to set the authority level

   86     // of our component.  We must have equal too or greater

   87     // than authority than the component we are trying to

   88     // control.  This is also a way to prevent low authority

   89     // level components from taking control of us!  Authority

   90     // values range from 0-255, with 255 being the highest.

   91     accessControlService->SetAuthorityCode(100);

   92     // The SetTimeoutPeriod method sets how often any controlling

   93     // component must attempt to reacquire control of our

   94     // component before we timeout control.  For example

   95     // if in this example, if a controller doesn't try to

   96     // reacquire control within 1 second, they will lose

   97     // control.

   98     accessControlService->SetTimeoutPeriod(1);

   99 

  100     JAUS::Address componentID(1000, 1, 4);

  101     // Initialize!

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

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

  104     {

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

  106         return 0;

  107     }

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

  109 

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

  111     // component has been told to shutdown.

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

  113     JAUS::Time::Stamp acquiredControlTimeMs = 0;

  114     JAUS::Time::Stamp releaseControlTimeMs = 0;

  115     while(true)

  116     {

  117         JAUS::Management* managementService = NULL;

  118         managementService = component.ManagementService();

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

  120         {

  121             // Exit program.

  122             break;

  123         }

  124 

  125         // In this tutorial, the following code shows how to take

  126         // and release control of a component.  In this example

  127         // we take control for 3 seconds, and then release control

  128         // for 3 seconds, then repeat.

  129 

  130         // Let's see if we are in control of any components.

  131         JAUS::Address::List controlledComponents;

  132         controlledComponents = accessControlService->GetControlledComponents();

  133         if(controlledComponents.size() == 0 &&

  134            JAUS::Time::GetUtcTimeMs() - releaseControlTimeMs > 3000)

  135         {

  136             // Find a component to take control of on our subsystem.

  137             JAUS::Address::List availableComponents;

  138             JAUS::Discovery* discoveryService = NULL;

  139             discoveryService = component.DiscoveryService();

  140             availableComponents =

  141                 discoveryService->GetSubsystem(component.GetComponentID())->GetComponentsWithService(JAUS::AccessControl::Name);

  142 

  143             JAUS::Address::List::iterator c;

  144             for(c = availableComponents.begin();

  145                 c != availableComponents.end();

  146                 c++)

  147             {

  148                 // Don't take control of ourself!

  149                 if( *c == component.GetComponentID() )

  150                 {

  151                     continue;

  152                 }

  153                 std::cout << "Requesting control of " << c->ToString() << std::endl;

  154                 if(accessControlService->RequestComponentControl( (*c) ) == true)

  155                 {

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

  157                     acquiredControlTimeMs = JAUS::Time::GetUtcTimeMs();

  158 

  159                     // Now that we have control, lets send a command to

  160                     // change the controlled component to the "Ready"

  161                     // state.

  162                     component.ManagementService()->Resume((*c));

  163 

  164                     break;

  165                 }

  166                 else

  167                 {

  168                     std::cout << "Failure!\n";

  169                 }

  170             }

  171         }

  172         // In this tutorial, this part is only here to show how to

  173         // release control of a component.  In this case, we will release

  174         // control after 3 seconds.

  175         else if(JAUS::Time::GetUtcTimeMs() - acquiredControlTimeMs > 3000)

  176         {

  177             JAUS::Address::List::iterator c;

  178             for(c = controlledComponents.begin();

  179                 c != controlledComponents.end();

  180                 c++)

  181             {

  182                 // Before releasing control, we should always put the

  183                 // component back in a standby state.

  184                 if(component.ManagementService()->GetComponentStatus( (*c) ) !=

  185                     JAUS::Management::Status::Standby)

  186                 {

  187                     // Sends a standby command.

  188                     component.ManagementService()->Standby( (*c) );

  189                 }

  190                 std::cout << "Releasing control of " << c->ToString() << std::endl;

  191                 if(accessControlService->ReleaseComponentControl( (*c) ) == true)

  192                 {

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

  194                     releaseControlTimeMs = JAUS::Time::GetUtcTimeMs();

  195                     break;

  196                 }

  197                 else

  198                 {

  199                     std::cout << "Failure!\n";

  200                 }

  201             }

  202         }

  203 

  204         if(JAUS::Time::GetUtcTimeMs() - displayStatusTimeMs > 500)

  205         {

  206             // Print out status of control service.  This will show

  207             // who we are controlling.

  208             accessControlService->PrintStatus(); std::cout << std::endl;

  209             displayStatusTimeMs = JAUS::Time::GetUtcTimeMs();

  210         }

  211 

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

  213         {

  214             break;

  215         }

  216 

  217         CxUtils::SleepMs(1);

  218     }

  219 

  220     // Shutdown your component completely.  Any

  221     // services added or belonging to the component

  222     // will be deleted.

  223     component.Shutdown();

  224 

  225     return 0;

  226 }

  227 

  228 

  229 

  230 /* End of File */

  231