HierarchicalMobilityModel: allow the parent model to be NULL, make the child/parent setters public, and add more detailed documentation; closes bug #511

This commit is contained in:
Gustavo J. A. M. Carneiro
2009-04-17 15:35:22 +01:00
parent e65ce189da
commit 0c8ec6fa07
2 changed files with 101 additions and 17 deletions

View File

@@ -52,15 +52,46 @@ HierarchicalMobilityModel::HierarchicalMobilityModel ()
void
HierarchicalMobilityModel::SetChild (Ptr<MobilityModel> model)
{
Ptr<MobilityModel> oldChild = m_child;
Vector pos;
if (m_child)
{
pos = GetPosition ();
m_child->TraceDisconnectWithoutContext ("CourseChange", MakeCallback (&HierarchicalMobilityModel::ChildChanged, this));
}
m_child = model;
m_child->TraceConnectWithoutContext ("CourseChange", MakeCallback (&HierarchicalMobilityModel::ChildChanged, this));
// if we had a child before, then we had a valid position before;
// try to preserve the old absolute position.
if (oldChild)
{
SetPosition (pos);
}
}
void
HierarchicalMobilityModel::SetParent (Ptr<MobilityModel> model)
{
Vector pos;
if (m_child)
{
pos = GetPosition ();
}
if (m_parent)
{
m_parent->TraceDisconnectWithoutContext ("CourseChange", MakeCallback (&HierarchicalMobilityModel::ParentChanged, this));
}
m_parent = model;
m_parent->TraceConnectWithoutContext ("CourseChange", MakeCallback (&HierarchicalMobilityModel::ParentChanged, this));
if (m_parent)
{
m_parent->TraceConnectWithoutContext ("CourseChange", MakeCallback (&HierarchicalMobilityModel::ParentChanged, this));
}
// try to preserve the old position across parent changes
if (m_child)
{
SetPosition (pos);
}
}
@@ -79,6 +110,10 @@ HierarchicalMobilityModel::GetParent (void) const
Vector
HierarchicalMobilityModel::DoGetPosition (void) const
{
if (!m_parent)
{
return m_child->GetPosition ();
}
Vector parentPosition = m_parent->GetPosition ();
Vector childPosition = m_child->GetPosition ();
return Vector (parentPosition.x + childPosition.x,
@@ -88,27 +123,41 @@ HierarchicalMobilityModel::DoGetPosition (void) const
void
HierarchicalMobilityModel::DoSetPosition (const Vector &position)
{
if (m_parent == 0 || m_child == 0)
if (m_child == 0)
{
return;
}
// This implementation of DoSetPosition is really an arbitraty choice.
// anything else would have been ok.
Vector parentPosition = m_parent->GetPosition ();
Vector childPosition (position.x - parentPosition.x,
position.y - parentPosition.y,
position.z - parentPosition.z);
m_child->SetPosition (childPosition);
if (m_parent)
{
Vector parentPosition = m_parent->GetPosition ();
Vector childPosition (position.x - parentPosition.x,
position.y - parentPosition.y,
position.z - parentPosition.z);
m_child->SetPosition (childPosition);
}
else
{
m_child->SetPosition (position);
}
}
Vector
HierarchicalMobilityModel::DoGetVelocity (void) const
{
Vector parentSpeed = m_parent->GetVelocity ();
Vector childSpeed = m_child->GetVelocity ();
Vector speed (parentSpeed.x + childSpeed.x,
parentSpeed.y + childSpeed.y,
parentSpeed.z + childSpeed.z);
return speed;
if (m_parent)
{
Vector parentSpeed = m_parent->GetVelocity ();
Vector childSpeed = m_child->GetVelocity ();
Vector speed (parentSpeed.x + childSpeed.x,
parentSpeed.y + childSpeed.y,
parentSpeed.z + childSpeed.z);
return speed;
}
else
{
return m_child->GetVelocity ();
}
}
void

View File

@@ -27,8 +27,31 @@ namespace ns3 {
/**
* \brief a hierachical mobility model.
*
* This model allows you to specify the position of a
* child object relative to a parent object.
* This model allows you to specify the position of a child object
* relative to a parent object.
*
* Basically this is a mobility model that combines two other mobility
* models: a "parent" model and a "child" model. The position of the
* hierarchical model is always the vector sum of the parent + child
* positions, so that if the parent model "moves", then this model
* will report an equal relative movement. Useful, for instance, if
* you want to simulate a node inside another node that moves, such as
* a vehicle.
*
* Setting the position on this model is always done using world
* absolute coordinates, and it changes only the child mobility model
* position, never the parent. The child mobility model always uses a
* coordinate sytem relative to the parent model position.
*
* @note: as a special case, the parent model may be NULL, which is
* semantically equivalent to having a ConstantPositionMobilityModel
* as parent positioned at origin (0,0,0). In other words, setting
* the parent model to NULL makes the child model and the hierarchical
* model start using world absolute coordinates.
*
* @warning: changing the parent/child mobility models in the middle
* of a simulation will probably not play very well with the
* ConfigStore APIs, so do this only if you know what you are doing.
*/
class HierarchicalMobilityModel : public MobilityModel
{
@@ -52,14 +75,26 @@ public:
* position by the child mobility model.
*/
Ptr<MobilityModel> GetParent (void) const;
/**
* Sets the child mobility model to a new one. If before there
* already existed a child model, then the child mobility model
* current position is also modified to ensure that the composite
* position is preserved.
*/
void SetChild (Ptr<MobilityModel> model);
/**
* Sets the parent mobility model to a new one. If before there
* already existed a child model, then the child mobility model
* current position is also modified to ensure that the composite
* position is preserved.
*/
void SetParent (Ptr<MobilityModel> model);
private:
virtual Vector DoGetPosition (void) const;
virtual void DoSetPosition (const Vector &position);
virtual Vector DoGetVelocity (void) const;
void SetChild (Ptr<MobilityModel> model);
void SetParent (Ptr<MobilityModel> model);
void ParentChanged (Ptr<const MobilityModel> model);
void ChildChanged (Ptr<const MobilityModel> model);