From 736e5950fcf262fc2d53d795db8acfe48c3e26a9 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 14 Sep 2021 17:08:44 -0700 Subject: [PATCH] mobility: Add GroupMobilityHelper class --- src/mobility/helper/group-mobility-helper.cc | 239 +++++++++++++++ src/mobility/helper/group-mobility-helper.h | 289 +++++++++++++++++++ src/mobility/wscript | 2 + 3 files changed, 530 insertions(+) create mode 100644 src/mobility/helper/group-mobility-helper.cc create mode 100644 src/mobility/helper/group-mobility-helper.h diff --git a/src/mobility/helper/group-mobility-helper.cc b/src/mobility/helper/group-mobility-helper.cc new file mode 100644 index 000000000..d4954ba73 --- /dev/null +++ b/src/mobility/helper/group-mobility-helper.cc @@ -0,0 +1,239 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * Copyright (c) 2021 University of Washington: Group mobility changes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + * Adapted from 'mobility-helper.cc' for group mobility by Tom Henderson + */ + +#include "ns3/group-mobility-helper.h" +#include "ns3/mobility-model.h" +#include "ns3/position-allocator.h" +#include "ns3/hierarchical-mobility-model.h" +#include "ns3/log.h" +#include "ns3/pointer.h" +#include "ns3/config.h" +#include "ns3/simulator.h" +#include "ns3/names.h" +#include "ns3/string.h" +#include + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("GroupMobilityHelper"); + +GroupMobilityHelper::GroupMobilityHelper () +{ +} + +GroupMobilityHelper::~GroupMobilityHelper () +{ +} + +void +GroupMobilityHelper::SetReferencePositionAllocator (Ptr allocator) +{ + m_referencePosition = allocator; +} + +void +GroupMobilityHelper::SetReferencePositionAllocator (std::string type, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7, + std::string n8, const AttributeValue &v8, + std::string n9, const AttributeValue &v9) +{ + ObjectFactory pos; + pos.SetTypeId (type); + pos.Set (n1, v1); + pos.Set (n2, v2); + pos.Set (n3, v3); + pos.Set (n4, v4); + pos.Set (n5, v5); + pos.Set (n6, v6); + pos.Set (n7, v7); + pos.Set (n8, v8); + pos.Set (n9, v9); + m_referencePosition = pos.Create ()->GetObject (); + NS_ABORT_MSG_IF (m_referencePosition == nullptr, "Unable to create allocator from TypeId " << type); +} + +void +GroupMobilityHelper::SetMemberPositionAllocator (Ptr allocator) +{ + m_memberPosition = allocator; +} + +void +GroupMobilityHelper::SetMemberPositionAllocator (std::string type, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7, + std::string n8, const AttributeValue &v8, + std::string n9, const AttributeValue &v9) +{ + ObjectFactory pos; + pos.SetTypeId (type); + pos.Set (n1, v1); + pos.Set (n2, v2); + pos.Set (n3, v3); + pos.Set (n4, v4); + pos.Set (n5, v5); + pos.Set (n6, v6); + pos.Set (n7, v7); + pos.Set (n8, v8); + pos.Set (n9, v9); + m_memberPosition = pos.Create ()->GetObject (); + NS_ABORT_MSG_IF (m_memberPosition == nullptr, "Unable to create allocator from TypeId " << type); +} + +void +GroupMobilityHelper::SetReferenceMobilityModel (Ptr mobility) +{ + m_referenceMobility = mobility; +} + +void +GroupMobilityHelper::SetReferenceMobilityModel (std::string type, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7, + std::string n8, const AttributeValue &v8, + std::string n9, const AttributeValue &v9) +{ + NS_LOG_FUNCTION (this << type); + ObjectFactory mob; + mob.SetTypeId (type); + mob.Set (n1, v1); + mob.Set (n2, v2); + mob.Set (n3, v3); + mob.Set (n4, v4); + mob.Set (n5, v5); + mob.Set (n6, v6); + mob.Set (n7, v7); + mob.Set (n8, v8); + mob.Set (n9, v9); + m_referenceMobility = mob.Create ()->GetObject (); + NS_ABORT_MSG_IF (m_referenceMobility == nullptr, "Unable to create mobility from TypeId " << type); +} + +void +GroupMobilityHelper::SetMemberMobilityModel (std::string type, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7, + std::string n8, const AttributeValue &v8, + std::string n9, const AttributeValue &v9) +{ + NS_LOG_FUNCTION (this << type); + m_memberMobilityFactory.SetTypeId (type); + m_memberMobilityFactory.Set (n1, v1); + m_memberMobilityFactory.Set (n2, v2); + m_memberMobilityFactory.Set (n3, v3); + m_memberMobilityFactory.Set (n4, v4); + m_memberMobilityFactory.Set (n5, v5); + m_memberMobilityFactory.Set (n6, v6); + m_memberMobilityFactory.Set (n7, v7); + m_memberMobilityFactory.Set (n8, v8); + m_memberMobilityFactory.Set (n9, v9); +} + +void +GroupMobilityHelper::Install (Ptr node) +{ + NS_ABORT_MSG_IF (node->GetObject () != nullptr, "Mobility model already installed"); + NS_ABORT_MSG_IF (m_referenceMobility == nullptr, "Reference mobility model is empty"); + NS_ABORT_MSG_UNLESS (m_memberMobilityFactory.IsTypeIdSet (), "Member mobility factory is unset"); + if (m_referencePosition && !m_referencePositionSet) + { + Vector referencePosition = m_referencePosition->GetNext (); + m_referenceMobility->SetPosition (referencePosition); + m_referencePositionSet = true; + } + Ptr hierarchical = CreateObject (); + hierarchical->SetParent (m_referenceMobility); + Ptr child = m_memberMobilityFactory.Create ()->GetObject (); + NS_ABORT_MSG_IF (child == nullptr, "Member mobility factory did not produce a MobilityModel"); + if (m_memberPosition) + { + Vector position = m_memberPosition->GetNext (); + child->SetPosition (position); + } + hierarchical->SetChild (child); + NS_LOG_DEBUG ("node="<GetParent ()->AssignStreams (currentStream); + firstNode = false; + } + currentStream += mobility->GetChild ()->AssignStreams (currentStream); + } + return (currentStream - stream); +} + +} // namespace ns3 diff --git a/src/mobility/helper/group-mobility-helper.h b/src/mobility/helper/group-mobility-helper.h new file mode 100644 index 000000000..5c39a6608 --- /dev/null +++ b/src/mobility/helper/group-mobility-helper.h @@ -0,0 +1,289 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * Copyright (c) 2021 University of Washington: Group mobility changes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Mathieu Lacage + * Adapted from 'mobility-helper.h' for group mobility by Tom Henderson + */ + +#ifndef GROUP_MOBILITY_HELPER_H +#define GROUP_MOBILITY_HELPER_H + +#include +#include "ns3/object-factory.h" +#include "ns3/attribute.h" +#include "ns3/node-container.h" + +namespace ns3 { + +class PositionAllocator; +class MobilityModel; + +/** + * \ingroup mobility + * \brief Helper class used to assign positions and mobility models to nodes + * for a group mobility configuration. + * + * This helper can be used for group mobility configuration and installation + * onto a group of nodes, in which there is a reference (parent) mobility + * model that is the same for all nodes, and similarly configured (but + * distinct) child mobility models. + */ +class GroupMobilityHelper +{ +public: + /** + * Construct a group mobility helper + */ + GroupMobilityHelper (); + + /** + * Destroy a group mobility helper + */ + ~GroupMobilityHelper (); + + /** + * Set the position allocator which will be used to allocate the initial + * position of the reference mobility model. + * + * \param allocator allocate initial reference mobility model position + */ + void SetReferencePositionAllocator (Ptr allocator); + + /** + * Configure the position allocator which will be used to allocate + * the initial position of the reference mobility model. + * + * \param type the type of mobility model to use. + * \param n1 the name of the attribute to set in the mobility model. + * \param v1 the value of the attribute to set in the mobility model. + * \param n2 the name of the attribute to set in the mobility model. + * \param v2 the value of the attribute to set in the mobility model. + * \param n3 the name of the attribute to set in the mobility model. + * \param v3 the value of the attribute to set in the mobility model. + * \param n4 the name of the attribute to set in the mobility model. + * \param v4 the value of the attribute to set in the mobility model. + * \param n5 the name of the attribute to set in the mobility model. + * \param v5 the value of the attribute to set in the mobility model. + * \param n6 the name of the attribute to set in the mobility model. + * \param v6 the value of the attribute to set in the mobility model. + * \param n7 the name of the attribute to set in the mobility model. + * \param v7 the value of the attribute to set in the mobility model. + * \param n8 the name of the attribute to set in the mobility model. + * \param v8 the value of the attribute to set in the mobility model. + * \param n9 the name of the attribute to set in the mobility model. + * \param v9 the value of the attribute to set in the mobility model. + */ + void SetReferencePositionAllocator (std::string type, + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (), + std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (), + std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ()); + + /** + * Set the position allocator which will be used to allocate the initial + * position of the member mobility models. + * + * \param allocator allocate initial member mobility model positions + */ + void SetMemberPositionAllocator (Ptr allocator); + + /** + * Configure the position allocator which will be used to allocate the + * initial position of the member mobility models. + * + * \param type the type of mobility model to use. + * \param n1 the name of the attribute to set in the mobility model. + * \param v1 the value of the attribute to set in the mobility model. + * \param n2 the name of the attribute to set in the mobility model. + * \param v2 the value of the attribute to set in the mobility model. + * \param n3 the name of the attribute to set in the mobility model. + * \param v3 the value of the attribute to set in the mobility model. + * \param n4 the name of the attribute to set in the mobility model. + * \param v4 the value of the attribute to set in the mobility model. + * \param n5 the name of the attribute to set in the mobility model. + * \param v5 the value of the attribute to set in the mobility model. + * \param n6 the name of the attribute to set in the mobility model. + * \param v6 the value of the attribute to set in the mobility model. + * \param n7 the name of the attribute to set in the mobility model. + * \param v7 the value of the attribute to set in the mobility model. + * \param n8 the name of the attribute to set in the mobility model. + * \param v8 the value of the attribute to set in the mobility model. + * \param n9 the name of the attribute to set in the mobility model. + * \param v9 the value of the attribute to set in the mobility model. + */ + void SetMemberPositionAllocator (std::string type, + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (), + std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (), + std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ()); + + /** + * Set the reference mobility model which will be installed as the parent + * mobility model during GroupMobilityModel::Install. + * + * \param mobility reference mobility model + */ + void SetReferenceMobilityModel (Ptr mobility); + + /** + * Configure the reference mobility model which will be installed as the + * parent mobility model during GroupMobilityModel::Install. + * + * \param type the type of mobility model to use. + * \param n1 the name of the attribute to set in the mobility model. + * \param v1 the value of the attribute to set in the mobility model. + * \param n2 the name of the attribute to set in the mobility model. + * \param v2 the value of the attribute to set in the mobility model. + * \param n3 the name of the attribute to set in the mobility model. + * \param v3 the value of the attribute to set in the mobility model. + * \param n4 the name of the attribute to set in the mobility model. + * \param v4 the value of the attribute to set in the mobility model. + * \param n5 the name of the attribute to set in the mobility model. + * \param v5 the value of the attribute to set in the mobility model. + * \param n6 the name of the attribute to set in the mobility model. + * \param v6 the value of the attribute to set in the mobility model. + * \param n7 the name of the attribute to set in the mobility model. + * \param v7 the value of the attribute to set in the mobility model. + * \param n8 the name of the attribute to set in the mobility model. + * \param v8 the value of the attribute to set in the mobility model. + * \param n9 the name of the attribute to set in the mobility model. + * \param v9 the value of the attribute to set in the mobility model. + */ + void SetReferenceMobilityModel (std::string type, + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (), + std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (), + std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ()); + + /** + * Configure the mobility model which will be installed as the + * member (child) mobility model during GroupMobilityModel::Install. + * + * \param type the type of mobility model to use. + * \param n1 the name of the attribute to set in the mobility model. + * \param v1 the value of the attribute to set in the mobility model. + * \param n2 the name of the attribute to set in the mobility model. + * \param v2 the value of the attribute to set in the mobility model. + * \param n3 the name of the attribute to set in the mobility model. + * \param v3 the value of the attribute to set in the mobility model. + * \param n4 the name of the attribute to set in the mobility model. + * \param v4 the value of the attribute to set in the mobility model. + * \param n5 the name of the attribute to set in the mobility model. + * \param v5 the value of the attribute to set in the mobility model. + * \param n6 the name of the attribute to set in the mobility model. + * \param v6 the value of the attribute to set in the mobility model. + * \param n7 the name of the attribute to set in the mobility model. + * \param v7 the value of the attribute to set in the mobility model. + * \param n8 the name of the attribute to set in the mobility model. + * \param v8 the value of the attribute to set in the mobility model. + * \param n9 the name of the attribute to set in the mobility model. + * \param v9 the value of the attribute to set in the mobility model. + * + * Calls to MobilityHelper::Install will create an instance of a matching + * mobility model for each node. + */ + void SetMemberMobilityModel (std::string type, + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (), + std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (), + std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ()); + + /** + * \brief Install and configure a hierarchical mobility model to the + * given node, based on the configured reference and member models. + * + * If position allocators are configured, they will be invoked to + * set the initial position. + * + * \param node The node to configure + */ + void Install (Ptr node); + /** + * \brief Install and configure a hierarchical mobility model to the + * given node, based on the configured reference and member models. + * + * If position allocators are configured, they will be invoked to + * set the initial position. + * + * \param nodeName The name of the node to configure + */ + void Install (std::string nodeName); + + /** + * \brief Install and configure a hierarchical mobility model to all nodes + * in the container, based on the configured reference and member models. + * + * If position allocators are configured, they will be invoked to + * set the initial positions. + * + * \param container The set of nodes to configure + */ + void Install (NodeContainer container); + + /** + * Assign a fixed random variable stream number to the random variables + * used by the mobility models on these nodes. Return the number of + * streams (possibly zero) that have been assigned. The Install() + * method should have previously been called by the user. + * + * \note If the PositionAllocator used contains random variables, they + * will not be affected by this call to AssignStreams because they are + * used earlier during Install() time. If the user needs to assign a fixed + * stream number to a PositionAllocator used with this helper, the user + * should instantiate it outside of the helper, call AssignStreams() on + * it, and then pass the pointer of it to this helper. + * + * \param c NodeContainer of the set of nodes containing the MobilityModels + * that should be modified to use a fixed stream + * \param stream first stream index to use + * \return the number of stream indices assigned by this helper + */ + int64_t AssignStreams (NodeContainer c, int64_t stream); + +private: + + bool m_referencePositionSet {false}; //!< flag for avoiding multiple SetPosition calls on the reference model + Ptr m_referenceMobility; //!< Reference mobility model + Ptr m_referencePosition; //!< Position allocator for use as reference position allocator + ObjectFactory m_memberMobilityFactory; //!< Object factory to create member mobility models + Ptr m_memberPosition; //!< Position allocator for use as member position allocator +}; + +} // namespace ns3 + +#endif /* GROUP_MOBILITY_HELPER_H */ diff --git a/src/mobility/wscript b/src/mobility/wscript index 05a3b4ab6..c171f3358 100644 --- a/src/mobility/wscript +++ b/src/mobility/wscript @@ -22,6 +22,7 @@ def build(bld): 'model/waypoint-mobility-model.cc', 'helper/mobility-helper.cc', 'helper/ns2-mobility-helper.cc', + 'helper/group-mobility-helper.cc', ] mobility_test = bld.create_ns3_module_test_library('mobility') @@ -64,6 +65,7 @@ def build(bld): 'model/waypoint-mobility-model.h', 'helper/mobility-helper.h', 'helper/ns2-mobility-helper.h', + 'helper/group-mobility-helper.h', ] if (bld.env['ENABLE_EXAMPLES']):