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