satellite-group-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions Ltd
4  * Copyright (c) 2018 CNES
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Bastien Tauran <bastien.tauran@viveris.fr>
20  */
21 
22 #include "satellite-group-helper.h"
23 
24 #include <ns3/log.h>
25 #include <ns3/satellite-id-mapper.h>
26 #include <ns3/satellite-topology.h>
27 #include <ns3/singleton.h>
28 
29 #include <algorithm>
30 #include <list>
31 #include <map>
32 #include <set>
33 #include <utility>
34 #include <vector>
35 
36 NS_LOG_COMPONENT_DEFINE("SatGroupHelper");
37 
38 namespace ns3
39 {
40 
41 NS_OBJECT_ENSURE_REGISTERED(SatGroupHelper);
42 
43 TypeId
45 {
46  static TypeId tid =
47  TypeId("ns3::SatGroupHelper").SetParent<Object>().AddConstructor<SatGroupHelper>();
48  return tid;
49 }
50 
51 TypeId
53 {
54  NS_LOG_FUNCTION(this);
55 
56  return GetTypeId();
57 }
58 
60  : m_scenarioCreated(false),
61  m_satConstellationEnabled(false)
62 {
63  NS_LOG_FUNCTION(this);
64 }
65 
66 void
68 {
69  NS_LOG_FUNCTION(this);
70 
71  m_groupsMap.clear();
72 }
73 
74 void
76 {
77  NS_LOG_FUNCTION(this);
78 
79  m_scenarioCreated = true;
80 
81  for (std::map<Ptr<Node>, uint32_t>::iterator it = m_nodesToAdd.begin();
82  it != m_nodesToAdd.end();
83  it++)
84  {
85  AddUtNodeToGroup(it->second, it->first);
86  }
87 }
88 
89 void
90 SatGroupHelper::AddUtNodeToGroup(uint32_t groupId, Ptr<Node> node)
91 {
92  NS_LOG_FUNCTION(this << groupId << node);
93 
94  if (m_scenarioCreated == false)
95  {
96  NS_FATAL_ERROR("Method SatGroupHelper::AddUtNodeToGroup has to be called after "
97  "SimulationHelper::CreateSatScenario");
98  }
99 
100  if (groupId == 0 && !m_satConstellationEnabled)
101  {
102  NS_FATAL_ERROR("Group ID 0 is reserved for UTs not manually assigned to a group");
103  }
104 
105  if (GetGroupId(node) != 0)
106  {
107  NS_FATAL_ERROR("Node " << node << " is already in group " << GetGroupId(node)
108  << ". It cannot be added to group " << groupId);
109  }
110 
111  if (IsGroupExisting(groupId) == false)
112  {
113  m_groupsList.push_back(groupId);
114  m_groupsMap[groupId] = std::set<Ptr<Node>>();
115  }
116  m_groupsMap[groupId].insert(node);
117  Singleton<SatIdMapper>::Get()->AttachMacToGroupId(
118  Singleton<SatIdMapper>::Get()->GetUtMacWithNode(node),
119  groupId);
120 
121  Singleton<SatTopology>::Get()->UpdateUtGroup(node, groupId);
122 }
123 
124 void
125 SatGroupHelper::AddUtNodesToGroup(uint32_t groupId, NodeContainer nodes)
126 {
127  NS_LOG_FUNCTION(this << groupId);
128 
129  if (m_scenarioCreated == false)
130  {
131  NS_FATAL_ERROR("Method SatGroupHelper::AddUtNodesToGroup has to be called after "
132  "SimulationHelper::CreateSatScenario");
133  }
134 
135  for (NodeContainer::Iterator it = nodes.Begin(); it != nodes.End(); it++)
136  {
137  AddUtNodeToGroup(groupId, *it);
138  }
139 }
140 
141 void
143  NodeContainer nodes,
144  GeoCoordinate center,
145  uint32_t radius)
146 {
147  NS_LOG_FUNCTION(this << groupId << center << radius);
148 
149  if (m_scenarioCreated == false)
150  {
151  NS_FATAL_ERROR("Method SatGroupHelper::CreateGroupFromPosition has to be called after "
152  "SimulationHelper::CreateSatScenario");
153  }
154 
155  if (groupId == 0)
156  {
157  NS_FATAL_ERROR("Cannot create new geographical group with a group ID of zero.");
158  }
159  if (GetUtNodes(groupId).GetN() != 0)
160  {
161  NS_FATAL_ERROR("Cannot create new geographical group with a group ID already used.");
162  }
163 
164  Vector centerPosition = center.ToVector();
165  GeoCoordinate nodePosition;
166  double distance;
167  NodeContainer nodesNotAlreadyAdded = GetNodesNotAddedFromPosition(nodes);
168  for (NodeContainer::Iterator it = nodesNotAlreadyAdded.Begin();
169  it != nodesNotAlreadyAdded.End();
170  it++)
171  {
172  nodePosition = (*it)->GetObject<SatMobilityModel>()->GetGeoPosition();
173  distance = CalculateDistance(centerPosition, nodePosition.ToVector());
174  if (distance <= radius)
175  {
176  AddUtNodeToGroup(groupId, *it);
177  }
178  }
179 }
180 
181 void
182 SatGroupHelper::CreateGroupsUniformly(std::vector<uint32_t> groupIds, NodeContainer nodes)
183 {
184  NS_LOG_FUNCTION(this << groupIds);
185 
186  if (m_scenarioCreated == false)
187  {
188  NS_FATAL_ERROR("Method SatGroupHelper::CreateGroupsUniformly has to be called after "
189  "SimulationHelper::CreateSatScenario");
190  }
191 
192  for (uint32_t groupId : groupIds)
193  {
194  if (GetUtNodes(groupId).GetN() != 0)
195  {
196  NS_FATAL_ERROR("Cannot create new group with a group ID already used: " << groupId);
197  }
198  }
199 
200  NodeContainer nodesNotAlreadyAdded = GetNodesNotAddedFromPosition(nodes);
201 
202  uint32_t nbNodes = nodesNotAlreadyAdded.GetN();
203  uint32_t counter = 0;
204 
205  for (uint32_t i = 0; i < nbNodes; i++)
206  {
207  AddUtNodeToGroup(groupIds[counter], nodesNotAlreadyAdded.Get(i));
208  counter++;
209  counter %= groupIds.size();
210  }
211 }
212 
213 void
215  uint32_t nb,
216  GeoCoordinate center,
217  uint32_t radius)
218 {
219  NS_LOG_FUNCTION(this << groupId << nb << center << radius);
220 
221  if (m_scenarioCreated == true)
222  {
223  NS_FATAL_ERROR("Method SatGroupHelper::CreateUtNodesFromPosition has to be called before "
224  "SimulationHelper::CreateSatScenario");
225  }
226 
227  if (groupId == 0)
228  {
229  NS_FATAL_ERROR("Cannot call CreateUtNodesFromPosition with a group ID of zero.");
230  }
231  if (std::find(m_groupsList.begin(), m_groupsList.end(), groupId) != m_groupsList.end())
232  {
233  NS_FATAL_ERROR(
234  "Cannot call CreateUtNodesFromPosition with a group ID already used: " << groupId);
235  }
236 
237  Ptr<SatRandomCirclePositionAllocator> circleAllocator =
238  CreateObject<SatRandomCirclePositionAllocator>(center, radius);
239 
240  for (uint32_t i = 0; i < nb; i++)
241  {
242  GeoCoordinate position = circleAllocator->GetNextGeoPosition();
243  m_additionalNodesPerBeam.push_back(std::make_pair(position, groupId));
244  }
245 
246  m_groupsList.push_back(groupId);
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION(this << groupId << node);
253 
254  m_nodesToAdd[node] = groupId;
255 }
256 
257 std::vector<std::pair<GeoCoordinate, uint32_t>>
259 {
260  NS_LOG_FUNCTION(this);
261 
263 }
264 
265 NodeContainer
266 SatGroupHelper::GetUtNodes(uint32_t groupId) const
267 {
268  NS_LOG_FUNCTION(this << groupId);
269 
270  if (groupId == 0)
271  {
272  bool found;
273  NodeContainer groupIdZeroUts;
274  NodeContainer uts = Singleton<SatTopology>::Get()->GetUtNodes();
275  for (NodeContainer::Iterator it = uts.Begin(); it != uts.End(); it++)
276  {
277  found = false;
278  for (std::map<uint32_t, std::set<Ptr<Node>>>::const_iterator it2 = m_groupsMap.begin();
279  it2 != m_groupsMap.end();
280  it2++)
281  {
282  if (it2->second.find(*it) != it2->second.end())
283  {
284  found = true;
285  break;
286  }
287  }
288  if (found == false)
289  {
290  groupIdZeroUts.Add(*it);
291  }
292  }
293  return groupIdZeroUts;
294  }
295 
296  if (IsGroupExisting(groupId) == false)
297  {
298  return NodeContainer();
299  }
300 
301  NodeContainer utNodes;
302  std::set<Ptr<Node>> nodes = m_groupsMap.at(groupId);
303 
304  for (std::set<Ptr<Node>>::const_iterator i = nodes.begin(); i != nodes.end(); i++)
305  {
306  utNodes.Add(*i);
307  }
308 
309  return utNodes;
310 }
311 
312 uint32_t
314 {
315  NS_LOG_FUNCTION(this);
316 
317  return m_groupsMap.size();
318 }
319 
320 std::list<uint32_t>
322 {
323  return m_groupsList;
324 }
325 
326 void
328 {
330 }
331 
332 bool
333 SatGroupHelper::IsGroupExisting(uint32_t groupId) const
334 {
335  return m_groupsMap.find(groupId) != m_groupsMap.end();
336 }
337 
338 uint32_t
339 SatGroupHelper::GetGroupId(Ptr<Node> node) const
340 {
341  for (std::map<uint32_t, std::set<Ptr<Node>>>::const_iterator it = m_groupsMap.begin();
342  it != m_groupsMap.end();
343  it++)
344  {
345  if (it->second.find(node) != it->second.end())
346  {
347  return it->first;
348  }
349  }
350  return 0;
351 }
352 
353 NodeContainer
355 {
356  NS_LOG_FUNCTION(this);
357 
358  NodeContainer nodesFiltered;
359  Ptr<Node> node;
360  for (uint32_t i = 0; i < nodes.GetN(); i++)
361  {
362  node = nodes.Get(i);
363  if (m_nodesToAdd.count(node) == 0)
364  {
365  nodesFiltered.Add(node);
366  }
367  }
368  return nodesFiltered;
369 }
370 
371 } // namespace ns3
GeoCoordinate class is used to store and operate with geodetic coordinates.
Vector ToVector() const
Converts Geodetic coordinates to Cartesian coordinates.
std::list< uint32_t > GetGroups()
Get the list of groups created.
virtual void DoDispose()
Dispose of this class instance.
NodeContainer GetUtNodes(uint32_t groupId) const
uint32_t GetN()
Count the number of groups created.
void AddUtNodesToGroup(uint32_t groupId, NodeContainer nodes)
Add several nodes to a group.
void Init()
Initialize the helper.
void CreateUtNodesFromPosition(uint32_t groupId, uint32_t nb, GeoCoordinate center, uint32_t radius)
Create a new group using a central position and a radius, and create UT nodes inside this area.
static TypeId GetTypeId(void)
Get the type ID.
std::map< Ptr< Node >, uint32_t > m_nodesToAdd
std::map< uint32_t, std::set< Ptr< Node > > > m_groupsMap
Container to associate nodes to the groups.
void AddNodeToGroupAfterScenarioCreation(uint32_t groupId, Ptr< Node > node)
Schedule a node to be added to a group when scenario creation is finished.
std::list< uint32_t > m_groupsList
List of group ID created.
virtual TypeId GetInstanceTypeId(void) const
Get the type ID of instance.
bool m_satConstellationEnabled
Use a constellation of satellites.
void CreateGroupsUniformly(std::vector< uint32_t > groupIds, NodeContainer nodes)
Create several groups and distribute nodes among them.
NodeContainer GetNodesNotAddedFromPosition(NodeContainer nodes)
Get list of nodes not created from position by group helper.
bool IsGroupExisting(uint32_t groupId) const
Tells if the groupId is already existing in the database.
std::vector< std::pair< GeoCoordinate, uint32_t > > GetAdditionalNodesPerBeam()
Get the position of nodes to add to the scenario.
SatGroupHelper()
Default constructor for SatGroupHelper.
uint32_t GetGroupId(Ptr< Node > node) const
Get the group to which a node belongs.
void CreateGroupFromPosition(uint32_t groupId, NodeContainer nodes, GeoCoordinate center, uint32_t radius)
Create a new group using a central position and a radius.
std::vector< std::pair< GeoCoordinate, uint32_t > > m_additionalNodesPerBeam
Nodes created by position to add to scenario.
void AddUtNodeToGroup(uint32_t groupId, Ptr< Node > node)
Add a node to a group.
Keep track of the current position and velocity of an object in satellite network.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.