1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #ifndef MOBILITY_HELPER_H
22 #define MOBILITY_HELPER_H
23 
24 #include <vector>
25 #include "ns3/object-factory.h"
26 #include "ns3/attribute.h"
27 #include "ns3/output-stream-wrapper.h"
28 #include "ns3/position-allocator.h"
29 #include "node-container.h"
30 
31 namespace ns3 {
32 
33 class PositionAllocator;
34 class MobilityModel;
35 
36 /**
37  * \ingroup mobility
38  * \brief Helper class used to assign positions and mobility models to nodes.
39  *
40  * MobilityHelper::Install is the most important method here.
41  */
42 class MobilityHelper
43 {
44 public:
45   /**
46    * Construct a Mobility Helper which is used to make life easier when working
47    * with mobility models.
48    */
49   MobilityHelper ();
50 
51   /**
52    * Destroy a Mobility Helper
53    */
54   ~MobilityHelper ();
55 
56   /**
57    * Set the position allocator which will be used to allocate the initial
58    * position of every node initialized during MobilityModel::Install.
59    *
60    * \param allocator allocate initial node positions
61    */
62   void SetPositionAllocator (Ptr<PositionAllocator> allocator);
63 
64   /**
65    * \param type the type of mobility model to use.
66    * \param n1 the name of the attribute to set in the mobility model.
67    * \param v1 the value of the attribute to set in the mobility model.
68    * \param n2 the name of the attribute to set in the mobility model.
69    * \param v2 the value of the attribute to set in the mobility model.
70    * \param n3 the name of the attribute to set in the mobility model.
71    * \param v3 the value of the attribute to set in the mobility model.
72    * \param n4 the name of the attribute to set in the mobility model.
73    * \param v4 the value of the attribute to set in the mobility model.
74    * \param n5 the name of the attribute to set in the mobility model.
75    * \param v5 the value of the attribute to set in the mobility model.
76    * \param n6 the name of the attribute to set in the mobility model.
77    * \param v6 the value of the attribute to set in the mobility model.
78    * \param n7 the name of the attribute to set in the mobility model.
79    * \param v7 the value of the attribute to set in the mobility model.
80    * \param n8 the name of the attribute to set in the mobility model.
81    * \param v8 the value of the attribute to set in the mobility model.
82    * \param n9 the name of the attribute to set in the mobility model.
83    * \param v9 the value of the attribute to set in the mobility model.
84    */
85   void SetPositionAllocator (std::string type,
86                              std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
87                              std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
88                              std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
89                              std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
90                              std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
91                              std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
92                              std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
93                              std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
94                              std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
95 
96   /**
97    * \param type the type of mobility model to use.
98    * \param n1 the name of the attribute to set in the mobility model.
99    * \param v1 the value of the attribute to set in the mobility model.
100    * \param n2 the name of the attribute to set in the mobility model.
101    * \param v2 the value of the attribute to set in the mobility model.
102    * \param n3 the name of the attribute to set in the mobility model.
103    * \param v3 the value of the attribute to set in the mobility model.
104    * \param n4 the name of the attribute to set in the mobility model.
105    * \param v4 the value of the attribute to set in the mobility model.
106    * \param n5 the name of the attribute to set in the mobility model.
107    * \param v5 the value of the attribute to set in the mobility model.
108    * \param n6 the name of the attribute to set in the mobility model.
109    * \param v6 the value of the attribute to set in the mobility model.
110    * \param n7 the name of the attribute to set in the mobility model.
111    * \param v7 the value of the attribute to set in the mobility model.
112    * \param n8 the name of the attribute to set in the mobility model.
113    * \param v8 the value of the attribute to set in the mobility model.
114    * \param n9 the name of the attribute to set in the mobility model.
115    * \param v9 the value of the attribute to set in the mobility model.
116    *
117    * Calls to MobilityHelper::Install will create an instance of a matching
118    * mobility model for each node.
119    */
120   void SetMobilityModel (std::string type,
121                          std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
122                          std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
123                          std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
124                          std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
125                          std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
126                          std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
127                          std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
128                          std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
129                          std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
130 
131   /**
132    * \param reference item to push.
133    *
134    * Push an item on the top of the stack of "reference mobility models".
135    * The input item should be a node instance to which a mobility model
136    * has already been aggregated (usually by a call to Install).
137    *
138    * If this stack is not empty when MobilityHelper::Install
139    * is called, the model from the top of the stack is used
140    * to create a ns3::HierarchicalMobilityModel to make the
141    * newly-created models define their positions relative to that
142    * of the parent mobility model.
143    *
144    * This method is typically used to create hierarchical mobility
145    * patterns and positions by starting with the large-scale mobility
146    * features, and, then, defining the smaller-scale movements relative
147    * to a few reference points in the large-scale model.
148    */
149   void PushReferenceMobilityModel (Ptr<Object> reference);
150   /**
151    * \param referenceName named item to push.
152    *
153    * Push an item on the top of the stack of "reference mobility models".
154    * The input item should be a node instance to which a mobility model
155    * has already been aggregated (usually by a call to Install).
156    *
157    * If this stack is not empty when MobilityHelper::Install
158    * is called, the model from the top of the stack is used
159    * to create a ns3::HierarchicalMobilityModel to make the
160    * newly-created models define their positions relative to that
161    * of the parent mobility model.
162    *
163    * This method is typically used to create hierarchical mobility
164    * patterns and positions by starting with the large-scale mobility
165    * features, and, then, defining the smaller-scale movements relative
166    * to a few reference points in the large-scale model.
167    */
168   void PushReferenceMobilityModel (std::string referenceName);
169   /**
170    * Remove the top item from the top of the stack of
171    * "reference mobility models".
172    */
173   void PopReferenceMobilityModel (void);
174 
175   /**
176    * \return a string which contains the TypeId of the currently-selected
177    *          mobility model.
178    */
179   std::string GetMobilityModelType (void) const;
180 
181   /**
182    * \brief "Layout" a single node according to the current position allocator type.
183    *
184    * This method creates an instance of a ns3::MobilityModel subclass (the
185    * type of which was set with MobilityHelper::SetMobilityModel), aggregates
186    * it to the provided node, and sets an initial position based on the current
187    * position allocator (set through MobilityHelper::SetPositionAllocator).
188    *
189    * \param node The node to "layout."
190    */
191   void Install (Ptr<Node> node) const;
192   /**
193    * \brief "Layout" a single node according to the current position allocator type.
194    *
195    * This method creates an instance of a ns3::MobilityModel subclass (the
196    * type of which was set with MobilityHelper::SetMobilityModel), aggregates
197    * it to the provided node, and sets an initial position based on the current
198    * position allocator (set through MobilityHelper::SetPositionAllocator).
199    *
200    * \param nodeName The name of the node to "layout."
201    */
202   void Install (std::string nodeName) const;
203 
204   /**
205    * \brief Layout a collection of nodes according to the current position allocator type.
206    *
207    * For each node in the provided NodeContainer, this method creates an instance
208    * of a ns3::MobilityModel subclass (the type of which was set with
209    * MobilityHelper::SetMobilityModel), aggregates it to the node, and sets an
210    * initial position based on the current position allocator (set through
211    * MobilityHelper::SetPositionAllocator).
212    *
213    * \param container The set of nodes to layout.
214    */
215   void Install (NodeContainer container) const;
216 
217   /**
218    * Perform the work of MobilityHelper::Install on _all_ nodes which
219    * exist in the simulation.
220    */
221   void InstallAll (void);
222 
223   /**
224    * \param stream an output stream wrapper
225    * \param nodeid the id of the node to generate ascii output for.
226    *
227    * Enable ascii output to record course changes from the mobility model
228    * associated with the specified nodeid and dump that to the specified output
229    * stream.  If the Node does not have a MobilityModel aggregated,
230    * this method will not produce any output.
231    */
232   static void EnableAscii (Ptr<OutputStreamWrapper> stream, uint32_t nodeid);
233   /**
234    * \param stream an output stream wrapper
235    * \param n node container
236    *
237    * Enable ascii output to record course changes from the mobility models
238    * associated to the the nodes in the input container and dump that to the
239    * specified output stream.  Nodes that do not have a MobilityModel
240    * aggregated will not result in any output.
241    */
242   static void EnableAscii (Ptr<OutputStreamWrapper> stream, NodeContainer n);
243   /**
244    * \param stream an output stream wrapper
245    *
246    * Enable ascii output to record course changes from the mobility models
247    * associated to every node in the system and dump that to the specified
248    * output stream.  Nodes that do not have a MobilityModel aggregated
249    * will not result in any output.
250    */
251   static void EnableAsciiAll (Ptr<OutputStreamWrapper> stream);
252   /**
253    * Assign a fixed random variable stream number to the random variables
254    * used by the mobility models on these nodes. Return the number of
255    * streams (possibly zero) that have been assigned. The Install()
256    * method should have previously been called by the user.
257    *
258    * \note If the PositionAllocator used contains random variables, they
259    * will not be affected by this call to AssignStreams because they are
260    * used earlier during Install() time.  If the user needs to assign a fixed
261    * stream number to a PositionAllocator used with this helper, the user
262    * should instantiate it outside of the helper, call AssignStreams() on
263    * it, and then pass the pointer of it to this helper.
264    *
265    * \param c NodeContainer of the set of nodes for which the MobilityModels
266    * should be modified to use a fixed stream
267    * \param stream first stream index to use
268    * \return the number of stream indices assigned by this helper
269    */
270   int64_t AssignStreams (NodeContainer c, int64_t stream);
271 
272   /**
273    * \param n1 node 1
274    * \param n2 node 2
275    * \return the distance (squared), in meters, between two nodes
276    */
277   static double GetDistanceSquaredBetween (Ptr<Node> n1, Ptr<Node> n2);
278 
279 private:
280 
281   /**
282    * Output course change events from mobility model to output stream
283    * \param stream output stream
284    * \param mobility mobility model
285    */
286   static void CourseChanged (Ptr<OutputStreamWrapper> stream, Ptr<const MobilityModel> mobility);
287   std::vector<Ptr<MobilityModel> > m_mobilityStack; //!< Internal stack of mobility models
288   ObjectFactory m_mobility; //!< Object factory to create mobility objects
289   Ptr<PositionAllocator> m_position; //!< Position allocator for use in hierarchical mobility model
290 };
291 
292 } // namespace ns3
293 
294 #endif /* MOBILITY_HELPER_H */
295