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