1 ////////////////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file tutorial_05.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 Events service
6 /// to request events from another component.
7 ///
8 /// <br>Author(s): Daniel Barber
9 /// <br>Created: 3 July 2010
10 /// <br>Copyright (c) 2010
11 /// <br>Applied Cognition and Training in Immersive Virtual Environments
12 /// <br>(ACTIVE) Laboratory
13 /// <br>Institute for Simulation and Training (IST)
14 /// <br>University of Central Florida (UCF)
15 /// <br>All rights reserved.
16 /// <br>Email: dbarber@ist.ucf.edu
17 /// <br>Web: http://active.ist.ucf.edu
18 ///
19 /// Redistribution and use in source and binary forms, with or without
20 /// modification, are permitted provided that the following conditions are met:
21 /// * Redistributions of source code must retain the above copyright
22 /// notice, this list of conditions and the following disclaimer.
23 /// * Redistributions in binary form must reproduce the above copyright
24 /// notice, this list of conditions and the following disclaimer in the
25 /// documentation and/or other materials provided with the distribution.
26 /// * Neither the name of the ACTIVE LAB, IST, UCF, nor the
27 /// names of its contributors may be used to endorse or promote products
28 /// derived from this software without specific prior written permission.
29 ///
30 /// THIS SOFTWARE IS PROVIDED BY THE ACTIVE LAB''AS IS'' AND ANY
31 /// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 /// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 /// DISCLAIMED. IN NO EVENT SHALL UCF BE LIABLE FOR ANY
34 /// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 /// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 /// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 /// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 /// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 /// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 ///
41 ////////////////////////////////////////////////////////////////////////////////////
42 #include <jaus/core/component.h>
43 #include <cxutils/keyboard.h>
44 #include <iostream>
45
46 // NOTE - Run another JAUS program like tutorial_01
47 // so that this program can talk to it.
48
49 // In this tutorial, a callback is used to show that
50 // event messages have been received.
51
52 // After looking at this tutorial program, try and modify
53 // it to learn how to get other event subscriptions like
54 // on change.
55 //
56 // Do the following:
57 // Find a component with the Time Service, and request
58 // just the Date Stamp information, at 1 Hz, then try
59 // create an On Change Event for the Time Stamp (it should
60 // update a lot).
61
62 class EventTutorialCallback : public JAUS::Events::Callback
63 {
64 public:
65 EventTutorialCallback()
66 {
67 }
68 ~EventTutorialCallback()
69 {
70 }
71 ////////////////////////////////////////////////////////////////////////////////////
72 ///
73 /// \brief Method called when an event related message has been received.
74 ///
75 /// \param[in] type Type of event (EveryChange, Periodic).
76 /// \param[in] eventID Event ID number.
77 /// \param[in] sequenceNumber The sequence number for the event (update number).
78 /// \param[in] message The message data associated with the event.
79 ///
80 ////////////////////////////////////////////////////////////////////////////////////
81 virtual void ProcessEvent(const JAUS::Events::Type type,
82 const JAUS::Byte eventID,
83 const JAUS::Byte sequenceNumber,
84 const JAUS::Message* message)
85 {
86 if(message->GetMessageCode() == JAUS::REPORT_HEARTBEAT_PULSE)
87 {
88 const JAUS::ReportHeartbeatPulse* report =
89 dynamic_cast<const JAUS::ReportHeartbeatPulse*>(message);
90
91 std::cout << "\tReceived Event Message [" << (int)sequenceNumber << "]!\n\t";
92 report->Print();
93 }
94 }
95 };
96
97 int main(int argc, char* argv[])
98 {
99 JAUS::Component component;
100
101 // Setup identification info. For questions about this,
102 // see the previous tutorial(s).
103 JAUS::Discovery* discoveryService = NULL;
104 discoveryService = component.DiscoveryService();
105 discoveryService->SetSubsystemIdentification(JAUS::Subsystem::Vehicle,
106 "Robot");
107 discoveryService->SetNodeIdentification("Primary Computer");
108 discoveryService->SetComponentIdentification("Baseline");
109
110 // The Events service is used to create and maintain
111 // subscriptions to other components that support events.
112 // It also acts as an interface that other services within
113 // your component inherit from so that they can support
114 // generation of events (see Liveness). In this
115 // tutorial example, we will use the Events service
116 // to subscribe to Report Heartbeat Pulse messages from
117 // another component.
118 JAUS::Events* eventsService = NULL;
119 eventsService = component.EventsService();
120
121 // Register a callback to be notified when event messages
122 // have been received.
123 EventTutorialCallback callback;
124 eventsService->RegisterCallback(&callback);
125
126 JAUS::Address componentID(1000, 1, 5);
127 // Initialize!
128 std::cout << "Initializing component...";
129 if(component.Initialize(componentID) == false)
130 {
131 std::cout << "Failed to initialize component [" << componentID.ToString() << "]\n";
132 return 0;
133 }
134 std::cout << "Success!\n";
135
136 // Now go into your main computer loop until the
137 // component has been told to shutdown.
138 JAUS::Time::Stamp displayStatusTimeMs = JAUS::Time::GetUtcTimeMs();
139 while(true)
140 {
141 // See if we have any subscriptions for the type of
142 // data we want (from any source), and if not, create one.
143 if(eventsService->HaveSubscription(JAUS::REPORT_HEARTBEAT_PULSE, JAUS::Address()) == false)
144 {
145 // Find components with the service that supports
146 // the type of data we want.
147 JAUS::Address::List availableComponents;
148 JAUS::Discovery* discoveryService = NULL;
149 discoveryService = component.DiscoveryService();
150 availableComponents =
151 discoveryService->GetSubsystem(component.GetComponentID())->GetComponentsWithService(JAUS::Liveness::Name);
152
153 JAUS::Address::List::iterator c;
154 for(c = availableComponents.begin();
155 c != availableComponents.end();
156 c++)
157 {
158 // Don't subscribe to ourselves!
159 if((*c) == component.GetComponentID())
160 {
161 continue;
162 }
163 // Create a periodic event. A periodic event is
164 // an event that happens at a fixed rate. The
165 // alternative is an Every Change event, which
166 // occurs whenever the data is modified.
167
168 // First we must setup the query message for the
169 // type of report we want. Since we want
170 // Report Heartbeat Pulse, we need a
171 // Query Heartbeat Pulse message.
172 JAUS::QueryHeartbeatPulse query;
173 std::cout << "Requesting Periodic Event From " << c->ToString();
174 // We are request a rate of 5 Hz, with a minimum acceptable rate
175 // of 1 Hz. If the component we are requesting cannot support
176 // at least 1 Hz, the request will be canceled.
177 if(eventsService->RequestPeriodicEvent((*c), &query, 5, 1))
178 {
179 std::cout << "Success!\n";
180 break;
181 // Now that we have the subscription, you should
182 // see the callback being triggered when the
183 // data arrives at 5Hz!
184 }
185 else
186 {
187 std::cout << "Failure!\n";
188 }
189 }
190 }
191
192 JAUS::Management* managementService = NULL;
193 managementService = component.ManagementService();
194 if(managementService->GetStatus() == JAUS::Management::Status::Shutdown)
195 {
196 // Exit program.
197 break;
198 }
199
200 if(JAUS::Time::GetUtcTimeMs() - displayStatusTimeMs > 500)
201 {
202 // Print out status of the service. You may see more
203 // events being displayed than just the one we created in
204 // this program. That is because the Discovery Service
205 // creates events to other components to be notified when
206 // the system configuration changes. This is part of
207 // the features within JAUS++ to support redundancy.
208 eventsService->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