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/singleton.h>
27 
28 NS_LOG_COMPONENT_DEFINE("SatGroupHelper");
29 
30 namespace ns3
31 {
32 
33 NS_OBJECT_ENSURE_REGISTERED(SatGroupHelper);
34 
35 TypeId
37 {
38  static TypeId tid =
39  TypeId("ns3::SatGroupHelper").SetParent<Object>().AddConstructor<SatGroupHelper>();
40  return tid;
41 }
42 
43 TypeId
45 {
46  NS_LOG_FUNCTION(this);
47 
48  return GetTypeId();
49 }
50 
52  : m_scenarioCreated(false),
53  m_satConstellationEnabled(false)
54 {
55  NS_LOG_FUNCTION(this);
56 }
57 
58 void
60 {
61  NS_LOG_FUNCTION(this);
62 
63  m_groupsMap.clear();
64 }
65 
66 void
67 SatGroupHelper::Init(NodeContainer uts)
68 {
69  NS_LOG_FUNCTION(this);
70  m_uts = uts;
71 
72  m_scenarioCreated = true;
73 
74  for (std::map<Ptr<Node>, uint32_t>::iterator it = m_nodesToAdd.begin();
75  it != m_nodesToAdd.end();
76  it++)
77  {
78  AddUtNodeToGroup(it->second, it->first);
79  }
80 }
81 
82 void
83 SatGroupHelper::AddUtNodeToGroup(uint32_t groupId, Ptr<Node> node)
84 {
85  NS_LOG_FUNCTION(this << groupId << node);
86 
87  if (m_scenarioCreated == false)
88  {
89  NS_FATAL_ERROR("Method SatGroupHelper::AddUtNodeToGroup has to be called after "
90  "SimulationHelper::CreateSatScenario");
91  }
92 
93  if (groupId == 0 && !m_satConstellationEnabled)
94  {
95  NS_FATAL_ERROR("Group ID 0 is reserved for UTs not manually assigned to a group");
96  }
97 
98  if (GetGroupId(node) != 0)
99  {
100  NS_FATAL_ERROR("Node " << node << " is already in group " << GetGroupId(node)
101  << ". It cannot be added to group " << groupId);
102  }
103 
104  if (IsGroupExisting(groupId) == false)
105  {
106  m_groupsList.push_back(groupId);
107  m_groupsMap[groupId] = std::set<Ptr<Node>>();
108  }
109  m_groupsMap[groupId].insert(node);
110  Singleton<SatIdMapper>::Get()->AttachMacToGroupId(
111  Singleton<SatIdMapper>::Get()->GetUtMacWithNode(node),
112  groupId);
113 }
114 
115 void
116 SatGroupHelper::AddUtNodesToGroup(uint32_t groupId, NodeContainer nodes)
117 {
118  NS_LOG_FUNCTION(this << groupId);
119 
120  if (m_scenarioCreated == false)
121  {
122  NS_FATAL_ERROR("Method SatGroupHelper::AddUtNodesToGroup has to be called after "
123  "SimulationHelper::CreateSatScenario");
124  }
125 
126  for (NodeContainer::Iterator it = nodes.Begin(); it != nodes.End(); it++)
127  {
128  AddUtNodeToGroup(groupId, *it);
129  }
130 }
131 
132 void
134  NodeContainer nodes,
135  GeoCoordinate center,
136  uint32_t radius)
137 {
138  NS_LOG_FUNCTION(this << groupId << center << radius);
139 
140  if (m_scenarioCreated == false)
141  {
142  NS_FATAL_ERROR("Method SatGroupHelper::CreateGroupFromPosition has to be called after "
143  "SimulationHelper::CreateSatScenario");
144  }
145 
146  if (groupId == 0)
147  {
148  NS_FATAL_ERROR("Cannot create new geographical group with a group ID of zero.");
149  }
150  if (GetUtNodes(groupId).GetN() != 0)
151  {
152  NS_FATAL_ERROR("Cannot create new geographical group with a group ID already used.");
153  }
154 
155  Vector centerPosition = center.ToVector();
156  GeoCoordinate nodePosition;
157  double distance;
158  NodeContainer nodesNotAlreadyAdded = GetNodesNotAddedFromPosition(nodes);
159  for (NodeContainer::Iterator it = nodesNotAlreadyAdded.Begin();
160  it != nodesNotAlreadyAdded.End();
161  it++)
162  {
163  nodePosition = (*it)->GetObject<SatMobilityModel>()->GetGeoPosition();
164  distance = CalculateDistance(centerPosition, nodePosition.ToVector());
165  if (distance <= radius)
166  {
167  AddUtNodeToGroup(groupId, *it);
168  }
169  }
170 }
171 
172 void
173 SatGroupHelper::CreateGroupsUniformly(std::vector<uint32_t> groupIds, NodeContainer nodes)
174 {
175  NS_LOG_FUNCTION(this << groupIds);
176 
177  if (m_scenarioCreated == false)
178  {
179  NS_FATAL_ERROR("Method SatGroupHelper::CreateGroupsUniformly has to be called after "
180  "SimulationHelper::CreateSatScenario");
181  }
182 
183  for (uint32_t groupId : groupIds)
184  {
185  if (GetUtNodes(groupId).GetN() != 0)
186  {
187  NS_FATAL_ERROR("Cannot create new group with a group ID already used: " << groupId);
188  }
189  }
190 
191  NodeContainer nodesNotAlreadyAdded = GetNodesNotAddedFromPosition(nodes);
192 
193  uint32_t nbNodes = nodesNotAlreadyAdded.GetN();
194  uint32_t counter = 0;
195 
196  for (uint32_t i = 0; i < nbNodes; i++)
197  {
198  AddUtNodeToGroup(groupIds[counter], nodesNotAlreadyAdded.Get(i));
199  counter++;
200  counter %= groupIds.size();
201  }
202 }
203 
204 void
206  uint32_t nb,
207  GeoCoordinate center,
208  uint32_t radius)
209 {
210  NS_LOG_FUNCTION(this << groupId << nb << center << radius);
211 
212  if (m_scenarioCreated == true)
213  {
214  NS_FATAL_ERROR("Method SatGroupHelper::CreateUtNodesFromPosition has to be called before "
215  "SimulationHelper::CreateSatScenario");
216  }
217 
218  if (groupId == 0)
219  {
220  NS_FATAL_ERROR("Cannot call CreateUtNodesFromPosition with a group ID of zero.");
221  }
222  if (std::find(m_groupsList.begin(), m_groupsList.end(), groupId) != m_groupsList.end())
223  {
224  NS_FATAL_ERROR(
225  "Cannot call CreateUtNodesFromPosition with a group ID already used: " << groupId);
226  }
227 
228  Ptr<SatRandomCirclePositionAllocator> circleAllocator =
229  CreateObject<SatRandomCirclePositionAllocator>(center, radius);
230 
231  for (uint32_t i = 0; i < nb; i++)
232  {
233  GeoCoordinate position = circleAllocator->GetNextGeoPosition();
234  m_additionalNodesPerBeam.push_back(std::make_pair(position, groupId));
235  }
236 
237  m_groupsList.push_back(groupId);
238 }
239 
240 void
242 {
243  NS_LOG_FUNCTION(this << groupId << node);
244 
245  m_nodesToAdd[node] = groupId;
246 }
247 
248 std::vector<std::pair<GeoCoordinate, uint32_t>>
250 {
251  NS_LOG_FUNCTION(this);
252 
254 }
255 
256 NodeContainer
257 SatGroupHelper::GetUtNodes(uint32_t groupId) const
258 {
259  NS_LOG_FUNCTION(this << groupId);
260 
261  if (groupId == 0)
262  {
263  bool found;
264  NodeContainer groupIdZeroUts;
265  for (NodeContainer::Iterator it = m_uts.Begin(); it != m_uts.End(); it++)
266  {
267  found = false;
268  for (std::map<uint32_t, std::set<Ptr<Node>>>::const_iterator it2 = m_groupsMap.begin();
269  it2 != m_groupsMap.end();
270  it2++)
271  {
272  if (it2->second.find(*it) != it2->second.end())
273  {
274  found = true;
275  break;
276  }
277  }
278  if (found == false)
279  {
280  groupIdZeroUts.Add(*it);
281  }
282  }
283  return groupIdZeroUts;
284  }
285 
286  if (IsGroupExisting(groupId) == false)
287  {
288  return NodeContainer();
289  }
290 
291  NodeContainer utNodes;
292  std::set<Ptr<Node>> nodes = m_groupsMap.at(groupId);
293 
294  for (std::set<Ptr<Node>>::const_iterator i = nodes.begin(); i != nodes.end(); i++)
295  {
296  utNodes.Add(*i);
297  }
298 
299  return utNodes;
300 }
301 
302 uint32_t
304 {
305  NS_LOG_FUNCTION(this);
306 
307  return m_groupsMap.size();
308 }
309 
310 std::list<uint32_t>
312 {
313  return m_groupsList;
314 }
315 
316 void
318 {
320 }
321 
322 bool
323 SatGroupHelper::IsGroupExisting(uint32_t groupId) const
324 {
325  return m_groupsMap.find(groupId) != m_groupsMap.end();
326 }
327 
328 uint32_t
329 SatGroupHelper::GetGroupId(Ptr<Node> node) const
330 {
331  for (std::map<uint32_t, std::set<Ptr<Node>>>::const_iterator it = m_groupsMap.begin();
332  it != m_groupsMap.end();
333  it++)
334  {
335  if (it->second.find(node) != it->second.end())
336  {
337  return it->first;
338  }
339  }
340  return 0;
341 }
342 
343 NodeContainer
345 {
346  NS_LOG_FUNCTION(this);
347 
348  NodeContainer nodesFiltered;
349  Ptr<Node> node;
350  for (uint32_t i = 0; i < nodes.GetN(); i++)
351  {
352  node = nodes.Get(i);
353  if (m_nodesToAdd.count(node) == 0)
354  {
355  nodesFiltered.Add(node);
356  }
357  }
358  return nodesFiltered;
359 }
360 
361 } // 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.
void Init(NodeContainer uts)
Initialize the helper.
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.
NodeContainer m_uts
The list of all the UTs in the simulation.
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.