20 #include "spring-mobility-model.h"
21 #include "ns3/simulator.h"
22 #include "ns3/double.h"
24 #include "ns3/node-list.h"
27 #include <boost/foreach.hpp>
29 NS_LOG_COMPONENT_DEFINE (
"SpringMobilityModel");
33 NS_OBJECT_ENSURE_REGISTERED (SpringMobilityModel);
35 double SpringMobilityModel::m_totalKineticEnergy = 0.0;
36 bool SpringMobilityModel::m_stable =
false;
37 EventId SpringMobilityModel::m_updateEvent;
38 double SpringMobilityModel::m_epsilon = 100.0;
40 const double COLOUMB_K = 200;
42 TypeId SpringMobilityModel::GetTypeId (
void)
44 static TypeId tid = TypeId (
"ns3::SpringMobilityModel")
45 .SetParent<MobilityModel> ()
46 .AddConstructor<SpringMobilityModel> ()
51 .AddAttribute (
"NodeMass",
"Node mass",
53 MakeDoubleAccessor (&SpringMobilityModel::m_nodeMass),
54 MakeDoubleChecker<double> ())
55 .AddAttribute (
"NodeCharge",
"Node charge",
57 MakeDoubleAccessor (&SpringMobilityModel::m_nodeCharge),
58 MakeDoubleChecker<double> ())
59 .AddAttribute (
"SpringNormalLength",
"Normal length of spring length",
61 MakeDoubleAccessor (&SpringMobilityModel::m_springNormalLength),
62 MakeDoubleChecker<double> ())
63 .AddAttribute (
"SpringConstant",
"Spring constant",
65 MakeDoubleAccessor (&SpringMobilityModel::m_springConstant),
66 MakeDoubleChecker<double> ())
67 .AddAttribute (
"DampingFactor",
"Dumping factor",
69 MakeDoubleAccessor (&SpringMobilityModel::m_dampingFactor),
70 MakeDoubleChecker<double> ())
82 SpringMobilityModel::~SpringMobilityModel ()
89 m_springs.push_back (node);
93 SpringMobilityModel::DoStart ()
95 if (!m_updateEvent.IsRunning ())
96 m_updateEvent = Simulator::Schedule (Seconds(0.05), SpringMobilityModel::UpdateAll);
100 SpringMobilityModel::UpdateAll ()
102 for (NodeList::Iterator node = NodeList::Begin ();
103 node != NodeList::End ();
111 if (m_totalKineticEnergy < m_epsilon)
114 NS_LOG_INFO (
"Stabilized with " << m_totalKineticEnergy);
117 m_updateEvent = Simulator::Schedule (Seconds(0.05), SpringMobilityModel::UpdateAll);
121 SpringMobilityModel::Update ()
const
123 NS_LOG_FUNCTION (
this << m_stable << m_position << m_velocity);
124 if (m_stable)
return;
125 Time now = Simulator::Now ();
127 if (now <= m_lastTime)
133 double time_step_s = (now - m_lastTime).ToDouble (Time::S);
136 Vector force (0.0, 0.0, 0.0);
138 for (NodeList::Iterator node = NodeList::Begin ();
139 node != NodeList::End ();
142 if ((*node)->GetId () == GetObject<Node> ()->GetId ())
continue;
144 if (model == 0)
continue;
145 if (model ==
this)
continue;
147 double distance = GetDistanceFrom (model);
148 if (distance < 0.1)
continue;
150 Vector direction = (GetPosition () - model->GetPosition ()) / distance;
152 force += direction * COLOUMB_K * m_nodeCharge * m_nodeCharge / distance / distance;
155 BOOST_FOREACH (Ptr<MobilityModel> model, m_springs)
157 double distance = GetDistanceFrom (model);
158 Vector direction = (model->GetPosition () - GetPosition ()) / distance;
160 force += direction * (- m_springNormalLength + distance) / m_springConstant;
166 double velocityValue = CalculateDistance (m_velocity, Vector(0,0,0));
167 m_totalKineticEnergy -= m_nodeMass * velocityValue * velocityValue;
170 m_velocity = (m_velocity + force * time_step_s) * m_dampingFactor;
171 m_position += m_velocity * time_step_s;
174 velocityValue = CalculateDistance (m_velocity, Vector(0,0,0));
175 m_totalKineticEnergy += m_nodeMass * velocityValue * velocityValue;
177 NotifyCourseChange ();
181 SpringMobilityModel::DoGetPosition (
void)
const
187 SpringMobilityModel::DoSetPosition (
const Vector &position)
190 m_position = position;
192 NotifyCourseChange ();
196 for (NodeList::Iterator node = NodeList::Begin ();
197 node != NodeList::End ();
202 model->m_lastTime = Simulator::Now ();
205 if (!m_updateEvent.IsRunning ())
206 m_updateEvent = Simulator::Schedule (Seconds(0.05), SpringMobilityModel::UpdateAll);
209 SpringMobilityModel::DoGetVelocity (
void)
const