Added UAN AUV module: remus and glider mobility and energy models, helpers and examples
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/examples/auv-energy-model.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,115 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/simulator.h"
+#include "ns3/node.h"
+#include "ns3/log.h"
+#include "ns3/glider-energy-model.h"
+#include "ns3/energy-source-container.h"
+
+using namespace ns3;
+
+/**
+ * In this example we show the basic usage of an AUV energy model.
+ * Specifically, we show how to create a generic node, adding to it a
+ * basic energy source and consuming energy from the energy source.
+ *
+ * The Seaglider AUV power consumption depends on buoyancy and vertical
+ * speed values, so we simulate a 20 seconds movement at 0.3 m/s of vertical
+ * speed and 138g of buoyancy. Then a 20 seconds movement at 0.2 m/s
+ * of vertical speed and 138g of buoyancy and then a stop of 5 seconds.
+ *
+ * The required energy will be drained by the model basing on the
+ * given buoyancy/speed values, from the energy source installed onto
+ * the node.
+ *
+ * We register a callback to the TotalEnergyConsumption traced value.
+ */
+
+void
+DoubleTrace (double oldValue, double newValue)
+{
+ std::cout << "Energy changed from " << oldValue << "J to " << newValue << "J" << std::endl;
+}
+
+int
+main (int argc, char **argv)
+{
+ // uncomment to see energy consumption details
+ // LogComponentEnable ("GliderEnergyModel", LOG_LEVEL_ALL);
+
+ // create node
+ Ptr<Node> node = CreateObject<Node> ();
+
+ // create energy source
+ ObjectFactory m_energySource;
+ m_energySource.SetTypeId ("ns3::BasicEnergySource");
+ m_energySource.Set ("BasicEnergySourceInitialEnergyJ",
+ DoubleValue (10000000));
+ Ptr<EnergySource> source = m_energySource.Create<EnergySource> ();
+ source->SetNode (node);
+ Ptr<EnergySourceContainer> sourceCont = CreateObject<EnergySourceContainer> ();
+ sourceCont->Add (source);
+ // aggregate energy source to node
+ node->AggregateObject (sourceCont);
+
+ // create device energy model
+ Ptr<GliderEnergyModel> model = CreateObject<GliderEnergyModel> ();
+ // set energy source pointer
+ model->SetEnergySource (source);
+ model->SetNode (node);
+ // add device energy model to model list in energy source
+ source->AppendDeviceEnergyModel (model);
+ // register a callback to the total consumption value
+ model->TraceConnectWithoutContext ("TotalEnergyConsumption", MakeCallback (&DoubleTrace));
+
+ // retrieve device energy model from energy source
+ DeviceEnergyModelContainer modelCont =
+ source->FindDeviceEnergyModels ("ns3::GliderEnergyModel");
+ NS_ASSERT (modelCont.GetN () != 0);
+ // get pointer
+ Ptr<GliderEnergyModel> devModel = DynamicCast<GliderEnergyModel> (modelCont.Get (0));
+
+ // simulate 20 seconds of movement with 138g buoyancy and 0.3 m/s of W
+ devModel->ChangeEnergyConsumption (138, 0.3);
+
+ // simulate 20 seconds of movement with 138g buoyancy and 0.2 m/s of W
+ Simulator::Schedule (Seconds (20),
+ &GliderEnergyModel::ChangeEnergyConsumption,
+ devModel,
+ 138,
+ 0.2);
+
+ // simulate a stop of the vehicle for the remaining 5 seconds
+ Simulator::Schedule (Seconds (40),
+ &GliderEnergyModel::ChangeEnergyConsumption,
+ devModel,
+ 0,
+ 0);
+
+ // run simulation
+ Simulator::Stop (Seconds (45));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ std::cout << "Remaining energy: " << source->GetRemainingEnergy () << std::endl;
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/examples/auv-mobility.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/glider-mobility-model.h"
+#include "ns3/auv-mobility-model.h"
+#include "ns3/simulator.h"
+#include "ns3/node.h"
+#include "ns3/nstime.h"
+#include "ns3/vector.h"
+#include "ns3/gnuplot.h"
+#include "ns3/auv-mobility-helper.h"
+
+#include <fstream>
+
+using namespace ns3;
+
+/**
+ * We show how to use the AuvMobilityHelper to install an auv mobility model
+ * into a (set of) node.
+ *
+ * Then we make the AUV to submerge to a depth of 1000 meters.
+ * We also set a callback function called on reaching of the target depth.
+ *
+ * The callback then makes the AUV to emerge to water surface (0 meters).
+ * We set a callback function called on reaching of the target depth.
+ * The emerge callback then, stops the AUV.
+ *
+ * During the whole navigation process, the AUV's position is tracked by the
+ * TracePos function and plotted into a Gnuplot graph.
+ */
+
+void Emerge (Ptr<GliderMobilityModel> mob);
+
+static void
+SubmergeCb (Ptr<MobilityModel> mob)
+{
+ // reached the target, makes the vehicle emerge
+ Emerge (mob->GetObject<GliderMobilityModel> ());
+}
+
+static void
+EmergeCb (Ptr<MobilityModel> mob)
+{
+ // stop the vehicle
+ mob->GetObject<GliderMobilityModel> ()->Stop ();
+}
+
+void
+Submerge (Ptr<GliderMobilityModel> mob)
+{
+ // set the submerge callback
+ mob->SetSubmergeCallback (MakeCallback (&SubmergeCb));
+
+ // makes the vehicle submerge to 1000m
+ mob->Submerge (-1000);
+}
+
+void
+Emerge (Ptr<GliderMobilityModel> mob)
+{
+ // set the emerge callback
+ mob->SetEmergeCallback (MakeCallback (&EmergeCb));
+
+ // makes the vehicle emerge to water surface
+ mob->Emerge (0);
+}
+
+static void
+TracePos (Gnuplot3dDataset* ds, Ptr<const GliderMobilityModel> mob)
+{
+ Vector curPos = mob->GetPosition ();
+ ds->Add (curPos.x, curPos.y, curPos.z);
+
+ Simulator::Schedule (Seconds (10),
+ &TracePos,
+ ds,
+ mob);
+}
+
+void
+GeneratePlot (const GnuplotDataset& ds)
+{
+ Gnuplot gp;
+ gp.SetTitle ("3D view");
+ gp.SetExtra ("set multiplot");
+ gp.AppendExtra ("set size 0.5,0.5");
+ gp.AppendExtra ("set origin 0.0,0.0");
+ gp.AppendExtra ("set view 60,30");
+ gp.AddDataset (ds);
+
+ Gnuplot gp1;
+ gp1.SetTitle ("X-Y view");
+ gp1.SetExtra ("set view 0,0");
+ gp1.AppendExtra ("set origin 0.0,0.5");
+ gp1.AddDataset (ds);
+
+ Gnuplot gp2;
+ gp2.SetTitle ("X-Z view");
+ gp2.SetExtra ("set view 90,0");
+ gp2.AppendExtra ("set origin 0.5,0.0");
+ gp2.AddDataset (ds);
+
+ Gnuplot gp3;
+ gp3.SetTitle ("Y-Z view");
+ gp3.SetExtra ("set view 0,90");
+ gp3.AppendExtra ("set origin 0.5,0.5");
+ gp3.AddDataset (ds);
+
+ GnuplotCollection gpc ("seaglider-navigation-trace.eps");
+ gpc.AddPlot (gp);
+ gpc.AddPlot (gp1);
+ gpc.AddPlot (gp2);
+ gpc.AddPlot (gp3);
+ gpc.SetTerminal ("postscript eps enhanced color \"Helvetica\" 10");
+
+ std::ofstream of ("seaglider-navigation-trace.gpl");
+ if (!of.is_open ())
+ {
+ NS_FATAL_ERROR ("Can not open GNU Plot outfile: seaglider-navigation-trace.gpl");
+ }
+ gpc.GenerateOutput (of);
+ of.close ();
+
+ std::cout << "Seaglider navigation trace successfully created!" << std::endl;
+}
+
+int
+main (int argc, char **argv)
+{
+ NodeContainer node;
+ node.Create (1);
+
+ // install the glider mobility model
+ AuvMobilityHelper rmh;
+ rmh.SetType ("ns3::GliderMobilityModel");
+ rmh.Install (node);
+
+ Ptr<GliderMobilityModel> glider = DynamicCast<GliderMobilityModel> (node.Get (0)->GetObject<AuvMobilityModel> ());
+ NS_ASSERT (glider != 0);
+
+ // set the initial position of the AUV
+ glider->SetPosition (Vector (0.,0.,0.));
+
+ // trace the position
+ Gnuplot3dDataset ds ("Navigation Trace");
+ TracePos (&ds, glider);
+
+ // submerge
+ Submerge (glider);
+
+ // run simulation
+ Simulator::Stop (Seconds (4001));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ // generate the navigation trace
+ GeneratePlot (ds);
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/examples/uan-energy-auv.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,188 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+#include "ns3/uan-net-device.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/auv-glider-helper.h"
+#include "ns3/waypoint-mobility-model.h"
+#include "ns3/uan-helper.h"
+#include "ns3/basic-energy-source-helper.h"
+#include "ns3/acoustic-modem-energy-model-helper.h"
+#include "ns3/constant-position-mobility-model.h"
+#include "ns3/log.h"
+#include "ns3/uan-channel.h"
+#include "ns3/uan-noise-model-default.h"
+#include "ns3/uan-prop-model-ideal.h"
+#include "uan-energy-auv.h"
+
+using namespace ns3;
+
+UanEnergyAuv::UanEnergyAuv ()
+ : m_bytesRx (0),
+ m_sentPackets (0)
+{
+}
+
+UanEnergyAuv::~UanEnergyAuv ()
+{
+ m_auv = 0;
+ m_gateway = 0;
+}
+
+void
+UanEnergyAuv::SendOnePacket (Ptr<Node> node)
+{
+ // create an empty 17 bytes packet
+ Ptr<Packet> pkt = Create<Packet> (17);
+ // send the packet in broadcast
+ Ptr<UanNetDevice> dev = node->GetDevice (0)->GetObject<UanNetDevice> ();
+ dev->Send (pkt, dev->GetBroadcast (), 0);
+ // increase the sent packets number
+ ++m_sentPackets;
+
+ Simulator::Schedule (Seconds (10),
+ &UanEnergyAuv::SendOnePacket,
+ this,
+ node);
+}
+
+bool
+UanEnergyAuv::RxPacket (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender)
+{
+ // increase the total bytes received
+ m_bytesRx += pkt->GetSize ();
+
+ return true;
+}
+
+void
+UanEnergyAuv::PrintStats ()
+{
+ std::cout << "AUV: sent " << m_sentPackets << " packets" << std::endl;
+
+ std::cout << "Gateway: received " << m_bytesRx << " bytes" << std::endl;
+
+ Ptr<EnergySource> src1 = m_gateway->GetObject<EnergySourceContainer> ()->Get (0);
+ std::cout << "Gateway energy consumption: " << src1->GetInitialEnergy () - src1->GetRemainingEnergy () << " J" << std::endl;
+
+ Ptr<EnergySource> src2 = m_auv->GetObject<EnergySourceContainer> ()->Get (1);
+ double init0 = src2->GetInitialEnergy ();
+ double init1 = src2->GetRemainingEnergy ();
+ std::cout << "AUV energy consumption (comms): " << init0 - init1 << " J" << std::endl;
+
+ Ptr<EnergySource> src3 = m_auv->GetObject<EnergySourceContainer> ()->Get (0);
+ std::cout << "AUV energy consumption (nav): " << src3->GetInitialEnergy () - src3->GetRemainingEnergy () << " J" << std::endl;
+}
+
+bool
+UanEnergyAuv::Run ()
+{
+ // create a generic node
+ NodeContainer nc = NodeContainer ();
+ nc.Create (1);
+ m_auv = nc.Get (0);
+
+ // create a default underwater channel
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise = CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ // install the underwater communication stack
+ UanHelper uan;
+ Ptr<UanNetDevice> devNode = uan.Install (m_auv, channel);
+
+ // install the glider components
+ AuvGliderHelper gh;
+ gh.Install (m_auv);
+
+ // move the vehicle somewhere
+ Ptr<WaypointMobilityModel> mob = m_auv->GetObject<WaypointMobilityModel> ();
+ mob->AddWaypoint (Waypoint (Seconds (0), Vector (0,0,0)));
+ mob->AddWaypoint (Waypoint (Seconds (2000), Vector (450,0,-1000)));
+ mob->AddWaypoint (Waypoint (Seconds (4000), Vector (900,0,0)));
+
+ // Schedule a packet every 10 seconds
+ Simulator::ScheduleNow (&UanEnergyAuv::SendOnePacket,
+ this,
+ m_auv);
+
+ // create a gateway node
+ NodeContainer nc1 = NodeContainer ();
+ nc1.Create (1);
+ m_gateway = nc1.Get (0);
+
+ // install the underwater communication stack
+ Ptr<UanNetDevice> devNode1 = uan.Install (m_gateway, channel);
+
+ // energy source
+ BasicEnergySourceHelper eh;
+ eh.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (10000000.0));
+ eh.Install (nc1);
+
+ // mobility model
+ Ptr<ConstantPositionMobilityModel> mobility = CreateObject<ConstantPositionMobilityModel> ();
+ mobility->SetPosition (Vector (1000,0,0));
+ m_gateway->AggregateObject (mobility);
+
+ // micro modem energy model
+ /*
+ Ptr<AcousticModemEnergyModel> umem = CreateObject<AcousticModemEnergyModel> ();
+ Ptr<EnergySource> source = m_gateway->GetObject<EnergySourceContainer> ()->Get (0);
+ NS_ASSERT (source != 0);
+ umem->SetEnergySource (source);
+ source->AppendDeviceEnergyModel (umem);
+ */
+ AcousticModemEnergyModelHelper modemHelper;
+ Ptr<EnergySource> source = m_gateway->GetObject<EnergySourceContainer> ()->Get (0);
+ DeviceEnergyModelContainer cont = modemHelper.Install (devNode1, source);
+
+ // set the receive callback
+ Ptr<NetDevice> dev = m_gateway->GetDevice (0);
+ dev->SetReceiveCallback (MakeCallback (&UanEnergyAuv::RxPacket,
+ this));
+
+ // run the simulation
+ Simulator::Stop (Seconds (4005));
+ Simulator::Run ();
+
+ // print the simulation's statistics
+ PrintStats ();
+
+ Simulator::Destroy ();
+
+ return false;
+}
+
+int
+main (int argc, char **argv)
+{
+ // uncomment to see models log
+ // LogComponentEnable("GliderEnergyModel", LOG_LEVEL_ALL);
+ // LogComponentEnable("BasicEnergySource", LOG_LEVEL_ALL);
+ // LogComponentEnable("LiIonEnergySource", LOG_LEVEL_ALL);
+ // LogComponentEnable("AcousticModemEnergyModel", LOG_LEVEL_ALL);
+
+ UanEnergyAuv uan;
+ uan.Run ();
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/examples/uan-energy-auv.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,65 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef UAN_ENERGY_AUV_H_
+#define UAN_ENERGY_AUV_H_
+
+/**
+ * This is a comprehensive example where all the project's components are used.
+ * We setup two nodes, one fixed surface gateway and a moving Seaglider AUV,
+ * both equipped with an acoustic modem.
+ *
+ * Using the waypoint mobility model with an underlying GliderMobilityModel,
+ * we make the glider descend to -1000 meters and then emerge to the water surface.
+ *
+ * The AUV sends a generic 17-bytes packet every 10 seconds during the navigation
+ * process.
+ * The gateway receives the packets and stores the total bytes amount.
+ *
+ * During the simulation the AUV consumes energy for navigation and packets sending.
+ * The energy drained is subtracted from the main energy source.
+ * The surface gateway instead consumes energy only receiving packets.
+ *
+ * At the end of the simulation are printed out the energy consumptions of the two
+ * nodes and the networking stats.
+ */
+
+using namespace ns3;
+
+class UanEnergyAuv
+{
+public:
+ UanEnergyAuv ();
+ ~UanEnergyAuv ();
+
+ bool RxPacket (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender);
+ void SendOnePacket (Ptr<Node> node);
+
+ void PrintStats ();
+
+ bool Run (void);
+
+ uint32_t m_bytesRx;
+ uint32_t m_sentPackets;
+ Ptr<Node> m_auv;
+ Ptr<Node> m_gateway;
+};
+
+#endif /* UAN_ENERGY_AUV_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/examples/waypoint-mobility.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,108 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/waypoint.h"
+#include "ns3/simulator.h"
+#include "ns3/remus-mobility-model.h"
+#include "ns3/waypoint-mobility-model.h"
+#include "ns3/glider-mobility-model.h"
+
+using namespace ns3;
+
+/**
+ * We show how to use the WaypointMobilityModel with a non-standard
+ * ConstantVelocityMobilityModel.
+ *
+ * We first create a waypoint model with an underlying RemusMobilityModel
+ * setting the mobility trace with two waypoints.
+ *
+ * We then create a waypoint model with an underlying GliderMobilityModel
+ * setting the waypoints separately with the AddWaypoint method.
+ *
+ * We start the simulation.
+ *
+ * The AUV's position is printed out every seconds.
+ */
+
+static void
+TracePos (Ptr<const WaypointMobilityModel> mob)
+{
+ Vector curPos = mob->GetPosition ();
+
+ std::cout << "At " << Simulator::Now ().GetSeconds () << ": " <<
+ curPos.x << " " << curPos.y << " " << curPos.z << std::endl;
+
+ Simulator::Schedule (Seconds (1),
+ &TracePos,
+ mob);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ Ptr<Node> node1 = CreateObject<Node> ();
+
+ // create the waypoint model
+ Ptr<WaypointMobilityModel> mm = CreateObject<WaypointMobilityModel> ();
+ Ptr<RemusMobilityModel> remus = CreateObject<RemusMobilityModel> ();
+ remus->SetNode (node1);
+ // set the RemusMobilityModel as the underlying model
+ mm->SetMobilityModel (remus);
+ node1->AggregateObject (mm);
+
+ // set some waypoints
+ mm->AddWaypoint (Waypoint (Seconds (0), Vector (0, 0, 0)));
+ mm->AddWaypoint (Waypoint (Seconds (10), Vector (20, 0, 0)));
+
+ std::cout << "Remus simulation" << std::endl;
+
+ // trace the position
+ TracePos (mm);
+
+ // run the simulation
+ Simulator::Stop (Seconds (15));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ // create another waypoint model with an underlying GliderMobilityModel
+ Ptr<Node> node2 = CreateObject<Node> ();
+ Ptr<GliderMobilityModel> gmm = CreateObject<GliderMobilityModel> ();
+ gmm->SetNode (node2);
+ Ptr<WaypointMobilityModel> wpmm = CreateObject<WaypointMobilityModel> ();
+ wpmm->SetMobilityModel (gmm);
+ node2->AggregateObject (wpmm);
+
+ // set some waypoints
+ wpmm->AddWaypoint (Waypoint (Seconds (0), Vector (0,0,0)));
+ wpmm->AddWaypoint (Waypoint (Seconds (60), Vector (10,0,-20)));
+
+ std::cout << std::endl << "Seaglider simulation" << std::endl;
+
+ // trace the position
+ TracePos (wpmm);
+
+ // run the simulation
+ Simulator::Stop (Seconds (62));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/examples/wscript Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,14 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_program('uan-energy-auv', ['core', 'simulator', 'uan', 'mobility', 'energy'])
+ obj.source = 'uan-energy-auv.cc'
+
+ obj = bld.create_ns3_program('auv-energy-model', ['core', 'simulator', 'mobility'])
+ obj.source = 'auv-energy-model.cc'
+
+ obj = bld.create_ns3_program('waypoint-mobility', ['core', 'simulator', 'mobility'])
+ obj.source = 'waypoint-mobility.cc'
+
+ obj = bld.create_ns3_program('auv-mobility', ['core', 'simulator', 'mobility'])
+ obj.source = 'auv-mobility.cc'
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/helper/auv-glider-helper.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,149 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "ns3/names.h"
+#include "ns3/auv-mobility-helper.h"
+#include "ns3/li-ion-energy-source.h"
+#include "ns3/glider-energy-model.h"
+#include "ns3/acoustic-modem-energy-model-helper.h"
+#include "ns3/uan-helper.h"
+#include "ns3/glider-mobility-model.h"
+#include "ns3/waypoint-mobility-model.h"
+#include "ns3/energy-source-container.h"
+#include "auv-glider-helper.h"
+#include "ns3/li-ion-energy-source-helper.h"
+
+namespace ns3 {
+
+AuvGliderHelper::AuvGliderHelper ()
+{
+ m_navigationEnergyPack.SetTypeId ("ns3::LiIonEnergySource");
+ m_navigationEnergyPack.Set ("LiIonEnergySourceInitialEnergyJ", DoubleValue (13608000.0));
+ m_navigationEnergyPack.Set ("IntialCellVoltage", DoubleValue (3.45 * 7));
+ m_navigationEnergyPack.Set ("NominalCellVoltage", DoubleValue (3.3 * 7));
+ m_navigationEnergyPack.Set ("ExpCellVoltage", DoubleValue (3.55 * 7));
+ m_navigationEnergyPack.Set ("RatedCapacity", DoubleValue (30.0 * 6));
+ m_navigationEnergyPack.Set ("NomCapacity", DoubleValue (27.0 * 6));
+ m_navigationEnergyPack.Set ("ExpCapacity", DoubleValue (15.0 * 6));
+ // 0.145 ohm per cell, 7 in series and 6 string in parallel
+ // Gstring = 1 / (0.145 * 7)
+ // Rint = 1 / (Gstring * 6)
+ m_navigationEnergyPack.Set ("InternalResistance", DoubleValue (0.16917));
+ m_navigationEnergyPack.Set ("TypCurrent", DoubleValue (1.0 * 6));
+ m_navigationEnergyPack.Set ("ThresholdVoltage", DoubleValue (3.0 * 6));
+
+ m_commsEnergyPack.SetTypeId ("ns3::LiIonEnergySource");
+ m_commsEnergyPack.Set ("LiIonEnergySourceInitialEnergyJ", DoubleValue (3888000.0));
+ m_commsEnergyPack.Set ("IntialCellVoltage", DoubleValue (3.45 * 3));
+ m_commsEnergyPack.Set ("NominalCellVoltage", DoubleValue (3.3 * 3));
+ m_commsEnergyPack.Set ("ExpCellVoltage", DoubleValue (3.55 * 3));
+ m_commsEnergyPack.Set ("RatedCapacity", DoubleValue (30.0 * 4));
+ m_commsEnergyPack.Set ("NomCapacity", DoubleValue (27.0 * 4));
+ m_commsEnergyPack.Set ("ExpCapacity", DoubleValue (15.0 * 4));
+ // 0.145 ohm per cell, 3 in series and 4 string in parallel
+ // Gstring = 1 / (0.145 * 3)
+ // Rint = 1 / (Gstring * 4)
+ m_commsEnergyPack.Set ("InternalResistance", DoubleValue (0.10875));
+ m_commsEnergyPack.Set ("TypCurrent", DoubleValue (1.0 * 4));
+ m_commsEnergyPack.Set ("ThresholdVoltage", DoubleValue (3.0 * 4));
+}
+
+void
+AuvGliderHelper::Install (NodeContainer c) const
+{
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Install (*i);
+ }
+}
+
+void
+AuvGliderHelper::Install (std::string nodeName) const
+{
+ Ptr<Node> node = Names::Find<Node> (nodeName);
+ Install (node);
+}
+
+void
+AuvGliderHelper::Install (Ptr<Node> node) const
+{
+ // waypoint mobility model with underlying glider mobility model
+ Ptr<GliderMobilityModel> gmm = CreateObject<GliderMobilityModel> ();
+ gmm->SetNode (node);
+ Ptr<WaypointMobilityModel> wpmm = CreateObject<WaypointMobilityModel> ();
+ wpmm->SetMobilityModel (gmm);
+ node->AggregateObject (wpmm);
+
+ // Motor battery pack. 7 in-series string x 6 strings = 42 cells
+ // Capacity 18.1 MJ @ 24 V
+ //
+ // +--C-C-C-C-C-C-C--+
+ // +--C-C-C-C-C-C-C--+
+ // ---+--C-C-C-C-C-C-C--+---
+ // +--C-C-C-C-C-C-C--+
+ // +--C-C-C-C-C-C-C--+
+ // +--C-C-C-C-C-C-C--+
+ //
+ Ptr<EnergySourceContainer> esContainer = CreateObject<EnergySourceContainer> ();
+ Ptr<EnergySourceContainer> cont = node->GetObject<EnergySourceContainer> ();
+ NS_ASSERT_MSG (cont == 0, "Energy source already installed!");
+ //ObjectFactory fact;
+ //fact.SetTypeId (LiIonEnergySource::GetTypeId ());
+ Ptr<EnergySource> navSource = m_navigationEnergyPack.Create<EnergySource> ();
+ esContainer->Add (navSource);
+ navSource->SetNode (node);
+
+ // Analogic/digital power battery pack. 3 in-series string x 4 strings = 12 cells
+ // Capacity 18.1 MJ @ 10 V
+ //
+ // +--C-C-C--+
+ // +--C-C-C--+
+ // ---+--C-C-C--+---
+ // +--C-C-C--+
+ //
+ //fact.SetTypeId (LiIonEnergySource::GetTypeId ());
+ Ptr<EnergySource> commsSource = m_commsEnergyPack.Create<EnergySource> ();
+ esContainer->Add (commsSource);
+ commsSource->SetNode (node);
+
+ node->AggregateObject (esContainer);
+
+ // get the installed energy source container
+ cont = node->GetObject<EnergySourceContainer> ();
+ NS_ASSERT (cont != 0);
+
+ // glider energy model
+ Ptr<GliderEnergyModel> gem = CreateObject<GliderEnergyModel> ();
+ gem->SetEnergySource (navSource);
+ navSource->AppendDeviceEnergyModel (gem);
+ gem->SetNode (node);
+
+ // micro modem energy model
+ AcousticModemEnergyModelHelper modemH;
+ Ptr<UanNetDevice> dev = node->GetDevice (0)->GetObject<UanNetDevice> ();
+ NS_ASSERT_MSG (dev != 0, "Node does not contains an UanNetDevice");
+ DeviceEnergyModelContainer devcont = modemH.Install (dev, commsSource);
+
+ return;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/helper/auv-glider-helper.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,98 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef AUV_GLIDER_HELPER_H_
+#define AUV_GLIDER_HELPER_H_
+
+#include <stdint.h>
+#include "ns3/node.h"
+#include "ns3/node-container.h"
+#include "ns3/object-factory.h"
+
+namespace ns3 {
+
+/**
+ * Install into a node (or set of nodes) the Seaglider's features:
+ * - waypoint model with underlying glider mobility model
+ * - glider energy model
+ * - glider energy source
+ * - micro modem energy model
+ *
+ * The glider mobility model is the GliderMobilityModel with default parameters.
+ *
+ * The glider energy model is the GliderEnergyModel with default parameters.
+ *
+ * Regarding the energy source, the Seaglider features two battery packs, one
+ * for motor power and one for digital-analog power.
+ * Each pack is composed of 12 (10V) and 42 (24V) lithium chloride DD-cell batteries,
+ * respectively [1]. The total power capacity is around 17.5 MJ (3.9 MJ + 13.6 MJ).
+ * In the original version of the Seaglider there was 18 + 63 D-cell with a total
+ * power capacity of 10MJ.
+ *
+ * The packs design is as follows:
+ * 10V - 3 in-series string x 4 strings = 12 cells - typical capacity ~100 Ah
+ * 24V - 7 in-series-strings x 6 strings = 42 cells - typical capacity ~150 Ah
+ *
+ * Battery cells are Electrochem 3B36, with 3.6 V nominal voltage and 30.0 Ah
+ * nominal capacity.
+ *
+ * The 10V battery pack is associated with the electronic devices, while the 24V one
+ * is associated with the pump motor.
+ *
+ * The micro modem energy model is the AcousticModemEnergyModel with default parameters.
+ *
+ * References:
+ * [1] Eriksen et al, "Seaglider: A Long-Range Autonomous Underwater Vehicle for Oceanographic Research"
+ * URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=972073&userType=inst
+ */
+class AuvGliderHelper
+{
+public:
+ AuvGliderHelper ();
+
+ /**
+ * Install the auv glider features into a set of nodes
+ *
+ * \param c a set of nodes
+ */
+ void Install (NodeContainer c) const;
+
+ /**
+ * Install the auv glider features into a single node
+ *
+ * \param nodeName Name of the node where to install the features
+ */
+ void Install (std::string nodeName) const;
+
+ /**
+ * Install the auv glider features into a single node
+ *
+ * \param node Pointer of the node where to install the features
+ */
+ void Install (Ptr<Node> node) const;
+
+private:
+ ObjectFactory m_navigationEnergyPack;
+ ObjectFactory m_commsEnergyPack;
+};
+
+} // namespace ns3
+
+#endif /* AUV_GLIDER_HELPER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/helper/auv-mobility-helper.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,116 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "auv-mobility-helper.h"
+#include "ns3/remus-mobility-model.h"
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "ns3/names.h"
+#include "ns3/position-allocator.h"
+
+namespace ns3 {
+
+AuvMobilityHelper::AuvMobilityHelper ()
+{
+ m_factory.SetTypeId ("ns3::RemusMobilityModel");
+
+ m_allocator = CreateObjectWithAttributes<RandomBoxPositionAllocator>
+ ("X", RandomVariableValue (ConstantVariable (0.0)),
+ "Y", RandomVariableValue (ConstantVariable (0.0)),
+ "Z", RandomVariableValue (ConstantVariable (0.0)));
+}
+
+void
+AuvMobilityHelper::SetType (std::string type)
+{
+ m_factory.SetTypeId (type);
+}
+
+void AuvMobilityHelper::SetAttribute (std::string name,
+ const AttributeValue &value)
+{
+ m_factory.Set (name,
+ value);
+}
+
+void
+AuvMobilityHelper::SetPositionAllocator (Ptr<PositionAllocator> allocator)
+{
+ m_allocator = allocator;
+}
+
+void
+AuvMobilityHelper::SetPositionAllocator (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_allocator = pos.Create<PositionAllocator> ();
+}
+
+void
+AuvMobilityHelper::Install (NodeContainer c) const
+{
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Install (*i);
+ }
+}
+
+void
+AuvMobilityHelper::Install (std::string nodeName) const
+{
+ Ptr<Node> node = Names::Find<Node> (nodeName);
+ Install (node);
+}
+
+void
+AuvMobilityHelper::Install (Ptr<Node> node) const
+{
+ Ptr<AuvMobilityModel> model = m_factory.Create<AuvMobilityModel> ();
+
+ NS_ASSERT_MSG (model != 0,
+ "The requested mobility model is not an auv mobility model: \"" <<
+ m_factory.GetTypeId ().GetName () << "\"");
+
+ Vector pos = m_allocator->GetNext ();
+ model->SetPosition (pos);
+ model->SetNode (node);
+ node->AggregateObject (model);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/helper/auv-mobility-helper.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,136 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef AUV_MOBILITY_HELPER_H
+#define AUV_MOBILITY_HELPER_H
+
+#include <stdint.h>
+#include "ns3/node-container.h"
+#include "ns3/object-factory.h"
+#include "ns3/position-allocator.h"
+
+namespace ns3 {
+
+/**
+ * \brief Install into a set of nodes an AuvMobilityModel
+ *
+ * Install into a set of nodes (or single node) the specified AuvMobilityModel.
+ * The specific AuvMobilityModel can be specified with the SetType method.
+ *
+ * The helper also uses a PositionAllocator to set the nodes positions.
+ *
+ * By default the mobility model is the RemusMobilityModel and the position
+ * allocator is a RandomBoxPositionAllocator with X, Y and Z variables set to
+ * constant zero.
+ */
+class AuvMobilityHelper
+{
+public:
+ /**
+ * Set the default mobility model (RemusMobilityModel) and the
+ * default position allocator (RandomBoxPositionAllocator with
+ * constant position in 0,0,0)
+ */
+ AuvMobilityHelper ();
+
+ /**
+ * \param type the AUV mobility model TypeId
+ */
+ void SetType (std::string type);
+
+ /**
+ * Set an attribute of the specified auv mobility model
+ *
+ * \param name name of the parameter
+ * \param value value of the parameter
+ */
+ void SetAttribute (std::string name, const AttributeValue &value);
+ /**
+ * Set the position allocator to be used during the install process
+ * to give each node an initial position
+ *
+ * \param allocator the position allocator to be set
+ */
+ void SetPositionAllocator (Ptr<PositionAllocator> allocator);
+ /**
+ * Set the position allocator to be used during the install process
+ * to give each node an initial position
+ *
+ * \param type the position allocator TypeId
+ * \param n1 the name of the attribute to set
+ * \param v1 the value of the attribute to set
+ * \param n2 the name of the attribute to set
+ * \param v2 the value of the attribute to set
+ * \param n3 the name of the attribute to set
+ * \param v3 the value of the attribute to set
+ * \param n4 the name of the attribute to set
+ * \param v4 the value of the attribute to set
+ * \param n5 the name of the attribute to set
+ * \param v5 the value of the attribute to set
+ * \param n6 the name of the attribute to set
+ * \param v6 the value of the attribute to set
+ * \param n7 the name of the attribute to set
+ * \param v7 the value of the attribute to set
+ * \param n8 the name of the attribute to set
+ * \param v8 the value of the attribute to set
+ * \param n9 the name of the attribute to set
+ * \param v9 the value of the attribute to set
+ */
+ void SetPositionAllocator (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);
+
+ /**
+ * For each of the input nodes a new mobility model of the specified type
+ * is created and attached to the node.
+ *
+ * \param c a set of nodes
+ */
+ void Install (NodeContainer c) const;
+
+ /**
+ * Install the specified auv mobility model into the node with the specified
+ * name.
+ *
+ * \param nodeName name of the node
+ */
+ void Install (std::string nodeName) const;
+
+ /**
+ * Install the specified auv mobility model into the specified node
+ *
+ * \param node Pointer of the node where to install the mobility model
+ */
+ void Install (Ptr<Node> node) const;
+
+ ObjectFactory m_factory;
+ Ptr<PositionAllocator> m_allocator;
+};
+
+} // namespace ns3
+
+#endif /* AUV_MOBILITY_HELPER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/helper/auv-remus-helper.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "ns3/names.h"
+#include "ns3/auv-mobility-helper.h"
+#include "ns3/basic-energy-source-helper.h"
+#include "ns3/remus-energy-model.h"
+#include "ns3/acoustic-modem-energy-model-helper.h"
+#include "ns3/remus-mobility-model.h"
+#include "ns3/waypoint-mobility-model.h"
+#include "auv-remus-helper.h"
+
+namespace ns3 {
+
+AuvRemusHelper::AuvRemusHelper ()
+{
+}
+
+void
+AuvRemusHelper::Install (NodeContainer c) const
+{
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Install (*i);
+ }
+}
+
+void
+AuvRemusHelper::Install (std::string nodeName) const
+{
+ Ptr<Node> node = Names::Find<Node> (nodeName);
+ Install (node);
+}
+
+void
+AuvRemusHelper::Install (Ptr<Node> node) const
+{
+ // waypoint mobility model with underlying remus mobility model
+ Ptr<RemusMobilityModel> rmm = CreateObject<RemusMobilityModel> ();
+ rmm->SetNode (node);
+ Ptr<WaypointMobilityModel> wpmm = CreateObject<WaypointMobilityModel> ();
+ wpmm->SetMobilityModel (rmm);
+ node->AggregateObject (wpmm);
+
+ // 1.1 kWh -> 1.1 * 1000 * 3600 = 3960000J
+ // remus energy source
+ BasicEnergySourceHelper eh;
+ eh.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (3960000.0));
+ eh.Install (node);
+
+ // remus energy model
+ Ptr<RemusEnergyModel> rem = CreateObject<RemusEnergyModel> ();
+ Ptr<EnergySource> source = node->GetObject<EnergySourceContainer> ()->Get (0);
+ NS_ASSERT (source != 0);
+ rem->SetEnergySource (source);
+ source->AppendDeviceEnergyModel (rem);
+ source->SetNode (node);
+ rem->SetNode (node);
+
+ // device energy model helper
+ AcousticModemEnergyModelHelper modemH;
+ Ptr<NetDevice> dev = node->GetDevice (0);
+ modemH.Install (dev, source);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/helper/auv-remus-helper.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef AUV_REMUS_HELPER_H_
+#define AUV_REMUS_HELPER_H_
+
+#include <stdint.h>
+#include "ns3/node.h"
+#include "ns3/node-container.h"
+#include "ns3/object-factory.h"
+
+namespace ns3 {
+
+/**
+ * Install into a node (or set of nodes) the REMUS features:
+ * - waypoint model with REMUS mobility model validation
+ * - REMUS energy model
+ * - REMUS energy source
+ * - micro modem energy model
+ *
+ * The REMUS mobility model is the RemusMobilityModel with default parameters.
+ *
+ * The REMUS energy model is the RemusEnergyModel with default parameters.
+ *
+ * Regarding the energy source, the REMUS features a rechargeable lithium ion
+ * battery pack rated 1.1 kWh @ 27 V (40 Ah) in operating conditions (specifications
+ * from [1] and Hydroinc European salesman).
+ * Since more detailed information about battery pack were not publicly available,
+ * the energy source used is a BasicEnergySource.
+ *
+ * The micro modem energy model is the AcousticModemEnergyModel with default parameters.
+ *
+ * References:
+ *
+ * [1] Hydroinc Products; http://www.hydroidinc.com/products.html
+ */
+class AuvRemusHelper
+{
+public:
+ AuvRemusHelper ();
+
+ /**
+ * Install the auv REMUS features into a set of nodes
+ *
+ * \param c NodeContainer where to install the features
+ */
+ void Install (NodeContainer c) const;
+
+ /**
+ * Install the auv REMUS features into a single node
+ *
+ * \param nodeName Name of the node where to install the features
+ */
+ void Install (std::string nodeName) const;
+
+ /**
+ * Install the auv REMUS features into a single node
+ *
+ * \param node Pointer of the node where to install the features
+ */
+ void Install (Ptr<Node> node) const;
+};
+
+} // namespace ns3
+
+#endif /* AUV_REMUS_HELPER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/auv-mobility-model.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "auv-mobility-model.h"
+#include "ns3/double.h"
+
+namespace ns3 {
+
+TypeId
+AuvMobilityModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::AuvMobilityModel")
+ .SetParent (ConstantVelocityMobilityModel::GetTypeId ())
+ ;
+ return tid;
+}
+
+AuvMobilityModel::AuvMobilityModel ()
+{
+}
+
+AuvMobilityModel::~AuvMobilityModel ()
+{
+}
+
+void
+AuvMobilityModel::Move (void)
+{
+ return DoMove ();
+}
+
+void
+AuvMobilityModel::Stop (void)
+{
+ return DoStop ();
+}
+
+void
+AuvMobilityModel::Emerge (double depth)
+{
+ return DoEmerge (depth);
+}
+
+void
+AuvMobilityModel::Submerge (double depth)
+{
+ return DoSubmerge (depth);
+}
+
+double
+AuvMobilityModel::GetPitch () const
+{
+ return DoGetPitch ();
+}
+
+void
+AuvMobilityModel::SetPitch (double pitch)
+{
+ return DoSetPitch (pitch);
+}
+
+double
+AuvMobilityModel::GetDepth (void)
+{
+ return DoGetDepth ();
+}
+
+double
+AuvMobilityModel::GetDirection (void) const
+{
+ return DoGetDirection ();
+}
+
+void
+AuvMobilityModel::SetDirection (double dir)
+{
+ return DoSetDirection (dir);
+}
+
+double
+AuvMobilityModel::GetSpeed () const
+{
+ return DoGetSpeed ();
+}
+
+void
+AuvMobilityModel::SetSpeed (double speed)
+{
+ return DoSetSpeed (speed);
+}
+
+void
+AuvMobilityModel::SetVelocity (const Vector &velocity)
+{
+ return DoSetVelocity (velocity);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/auv-mobility-model.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef AUV_MOBILITY_MODEL_H_
+#define AUV_MOBILITY_MODEL_H_
+
+#include "ns3/constant-velocity-mobility-model.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+/**
+ * \brief keep track of the current position of an Autonomous Underwater Vehicle (AUV)
+ *
+ * Define an interface for AUV mobility models. Every AUV mobility model should derive
+ * from this interface, and implements all the pure virtual methods.
+ *
+ * The interface allow the client to move/stop the vehicle's movement, makes it submerge
+ * or emerge to a target depth, and getting and setting the main navigation's parameter
+ * like pitch, direction, speed.
+ *
+ * The emerge and submerge callback are called when the vehicle reach the target depth.
+ */
+class AuvMobilityModel : public ConstantVelocityMobilityModel
+{
+public:
+ static TypeId GetTypeId (void);
+ AuvMobilityModel ();
+ virtual ~AuvMobilityModel () = 0;
+
+ /**
+ * Makes the AUV to move along the given direction
+ */
+ void Move (void);
+ /**
+ * Makes the AUV to stop
+ */
+ void Stop (void);
+ /**
+ * Makes the AUV to emerge at the maximum velocity
+ * to the given depth
+ * \param depth the depth to which emerge to, in m (negative)
+ */
+ void Emerge (double depth);
+ /**
+ * Makes the AUV to submerge at the maximum velocity
+ * to the given depth
+ * \param depth the depth to which submerge to, in m (negative)
+ */
+ void Submerge (double depth);
+ /**
+ * \returns the current pitch in degrees
+ */
+ double GetPitch () const;
+
+ /**
+ * \param pitch the pitch to set in degrees
+ */
+ void SetPitch (double pitch);
+ /**
+ * \returns the current depth
+ */
+ double GetDepth (void);
+ /**
+ * \returns the current direction in degrees
+ */
+ double GetDirection (void) const;
+ /**
+ * \param dir the heading direction in degrees
+ */
+ void SetDirection (double dir);
+ /**
+ * \returns the current speed in m/s
+ */
+ double GetSpeed () const;
+ /**
+ * \param speed the speed to set in m/s
+ */
+ void SetSpeed (double speed);
+ /**
+ * \param velocity the velocity vector to set
+ */
+ void SetVelocity (const Vector &velocity);
+ /**
+ * \param node the node associated with the mobility model
+ */
+ virtual void SetNode (const Ptr<Node> node) = 0;
+ /**
+ * \returns the associated node
+ */
+ virtual Ptr<Node> GetNode (void) const = 0;
+ /**
+ * \param cb the callback being called at the end of the emerging process
+ */
+ virtual void SetEmergeCallback (Callback<void, Ptr<MobilityModel> > cb) = 0;
+
+ /**
+ ** \param cb the callback being called at the end of the submerging process
+ */
+ virtual void SetSubmergeCallback (Callback<void, Ptr<MobilityModel> > cb) = 0;
+
+private:
+ /**
+ * Concrete subclasses of this base class must
+ * implement this methods.
+ */
+
+ /**
+ * Makes the AUV to move along the given direction
+ */
+ virtual void DoMove (void) = 0;
+ /**
+ * Makes the AUV to stop
+ */
+ virtual void DoStop (void) = 0;
+ /**
+ * Makes the AUV to emerge at the maximum velocity
+ * to the given depth. When reaching the target depth, it
+ * will be called the EmergeCallback, if set.
+ * \param depth the depth to which emerge to, in m (negative)
+ */
+ virtual void DoEmerge (double depth) = 0;
+ /**
+ * Makes the AUV to submerge at the maximum velocity
+ * to the given depth. When reaching the target depth, it
+ * will be called the SubmergeCallback, if set.
+ * \param depth the depth to which submerge to, in m (negative)
+ */
+ virtual void DoSubmerge (double depth) = 0;
+ /**
+ * \returns the current pitch in degrees
+ */
+ virtual double DoGetPitch () const = 0;
+ /**
+ * \param pitch the pitch to set in degrees
+ */
+ virtual void DoSetPitch (double pitch) = 0;
+ /**
+ * \returns the current depth
+ */
+ virtual double DoGetDepth (void) = 0;
+ /**
+ * \returns the current direction in degrees
+ */
+ virtual double DoGetDirection (void) const = 0;
+ /**
+ * \param direction the heading direction in degrees
+ */
+ virtual void DoSetDirection (double dir) = 0;
+ /**
+ * \returns the current speed in m/s
+ */
+ virtual double DoGetSpeed () const = 0;
+ /**
+ * \param speed the speed to set in m/s
+ */
+ virtual void DoSetSpeed (double speed) = 0;
+ /**
+ * \param velocity the velocity vector to set
+ */
+ virtual void DoSetVelocity (const Vector &velocity) = 0;
+
+ // inherited from MobilityModel
+ /**
+ * \returns the current position
+ */
+ virtual Vector DoGetPosition (void) const = 0;
+ /**
+ * \param position the position to set
+ */
+ virtual void DoSetPosition (const Vector &position) = 0;
+ /**
+ * \returns the current velocity vector
+ */
+ virtual Vector DoGetVelocity (void) const = 0;
+};
+
+}; // namespace ns3
+
+#endif /* AUV_MOBILITY_MODEL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/glider-energy-model.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/double.h"
+#include "ns3/simulator.h"
+#include "ns3/trace-source-accessor.h"
+#include "glider-energy-model.h"
+
+NS_LOG_COMPONENT_DEFINE ("GliderEnergyModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (GliderEnergyModel);
+
+TypeId
+GliderEnergyModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::GliderEnergyModel")
+ .SetParent<DeviceEnergyModel> ()
+ .AddConstructor<GliderEnergyModel> ()
+ .AddTraceSource ("TotalEnergyConsumption",
+ "Total energy consumption of the glider AUV.",
+ MakeTraceSourceAccessor (&GliderEnergyModel::m_totalEnergyConsumption))
+ ;
+ return tid;
+}
+
+GliderEnergyModel::GliderEnergyModel ()
+{
+ NS_LOG_FUNCTION (this);
+ m_currentBuoyancy = 0.0;
+ m_currentW = 0.0;
+ m_actualCurrentDrain = 0.0;
+ m_lastUpdateTime = Seconds (0.0);
+ m_energyDepletionCallback.Nullify ();
+ m_node = 0;
+ m_source = 0;
+}
+
+GliderEnergyModel::~GliderEnergyModel ()
+{
+}
+
+void
+GliderEnergyModel::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+ NS_ASSERT (node != NULL);
+ m_node = node;
+}
+
+Ptr<Node>
+GliderEnergyModel::GetNode (void) const
+{
+ return m_node;
+}
+
+void
+GliderEnergyModel::SetEnergySource (Ptr<EnergySource> source)
+{
+ NS_LOG_FUNCTION (this << source);
+ NS_ASSERT (source != 0);
+ m_source = source;
+}
+
+double
+GliderEnergyModel::GetTotalEnergyConsumption (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_totalEnergyConsumption;
+}
+
+void
+GliderEnergyModel::ChangeState (int newState)
+{
+ NS_FATAL_ERROR ("ChangeState not implemented, use ChangeEnergyConsumption instead.");
+}
+
+void
+GliderEnergyModel::ChangeEnergyConsumption (const double buoyancy, const double W)
+{
+ NS_LOG_FUNCTION (this << buoyancy << W);
+
+ Time duration = Simulator::Now () - m_lastUpdateTime;
+ NS_ASSERT (duration.GetNanoSeconds () >= 0); // check if duration is valid
+
+ // update remaining energy accordingly
+ double power = GetPower (m_currentBuoyancy, m_currentW);
+ double energyToDecrease = duration.GetSeconds () * power;
+
+ // update total energy consumption
+ m_totalEnergyConsumption += energyToDecrease;
+
+ // update current buoyancy
+ m_currentBuoyancy = buoyancy;
+ // update current vertical speed
+ m_currentW = W;
+ // update current drain
+ double actualPower = GetPower (m_currentBuoyancy, m_currentW);
+ double supplyVoltage = m_source->GetSupplyVoltage ();
+ m_actualCurrentDrain = actualPower / supplyVoltage;
+
+ // update last update time stamp
+ m_lastUpdateTime = Simulator::Now ();
+
+ // notify energy source
+ m_source->UpdateEnergySource ();
+
+ // some debug message
+ NS_LOG_DEBUG ("GliderEnergyModel:Total energy consumption at node #" <<
+ m_node->GetId () << " is " << m_totalEnergyConsumption << "J");
+}
+
+void
+GliderEnergyModel::SetEnergyDepletionCallback (GliderEnergyDepletionCallback callback)
+{
+ NS_LOG_FUNCTION (this);
+ if (callback.IsNull ())
+ {
+ NS_LOG_DEBUG ("GliderEnergyModel:Setting NULL energy depletion callback!");
+ }
+ m_energyDepletionCallback = callback;
+}
+
+void
+GliderEnergyModel::HandleEnergyDepletion (void)
+{
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG ("GliderEnergyModel:Energy is depleted at node #" <<
+ m_node->GetId ());
+ // invoke energy depletion callback, if set.
+ if (!m_energyDepletionCallback.IsNull ())
+ {
+ m_energyDepletionCallback ();
+ }
+}
+
+/*
+ * Private functions start here.
+ */
+
+void
+GliderEnergyModel::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_node = 0;
+ m_source = 0;
+ m_energyDepletionCallback.Nullify ();
+}
+
+double
+GliderEnergyModel::DoGetCurrentA (void) const
+{
+ NS_LOG_FUNCTION (this);
+
+ return m_actualCurrentDrain;
+}
+
+double
+GliderEnergyModel::GetPower (double buoyancy, double W) const
+{
+ // power needed to get the buoyancy, in watts
+ double power = buoyancy / 100 * W;
+
+ return power;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/glider-energy-model.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef GLIDER_ENERGY_MODEL_H
+#define GLIDER_ENERGY_MODEL_H
+
+#include "ns3/device-energy-model.h"
+#include "ns3/energy-source.h"
+#include "ns3/nstime.h"
+#include "ns3/event-id.h"
+#include "ns3/traced-value.h"
+
+namespace ns3 {
+
+/**
+ * \brief Keeps track of the Seaglider's energy consumption
+ *
+ * Implement the DeviceEnergyModel interface for the Seaglider
+ * AUV. The energy consumption is calculated with the product of
+ * buoyancy with vertical speed [1].
+ *
+ * This model should be used in conjunction with the GliderMobilityModel.
+ * The mobility model, in fact, on every course change, updates the
+ * energy consumption with the new buoyancy/speed values.
+ *
+ * References:
+ *
+ * [1] Eriksen et al, "Seaglider: A Long-Range Autonomous Underwater Vehicle for Oceanographic Research"
+ * URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=972073&userType=inst
+ */
+class GliderEnergyModel : public DeviceEnergyModel
+{
+public:
+ // / Callback type for energy depletion handling.
+ typedef Callback<void> GliderEnergyDepletionCallback;
+
+public:
+ static TypeId GetTypeId (void);
+ GliderEnergyModel ();
+ virtual ~GliderEnergyModel ();
+
+ /**
+ * \brief Sets pointer to node.
+ *
+ * \param node Pointer to node.
+ *
+ * Implements DeviceEnergyModel::SetNode.
+ */
+ virtual void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Gets pointer to node.
+ *
+ * \returns Pointer to node.
+ *
+ * Implements DeviceEnergyModel::GetNode.
+ */
+ virtual Ptr<Node> GetNode (void) const;
+
+ /**
+ * \brief Sets pointer to EnergySouce installed on node.
+ *
+ * \param source Pointer to EnergySource installed on node.
+ *
+ * Implements DeviceEnergyModel::SetEnergySource.
+ */
+ virtual void SetEnergySource (Ptr<EnergySource> source);
+
+ /**
+ * \returns Total energy consumption of the vehicle.
+ *
+ * Implements DeviceEnergyModel::GetTotalEnergyConsumption.
+ */
+ virtual double GetTotalEnergyConsumption (void) const;
+
+ /**
+ * \param newState New state the device is in.
+ *
+ * DeviceEnergyModel is a state based model. This function is implemented by
+ * all child of DeviceEnergyModel to change the model's state. States are to
+ * be defined by each child using an enum (int).
+ */
+ virtual void ChangeState (int newState);
+
+ /**
+ * \param buoyancy buoyancy value in grams
+ * \param W vertical speed value in m/s
+ *
+ * Update the energy consumption according to the buoyancy value and vertical
+ * speed value.
+ */
+ void ChangeEnergyConsumption (const double buoyancy, const double W);
+
+ /**
+ * \param callback Callback function.
+ *
+ * Sets callback for energy depletion handling.
+ */
+ void SetEnergyDepletionCallback (GliderEnergyDepletionCallback callback);
+
+ /**
+ * \brief Handles energy depletion.
+ *
+ * Implements DeviceEnergyModel::HandleEnergyDepletion
+ */
+ virtual void HandleEnergyDepletion (void);
+
+private:
+ void DoDispose (void);
+
+ /**
+ * \returns Current draw of device, at current state.
+ *
+ * Implements DeviceEnergyModel::GetCurrentA.
+ */
+ virtual double DoGetCurrentA (void) const;
+
+ /**
+ * \param buoyancy the buoyancy value in grams
+ * \param W the vertical speed in m/s
+ * \return the needed power in watts
+ *
+ * This get the power needed to maintain a given buoyancy and vertical speed
+ */
+ double GetPower (double buoyancy, double W) const;
+
+private:
+ Ptr<Node> m_node;
+ Ptr<EnergySource> m_source;
+
+ // This variable keeps track of the total energy consumed by this particular model.
+ TracedValue<double> m_totalEnergyConsumption;
+
+ // actual current drain
+ double m_actualCurrentDrain;
+ // current buoyancy value in grams
+ double m_currentBuoyancy;
+ // current vertical speed value in m/s
+ double m_currentW;
+ // time stamp of previous energy update
+ Time m_lastUpdateTime;
+
+ // energy depletion callback
+ GliderEnergyDepletionCallback m_energyDepletionCallback;
+};
+
+} // namespace ns3
+
+#endif /* GLIDER_ENERGY_MODEL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/glider-mobility-model.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,470 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "glider-mobility-model.h"
+#include <cmath>
+#include "ns3/double.h"
+#include "ns3/simulator.h"
+#include "ns3/energy-source.h"
+#include "ns3/energy-source-container.h"
+#include "ns3/device-energy-model-container.h"
+#include "ns3/glider-energy-model.h"
+#include "ns3/log.h"
+#include "ns3/vector.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("GliderMobilityModel");
+
+NS_OBJECT_ENSURE_REGISTERED (GliderMobilityModel);
+
+TypeId
+GliderMobilityModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::GliderMobilityModel")
+ .SetParent (AuvMobilityModel::GetTypeId ())
+ .AddConstructor<GliderMobilityModel> ()
+ .AddAttribute ("MaxDepth", "The maximum operational depth, in m",
+ DoubleValue (-1000.0),
+ MakeDoubleAccessor (&GliderMobilityModel::m_maxDepth),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MinGlideAngle", "The minimum glide angle of the glider, in degrees.",
+ DoubleValue (14.0), // correspond to a 1/4 glide angle
+ MakeDoubleAccessor (&GliderMobilityModel::m_minGlideAngle),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxGlideAngle", "The maximum glide angle of the glider, in degrees.",
+ DoubleValue (68.2), // correspond to a 5/2 glide angle, derived from the paper
+ MakeDoubleAccessor (&GliderMobilityModel::m_maxGlideAngle),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxHSpeed", "The maximum horizontal speed of the glider, in m/s.",
+ DoubleValue (0.32), // derived from the paper
+ MakeDoubleAccessor (&GliderMobilityModel::m_maxU),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxWSpeed", "The maximum vertical speed of the glider, in m/s.",
+ DoubleValue (0.5), // derived from the paper
+ MakeDoubleAccessor (&GliderMobilityModel::m_maxW),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxBuoyancy", "The maximum buoyancy supported by the glider buoyancy control system, in grammes",
+ DoubleValue (200), // derived from the paper
+ MakeDoubleAccessor (&GliderMobilityModel::m_maxBuoyancy),
+ MakeDoubleChecker<double> ())
+ ;
+ return tid;
+}
+
+GliderMobilityModel::GliderMobilityModel ()
+ : m_direction (0),
+ m_speed (0),
+ m_pitch (0),
+ m_depth (0),
+ m_deployed (false)
+{
+}
+
+Vector
+GliderMobilityModel::RoundPosition (const Vector &pos, uint16_t decimals) const
+{
+ Vector roundPos;
+
+ double off = std::pow (10, decimals);
+ roundPos.x = (std::floor ((pos.x * off) + 0.5)) / off;
+ roundPos.y = (std::floor ((pos.y * off) + 0.5)) / off;
+ roundPos.z = (std::floor ((pos.z * off) + 0.5)) / off;
+
+ return roundPos;
+}
+
+double
+GliderMobilityModel::GetBuoyancy (void) const
+{
+ return m_buoyancy;
+}
+
+void
+GliderMobilityModel::SetNode (const Ptr<Node> node)
+{
+ NS_ASSERT (node != 0);
+ m_node = node;
+}
+
+Ptr<Node>
+GliderMobilityModel::GetNode (void) const
+{
+ return m_node;
+}
+
+void
+GliderMobilityModel::SetEmergeCallback (Callback<void, Ptr<MobilityModel> > cb)
+{
+ m_emergeCb = cb;
+}
+
+void
+GliderMobilityModel::SetSubmergeCallback (Callback<void, Ptr<MobilityModel> > cb)
+{
+ m_submergeCb = cb;
+}
+
+Vector
+GliderMobilityModel::DoGetPosition (void) const
+{
+ m_helper.Update ();
+
+ // get the current position
+ Vector pos = m_helper.GetCurrentPosition ();
+
+ // get the rounded precision position
+ Vector rpos = RoundPosition (pos, 4);
+
+ return rpos;
+}
+
+void
+GliderMobilityModel::DoSetPosition (const Vector &position)
+{
+ NS_ASSERT (!m_deployed);
+
+ m_helper.SetPosition (position);
+}
+
+Vector
+GliderMobilityModel::DoGetVelocity (void) const
+{
+ return m_helper.GetVelocity ();
+}
+
+void
+GliderMobilityModel::DoSetVelocity (const Vector &velocity)
+{
+ // if velocity is 0
+ if (CalculateDistance (velocity,Vector (0, 0, 0)) == 0)
+ {
+ // stop the vehicle
+ DoStop ();
+
+ return;
+ }
+
+ // get the total speed magnitude
+ double speed = std::sqrt ((velocity.x * velocity.x) +
+ (velocity.y * velocity.y) +
+ (velocity.z * velocity.z));
+
+ // calculate the pitch
+ double pitch = std::asin ((velocity.z / speed));
+
+ NS_ASSERT (std::abs (pitch * 180 / M_PI) <= m_maxGlideAngle);
+
+ // get horizontal and vertical speeds
+ double u = speed * std::cos (pitch);
+ double w = speed * std::sin (pitch);
+ // get the required buoyancy for the given speed
+ double buoyancy = GetBuoyancy (std::abs (u), std::abs (w));
+
+ NS_ASSERT_MSG (buoyancy <= m_maxBuoyancy, "Max Buoyancy value exceeded");
+ m_buoyancy = buoyancy;
+ m_speed = speed;
+ m_pitch = pitch;
+
+ // get the direction
+ double dir = std::atan2 (velocity.y, velocity.x);
+ m_direction = dir;
+
+ m_helper.SetVelocity (velocity);
+
+ Move ();
+}
+
+void
+GliderMobilityModel::UpdatePowerConsumption (double buoyancy, double W)
+{
+ Ptr<EnergySourceContainer> source = m_node->GetObject<EnergySourceContainer> ();
+ if (source != 0)
+ {
+ // retrieve device energy model from energy source
+ DeviceEnergyModelContainer modelCont;
+ for (EnergySourceContainer::Iterator it = source->Begin (); it != source->End (); it++)
+ {
+ Ptr<EnergySource> source = *it;
+
+ modelCont = source->FindDeviceEnergyModels ("ns3::GliderEnergyModel");
+ if (modelCont.GetN () != 0)
+ {
+ break;
+ }
+ }
+ NS_ASSERT (modelCont.GetN () != 0);
+
+ // get pointer
+ Ptr<GliderEnergyModel> devModel = DynamicCast<GliderEnergyModel> (modelCont.Get (0));
+ devModel->ChangeEnergyConsumption (buoyancy, std::abs (W));
+ }
+}
+
+void
+GliderMobilityModel::Update (void)
+{
+ // get the vector components
+ double cosD = std::cos (m_direction);
+ double cosP = std::cos (m_pitch);
+ double sinD = std::sin (m_direction);
+ double sinP = std::sin (m_pitch);
+
+ // set the velocity vector
+ m_helper.SetVelocity (Vector (m_speed * cosD * cosP,
+ m_speed * sinD * cosP,
+ m_speed * sinP));
+
+ // update buoyancy
+ m_buoyancy = GetBuoyancy (std::abs (m_speed * cosP),
+ std::abs (m_speed * sinP));
+
+ // update depth
+ m_depth = GetDepth ();
+
+ // update the helper
+ m_helper.Update ();
+
+ // notify the change
+ NotifyCourseChange ();
+}
+
+void
+GliderMobilityModel::DoMove (void)
+{
+ if (!m_deployed)
+ {
+ // the vehicle has just been deployed
+ m_deployed = true;
+ }
+
+ // unpause the helper
+ m_helper.Unpause ();
+
+ // update the helper with the new nav params
+ Update ();
+
+ // update the energy consumption
+ UpdatePowerConsumption (m_buoyancy, std::abs (m_speed * std::sin (m_pitch)));
+
+ // compute the necessary time to reach the maximum operative depth
+ // or water surface and set a stop event
+ double vertVel = m_helper.GetVelocity ().z;
+
+ if (vertVel != 0)
+ {
+ double stopTime = 0;
+ if (vertVel < 0)
+ {
+ stopTime = (m_maxDepth - DoGetDepth ()) / vertVel;
+ }
+ else
+ {
+ stopTime = (0 - DoGetDepth ()) / vertVel;
+ }
+
+ Simulator::Cancel (m_stop);
+ m_stop = Simulator::Schedule (Seconds (stopTime),
+ &GliderMobilityModel::Stop,
+ this);
+ }
+}
+
+void
+GliderMobilityModel::DoStop (void)
+{
+ // Update ();
+ m_helper.Update ();
+
+ // now the vehicle is stopped
+ m_speed = 0;
+ m_buoyancy = 0;
+
+ // update the energy consumption
+ UpdatePowerConsumption (m_buoyancy, 0);
+
+ Simulator::Cancel (m_stop);
+ m_helper.Pause ();
+}
+
+void
+GliderMobilityModel::DoEmerge (double depth)
+{
+ NS_ASSERT (depth <= 0 && depth >= m_maxDepth);
+
+ double deltaDepth = depth - GetDepth ();
+
+ // we want to emerge so the delta depth must be positive
+ NS_ASSERT (deltaDepth > 0);
+ // set the maximum pitch value
+ SetPitch (m_maxGlideAngle);
+ // set the maximum speed value
+ // from the paper, the vertical speed seems to not go over 0.15 m/s
+ // even if there are "outlayers" at 0.5 m/s
+ SetSpeed (m_maxW / std::sin (m_pitch));
+
+ // compute the time needed to reach to the specified depth
+ double emergeTime = deltaDepth / m_maxW;
+
+ // set an event to stop the vehicle when it have reached the specified depth
+ m_stop = Simulator::Schedule (Seconds (emergeTime),
+ &GliderMobilityModel::DoStop,
+ this);
+
+ if (!m_emergeCb.IsNull ())
+ {
+ // schedule the call to the emerge callback
+ Simulator::Schedule (Seconds (emergeTime),
+ &GliderMobilityModel::m_emergeCb,
+ this,
+ this);
+ }
+}
+
+void
+GliderMobilityModel::DoSubmerge (double depth)
+{
+ NS_ASSERT (depth >= m_maxDepth && depth <= 0);
+
+ double deltaDepth = depth - GetDepth ();
+
+ // we want to submerge so the delta depth must be negative
+ NS_ASSERT (deltaDepth < 0);
+ // set the maximum pitch value
+ SetPitch (-m_maxGlideAngle);
+ // set the maximum speed value
+ SetSpeed (-m_maxW / std::sin (m_pitch));
+
+ // compute the time needed to reach to the specified depth
+ double submergeTime = deltaDepth / -m_maxW;
+ // set an event to stop the vehicle when it have reached the specified depth
+ m_stop = Simulator::Schedule (Seconds (submergeTime),
+ &GliderMobilityModel::DoStop,
+ this);
+
+ if (!m_submergeCb.IsNull ())
+ {
+ // schedule the call to the submerge callback
+ Simulator::Schedule (Seconds (submergeTime),
+ &GliderMobilityModel::m_submergeCb,
+ this,
+ this);
+ }
+}
+
+double
+GliderMobilityModel::DoGetPitch () const
+{
+ return m_pitch * 180 / M_PI;
+}
+
+void
+GliderMobilityModel::DoSetPitch (double pitch)
+{
+ // actually sets the glide angle
+ NS_ASSERT_MSG (std::abs (pitch) <= m_maxGlideAngle,
+ "An excessive glide angle has been set");
+
+ NS_ASSERT_MSG (std::abs (pitch) >= m_minGlideAngle,
+ "An insufficient glide angle has been set");
+
+ // the pitch angle is stored in radians
+ m_pitch = pitch * M_PI / 180;
+
+ Update ();
+}
+
+double
+GliderMobilityModel::DoGetDepth (void)
+{
+ // update the current depth
+ Vector pos = GetPosition ();
+ m_depth = pos.z;
+
+ return m_depth;
+}
+
+double
+GliderMobilityModel::DoGetDirection (void) const
+{
+ return m_direction * 180 / M_PI;
+}
+
+void
+GliderMobilityModel::DoSetDirection (double dir)
+{
+ m_direction = dir * M_PI / 180;
+
+ Update ();
+}
+
+double
+GliderMobilityModel::DoGetSpeed () const
+{
+ return m_speed;
+}
+
+void
+GliderMobilityModel::DoSetSpeed (double speed)
+{
+ NS_ASSERT ((float) speed <= (float) m_maxW / std::sin (m_maxGlideAngle * M_PI / 180));
+
+ m_speed = speed;
+
+ Update ();
+ Move ();
+}
+
+double
+GliderMobilityModel::GetBuoyancy (double U, double W) const
+{
+ // here we get the bouyancy needed to mantain
+ // the given velocity at the given glide anlge
+ double a = 0.0022436;
+ double b = 0.01249;
+ double c = 9.8016e-6;
+ // v^2=U^2+W^2
+ double v = std::sqrt (U * U + W * W);
+ // water density kg/m^3
+ double rho = 1023;
+ // dynamic pressure
+ double q = 0.5 * rho * (v * v);
+ // seaglider hull length, in m
+ double l = 1.8;
+
+ double tgteta = W / U;
+ double teta = std::atan (tgteta);
+
+ double lambda = (a * a) / (b * (1 / std::pow (q, 0.25)) * c);
+
+ double temp = (q * (l * l) * (a * a) * std::sin (teta)) /
+ (2 * c * (std::cos (teta) * std::cos (teta)));
+
+ // positive sqrt solution for Buoyancy
+ // double Bp = temp*(1 + std::sqrt(1 - 4/(lambda*(tgteta * tgteta))));
+ // negative sqrt solution for Buoyancy
+ double Bn = temp * (1 - std::sqrt (1 - 4 / (lambda * (tgteta * tgteta))));
+
+ // the negative solution is returned, as the more efficient, as said into the article
+ // TODO discrepancies with paper values
+ return Bn * 100;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/glider-mobility-model.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef GLIDER_MOBILITY_MODEL_H_
+#define GLIDER_MOBILITY_MODEL_H_
+
+#include "auv-mobility-model.h"
+#include "ns3/constant-velocity-helper.h"
+#include "ns3/box.h"
+#include "ns3/event-id.h"
+#include "ns3/vector.h"
+
+namespace ns3 {
+
+/**
+ * \brief keep track of the position of a Seaglider AUV
+ *
+ * The model is based on the constant velocity mobility model but introduces the physical
+ * constraints characteristics of the Seaglider AUV:
+ *
+ * - maximum operational depth, 1000 m
+ * - minimum glide angle, +/- 14 degrees
+ * - maximum glide angle, +/- 68,2 degrees
+ * - maximum horizontal speed, 0.32 m/s
+ * - maximum vertical speed, 0.5
+ * - maximum buoyancy, 200 grams
+ *
+ * Unlike motor propelled AUV, Seaglider exploits small changes in its buoyancy that,
+ * in conjunction with wings, can convert vertical motion to horizontal.
+ * So, a glider will reach a point into the water by describing a "saw-tooth" movement.
+ * Thus the model, keeps track also of the buoyancy needed to maintain a given speed value.
+ *
+ * All the technical details and model's equations, can be found in [1]
+ *
+ * References:
+ * [1] Eriksen et al, "Seaglider: A Long-Range Autonomous Underwater Vehicle for Oceanographic Research"
+ * URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=972073&userType=inst
+ */
+class GliderMobilityModel : public AuvMobilityModel
+{
+public:
+ static TypeId GetTypeId (void);
+ GliderMobilityModel ();
+
+ /**
+ * \returns the current buoyancy of the glider in grams
+ */
+ double GetBuoyancy (void) const;
+ /**
+ * \param node the node associated with the mobility model
+ */
+ void SetNode (const Ptr<Node> node);
+ /**
+ * \returns the associated node
+ */
+ Ptr<Node> GetNode (void) const;
+
+ virtual void SetEmergeCallback (Callback<void, Ptr<MobilityModel> > cb);
+ virtual void SetSubmergeCallback (Callback<void, Ptr<MobilityModel> > cb);
+
+private:
+ /**
+ * Round a Vector of double, to the given decimal precision
+ *
+ * \param pos the position vector to be rounded
+ * \param decimals the decimal precision
+ * \returns the rounded position vector
+ */
+ Vector RoundPosition (const Vector &pos, uint16_t decimals) const;
+ void Update (void);
+ void UpdatePowerConsumption (double buoyancy, double W);
+
+ virtual Vector DoGetPosition (void) const;
+ virtual void DoSetPosition (const Vector &position);
+ virtual Vector DoGetVelocity (void) const;
+
+ virtual void DoMove (void);
+ virtual void DoStop (void);
+ virtual void DoEmerge (double depth);
+ virtual void DoSubmerge (double depth);
+ virtual double DoGetPitch () const;
+ virtual void DoSetPitch (double pitch);
+ virtual double DoGetDepth (void);
+ virtual double DoGetDirection (void) const;
+ virtual void DoSetDirection (double dir);
+ virtual double DoGetSpeed () const;
+ virtual void DoSetSpeed (double speed);
+ virtual void DoSetVelocity (const Vector &velocity);
+
+ // get the buoyancy value in grams from vertical and horizontal speed values
+ double GetBuoyancy (double U, double W) const;
+
+ ConstantVelocityHelper m_helper;
+ double m_direction;
+ double m_speed;
+ double m_pitch;
+ double m_depth;
+ double m_buoyancy;
+ double m_minGlideAngle;
+ double m_maxGlideAngle;
+ double m_maxU;
+ double m_maxW;
+ double m_maxBuoyancy;
+ double m_maxDepth;
+ bool m_deployed;
+
+ EventId m_stop;
+ Ptr<Node> m_node;
+
+ Callback<void, Ptr<MobilityModel> > m_emergeCb;
+ Callback<void, Ptr<MobilityModel> > m_submergeCb;
+};
+
+}; // namespace ns3
+
+#endif /* GLIDER_MOBILITY_MODEL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/remus-energy-model.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/double.h"
+#include "ns3/simulator.h"
+#include "ns3/trace-source-accessor.h"
+#include "remus-energy-model.h"
+
+NS_LOG_COMPONENT_DEFINE ("RemusEnergyModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (RemusEnergyModel);
+
+TypeId
+RemusEnergyModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::RemusEnergyModel")
+ .SetParent<DeviceEnergyModel> ()
+ .AddConstructor<RemusEnergyModel> ()
+ .AddAttribute ("PowerSpeedRatio",
+ "Consumed power ratio with respect to motor speed",
+ DoubleValue (10.0), // in W*s/m
+ MakeDoubleAccessor (&RemusEnergyModel::m_powerSpeedRatio),
+ MakeDoubleChecker<double> ())
+ .AddTraceSource ("TotalEnergyConsumption",
+ "Total energy consumption of the radio device.",
+ MakeTraceSourceAccessor (&RemusEnergyModel::m_totalEnergyConsumption))
+ ;
+ return tid;
+}
+
+RemusEnergyModel::RemusEnergyModel ()
+{
+ NS_LOG_FUNCTION (this);
+ m_currentSpeed = 0.0;
+ m_lastUpdateTime = Seconds (0.0);
+ m_energyDepletionCallback.Nullify ();
+ m_node = 0;
+ m_source = 0;
+}
+
+RemusEnergyModel::~RemusEnergyModel ()
+{
+ m_energyDepletionCallback.Nullify ();
+ m_node = 0;
+ m_source = 0;
+}
+void
+RemusEnergyModel::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+ NS_ASSERT (node != NULL);
+ m_node = node;
+}
+
+Ptr<Node>
+RemusEnergyModel::GetNode (void) const
+{
+ return m_node;
+}
+
+void
+RemusEnergyModel::SetEnergySource (Ptr<EnergySource> source)
+{
+ NS_LOG_FUNCTION (this << source);
+ NS_ASSERT (source != 0);
+ m_source = source;
+}
+
+double
+RemusEnergyModel::GetTotalEnergyConsumption (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_totalEnergyConsumption;
+}
+
+void
+RemusEnergyModel::ChangeState (int newState)
+{
+ NS_FATAL_ERROR ("ChangeState not implemented, use ChangeEnergyConsumption instead.");
+}
+
+void
+RemusEnergyModel::ChangeEnergyConsumption (const double speed)
+{
+ NS_LOG_FUNCTION (this << speed);
+
+ Time duration = Simulator::Now () - m_lastUpdateTime;
+ NS_ASSERT (duration.GetNanoSeconds () >= 0); // check if duration is valid
+
+ // update remaining energy accordingly
+ double power = GetPower (speed);
+ double energyToDecrease = duration.GetSeconds () * power;
+
+ // update total energy consumption
+ m_totalEnergyConsumption += energyToDecrease;
+
+ // update current speed value
+ m_currentSpeed = speed;
+ // update current drain
+ double supplyVoltage = m_source->GetSupplyVoltage ();
+ m_actualCurrentDrain = power / supplyVoltage;
+
+ // update last update time stamp
+ m_lastUpdateTime = Simulator::Now ();
+
+ // notify energy source
+ m_source->UpdateEnergySource ();
+
+ // some debug message
+ NS_LOG_DEBUG ("GliderEnergyModel:Total energy consumption at node #" <<
+ m_node->GetId () << " is " << m_totalEnergyConsumption << "J");
+}
+
+void
+RemusEnergyModel::SetEnergyDepletionCallback (RemusEnergyDepletionCallback callback)
+{
+ NS_LOG_FUNCTION (this);
+ if (callback.IsNull ())
+ {
+ NS_LOG_DEBUG ("RemusEnergyModel:Setting NULL energy depletion callback!");
+ }
+ m_energyDepletionCallback = callback;
+}
+
+void
+RemusEnergyModel::HandleEnergyDepletion (void)
+{
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG ("RemusEnergyModel:Energy is depleted at node #" <<
+ m_node->GetId ());
+ // invoke energy depletion callback, if set.
+ if (!m_energyDepletionCallback.IsNull ())
+ {
+ m_energyDepletionCallback ();
+ }
+}
+
+/*
+ * Private functions start here.
+ */
+
+void
+RemusEnergyModel::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_node = 0;
+ m_source = 0;
+ m_energyDepletionCallback.Nullify ();
+}
+
+double
+RemusEnergyModel::DoGetCurrentA (void) const
+{
+ NS_LOG_FUNCTION (this);
+
+ return m_actualCurrentDrain;
+}
+
+double
+RemusEnergyModel::GetPower (double speed) const
+{
+ // power needed, in watts
+ // it is about 10 times the speed in m/s, thus for 1.5 m/s of navigation speed
+ // the electric motor will drain 15 W of power
+ double power = speed * m_powerSpeedRatio;
+
+ return power;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/remus-energy-model.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,142 @@
+#ifndef GLIDER_ENERGY_MODEL_H
+#define GLIDER_ENERGY_MODEL_H
+
+#include "ns3/device-energy-model.h"
+#include "ns3/energy-source.h"
+#include "ns3/nstime.h"
+#include "ns3/event-id.h"
+#include "ns3/traced-value.h"
+
+namespace ns3 {
+
+/**
+ * \brief Keeps track of the REMUS AUV energy consumption
+ *
+ * The class model the energy consumed by the AUV for navigation.
+ * The REMUS is propelled by a brush-less electric motor.
+ *
+ * Consumption values have been taken from [1] and Hydroinc European salesman.
+ * A typical value is 15 W @ 1.5 m/s of navigation speed.
+ *
+ * Since there are not detailed datasheet and specifications publicly available,
+ * a power consumption linear with speed, is considered.
+ *
+ * References:
+ * [1] Hydroinc REMUS 100 specifications; http://www.hydroidinc.com/100spec.html
+ */
+class RemusEnergyModel : public DeviceEnergyModel
+{
+public:
+ // / Callback type for energy depletion handling.
+ typedef Callback<void> RemusEnergyDepletionCallback;
+
+public:
+ static TypeId GetTypeId (void);
+ RemusEnergyModel ();
+ virtual ~RemusEnergyModel ();
+
+ /**
+ * \brief Sets pointer to node.
+ *
+ * \param node Pointer to node.
+ *
+ * Implements DeviceEnergyModel::SetNode.
+ */
+ virtual void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Gets pointer to node.
+ *
+ * \returns Pointer to node.
+ *
+ * Implements DeviceEnergyModel::GetNode.
+ */
+ virtual Ptr<Node> GetNode (void) const;
+
+ /**
+ * \brief Sets pointer to EnergySouce installed on node.
+ *
+ * \param source Pointer to EnergySource installed on node.
+ *
+ * Implements DeviceEnergyModel::SetEnergySource.
+ */
+ virtual void SetEnergySource (Ptr<EnergySource> source);
+
+ /**
+ * \returns Total energy consumption of the vehicle.
+ *
+ * Implements DeviceEnergyModel::GetTotalEnergyConsumption.
+ */
+ virtual double GetTotalEnergyConsumption (void) const;
+
+ /**
+ * \param newState New state the device is in.
+ *
+ * DeviceEnergyModel is a state based model. This function is implemented by
+ * all child of DeviceEnergyModel to change the model's state. States are to
+ * be defined by each child using an enum (int).
+ */
+ virtual void ChangeState (int newState);
+
+ /**
+ * \param speed the speed value of the vehicle
+ *
+ * Update the energy consumption according to the speed value.
+ */
+ void ChangeEnergyConsumption (const double speed);
+
+ /**
+ * \param callback Callback function.
+ *
+ * Sets callback for energy depletion handling.
+ */
+ void SetEnergyDepletionCallback (RemusEnergyDepletionCallback callback);
+
+ /**
+ * \brief Handles energy depletion.
+ *
+ * Implements DeviceEnergyModel::HandleEnergyDepletion
+ */
+ virtual void HandleEnergyDepletion (void);
+
+private:
+ void DoDispose (void);
+
+ /**
+ * \returns Current draw of device, at current state.
+ *
+ * Implements DeviceEnergyModel::GetCurrentA.
+ */
+ virtual double DoGetCurrentA (void) const;
+
+ /**
+ * \param speed the navigation speed in m/s
+ * \return the needed power in watts
+ *
+ * This get the power needed to maintain a given speed value.
+ */
+ double GetPower (double speed) const;
+
+private:
+ Ptr<Node> m_node;
+ Ptr<EnergySource> m_source;
+
+ // This variable keeps track of the total energy consumed by this particular model.
+ TracedValue<double> m_totalEnergyConsumption;
+
+ // actual current drain
+ double m_actualCurrentDrain;
+ // current navigation speed in m/s
+ double m_currentSpeed;
+ // time stamp of previous energy update
+ Time m_lastUpdateTime;
+
+ double m_powerSpeedRatio;
+
+ // energy depletion callback
+ RemusEnergyDepletionCallback m_energyDepletionCallback;
+};
+
+} // namespace ns3
+
+#endif /* GLIDER_ENERGY_MODEL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/remus-mobility-model.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,397 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "remus-mobility-model.h"
+#include <cmath>
+#include "ns3/double.h"
+#include "ns3/simulator.h"
+#include "ns3/energy-source.h"
+#include "ns3/energy-source-container.h"
+#include "ns3/device-energy-model-container.h"
+#include "ns3/remus-energy-model.h"
+#include "ns3/vector.h"
+#include "ns3/log.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("RemusMobilityModel");
+
+NS_OBJECT_ENSURE_REGISTERED (RemusMobilityModel);
+
+TypeId
+RemusMobilityModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::RemusMobilityModel")
+ .SetParent (AuvMobilityModel::GetTypeId ())
+ .AddConstructor<RemusMobilityModel> ()
+ .AddAttribute ("MaxDepth", "The maximum operational depth, in m",
+ DoubleValue (-100.0),
+ MakeDoubleAccessor (&RemusMobilityModel::m_maxDepth),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MinSpeed", "The minimum speed of the vehicle, in m/s.",
+ DoubleValue (0.25),
+ MakeDoubleAccessor (&RemusMobilityModel::m_minSpeed),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxSpeed", "The maximum speed of the vehicle, in m/s.",
+ DoubleValue (2.8),
+ MakeDoubleAccessor (&RemusMobilityModel::m_maxSpeed),
+ MakeDoubleChecker<double> ())
+ ;
+ return tid;
+}
+
+RemusMobilityModel::RemusMobilityModel ()
+ : m_direction (0),
+ m_speed (0),
+ m_pitch (0),
+ m_depth (0),
+ m_maxPitch (60),
+ m_deployed (false)
+{
+}
+
+Vector
+RemusMobilityModel::RoundPosition (const Vector &pos, uint16_t decimals) const
+{
+ Vector roundPos;
+
+ double off = std::pow (10, decimals);
+ roundPos.x = (std::floor ((pos.x * off) + 0.5)) / off;
+ roundPos.y = (std::floor ((pos.y * off) + 0.5)) / off;
+ roundPos.z = (std::floor ((pos.z * off) + 0.5)) / off;
+
+ return roundPos;
+}
+
+void
+RemusMobilityModel::SetNode (const Ptr<Node> node)
+{
+ NS_ASSERT (node != 0);
+ m_node = node;
+}
+
+Ptr<Node>
+RemusMobilityModel::GetNode (void) const
+{
+ return m_node;
+}
+
+void
+RemusMobilityModel::SetEmergeCallback (Callback<void, Ptr<MobilityModel> > cb)
+{
+ m_emergeCb = cb;
+}
+
+void
+RemusMobilityModel::SetSubmergeCallback (Callback<void, Ptr<MobilityModel> > cb)
+{
+ m_submergeCb = cb;
+}
+
+Vector
+RemusMobilityModel::DoGetPosition (void) const
+{
+ // update the helper position
+ m_helper.Update ();
+
+ // get the current position
+ Vector pos = m_helper.GetCurrentPosition ();
+
+ // get the rounded precision position
+ Vector rpos = RoundPosition (pos, 4);
+
+ return rpos;
+}
+
+void
+RemusMobilityModel::DoSetPosition (const Vector &position)
+{
+ NS_ASSERT (!m_deployed);
+
+ m_helper.SetPosition (position);
+}
+
+Vector
+RemusMobilityModel::DoGetVelocity (void) const
+{
+ return m_helper.GetVelocity ();
+}
+
+void
+RemusMobilityModel::DoSetVelocity (const Vector &velocity)
+{
+ // if velocity is 0
+ if (CalculateDistance (velocity,Vector (0, 0, 0)) == 0)
+ {
+ // stop the vehicle
+ DoStop ();
+
+ return;
+ }
+
+ // convert the cartesians coordinates into polar one
+
+ double speed = std::sqrt ((velocity.x * velocity.x) +
+ (velocity.y * velocity.y) +
+ (velocity.z * velocity.z));
+
+ NS_ASSERT (speed <= m_maxSpeed);
+ m_speed = speed;
+
+ double dir = std::atan2 (velocity.y, velocity.x);
+ m_direction = dir;
+
+ double pitch = std::asin ((velocity.z / speed));
+ NS_ASSERT (std::abs (pitch * 180 / M_PI) <= m_maxPitch);
+ m_pitch = pitch;
+
+ m_helper.SetVelocity (velocity);
+
+ Move ();
+}
+
+void
+RemusMobilityModel::UpdatePowerConsumption (const double speed)
+{
+ Ptr<EnergySourceContainer> source = m_node->GetObject<EnergySourceContainer> ();
+ if (source != 0)
+ {
+ // retrieve device energy model from energy source
+ DeviceEnergyModelContainer modelCont =
+ source->Get (0)->FindDeviceEnergyModels ("ns3::RemusEnergyModel");
+
+ NS_ASSERT (modelCont.GetN () != 0);
+ // get pointer
+ Ptr<RemusEnergyModel> devModel = DynamicCast<RemusEnergyModel> (modelCont.Get (0));
+ devModel->ChangeEnergyConsumption (speed);
+ }
+}
+
+void
+RemusMobilityModel::Update (void)
+{
+ // get the vector components
+ double cosD = std::cos (m_direction);
+ double cosP = std::cos (m_pitch);
+ double sinD = std::sin (m_direction);
+ double sinP = std::sin (m_pitch);
+
+ // set the velocity vector
+ m_helper.SetVelocity (Vector (m_speed * cosD * cosP, m_speed * sinD * cosP, m_speed * sinP));
+
+ // update depth
+ m_depth = GetDepth ();
+
+ // update the helper
+ m_helper.Update ();
+
+ // notify the change
+ NotifyCourseChange ();
+}
+
+void
+RemusMobilityModel::DoMove (void)
+{
+ if (!m_deployed)
+ {
+ // the vehicle has just been deployed
+ m_deployed = true;
+ }
+
+ // unpause the helper
+ m_helper.Unpause ();
+
+ // update the helper with the new nav params
+ Update ();
+
+ // update the energy consumption
+ UpdatePowerConsumption (m_speed);
+
+ // compute the necessary time to reach the maximum operative depth
+ // or water surface and set a stop event
+ double vertVel = m_helper.GetVelocity ().z;
+
+ if (vertVel != 0)
+ {
+ double stopTime = 0;
+ if (vertVel < 0)
+ {
+ stopTime = (m_maxDepth - DoGetDepth ()) / vertVel;
+ }
+ else
+ {
+ stopTime = (0 - DoGetDepth ()) / vertVel;
+ }
+
+ Simulator::Cancel (m_stop);
+ m_stop = Simulator::Schedule (Seconds (stopTime),
+ &RemusMobilityModel::Stop,
+ this);
+ }
+}
+
+void
+RemusMobilityModel::DoStop (void)
+{
+ // Update ();
+ m_helper.Update ();
+
+ // now the vehicle is stopped
+ m_speed = 0;
+
+ // update the energy consumption
+ UpdatePowerConsumption (m_speed);
+
+ Simulator::Cancel (m_stop);
+ m_helper.Pause ();
+}
+
+void
+RemusMobilityModel::DoEmerge (double depth)
+{
+ NS_ASSERT (depth <= 0 && depth >= m_maxDepth);
+
+ double deltaDepth = depth - GetDepth ();
+
+ // we want to emerge so the delta depth must be positive
+ NS_ASSERT (deltaDepth > 0);
+ // set the maximum pitch value
+ SetPitch (m_maxPitch);
+ // set the maximum speed value
+ SetSpeed (m_maxSpeed);
+
+ // compute the time needed to reach to the specified depth
+ double emergeTime = deltaDepth / (m_speed * std::sin (m_pitch));
+
+ // set an event to stop the vehicle when it have reached the specified depth
+ m_stop = Simulator::Schedule (Seconds (emergeTime),
+ &RemusMobilityModel::DoStop,
+ this);
+
+ // schedule the call to the emerge callback
+ if (!m_emergeCb.IsNull ())
+ {
+ Simulator::Schedule (Seconds (emergeTime),
+ &RemusMobilityModel::m_emergeCb,
+ this,
+ this);
+ }
+}
+
+void
+RemusMobilityModel::DoSubmerge (double depth)
+{
+ NS_ASSERT (depth >= m_maxDepth && depth <= 0);
+
+ double deltaDepth = depth - GetDepth ();
+
+ // we want to submerge so the delta depth must be negative
+ NS_ASSERT (deltaDepth < 0);
+ // set the maximum pitch value, negative because we're going down
+ SetPitch (-m_maxPitch);
+ // set the maximum speed value
+ SetSpeed (m_maxSpeed);
+
+ // compute the time needed to reach to the specified depth
+ double submergeTime = deltaDepth / (m_speed * std::sin (m_pitch));
+
+ // set an event to stop the vehicle when it have reached the specified depth
+ m_stop = Simulator::Schedule (Seconds (submergeTime),
+ &RemusMobilityModel::DoStop,
+ this);
+
+ // schedule the call to the submerge callback
+ if (!m_submergeCb.IsNull ())
+ {
+ Simulator::Schedule (Seconds (submergeTime),
+ &RemusMobilityModel::m_submergeCb,
+ this,
+ this);
+ }
+}
+
+double
+RemusMobilityModel::DoGetPitch () const
+{
+ // the pitch angle is stored in radians
+ return m_pitch * 180 / M_PI;
+}
+
+void
+RemusMobilityModel::DoSetPitch (double pitch)
+{
+ NS_ASSERT_MSG (std::abs (pitch) <= m_maxPitch,
+ "An excessive pitch angle has been set");
+
+ // the pitch angle is stored in radians
+ m_pitch = pitch * M_PI / 180;
+
+ Update ();
+}
+
+double
+RemusMobilityModel::DoGetDepth (void)
+{
+ // update the current depth
+ Vector pos = GetPosition ();
+ m_depth = pos.z;
+
+ return m_depth;
+}
+
+double
+RemusMobilityModel::DoGetDirection (void) const
+{
+ return m_direction * 180 / M_PI;
+}
+
+void
+RemusMobilityModel::DoSetDirection (double dir)
+{
+ m_direction = dir * M_PI / 180;
+
+ Update ();
+}
+
+double
+RemusMobilityModel::DoGetSpeed () const
+{
+ return m_speed;
+}
+
+void
+RemusMobilityModel::DoSetSpeed (double speed)
+{
+ NS_ASSERT (speed <= m_maxSpeed);
+
+ if (speed < m_minSpeed)
+ {
+ m_speed = 0;
+ }
+ else
+ {
+ m_speed = speed;
+ }
+
+ Update ();
+ Move ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/model/remus-mobility-model.h Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#ifndef REMUS_MOBILITY_MODEL_H_
+#define REMUS_MOBILITY_MODEL_H_
+
+#include "auv-mobility-model.h"
+#include "ns3/constant-velocity-helper.h"
+#include "ns3/box.h"
+#include "ns3/event-id.h"
+
+namespace ns3 {
+
+/**
+ * \brief keep track of the position of a REMUS AUV
+ *
+ * A REMUS class AUV is an submarine-like device, propelled by an electric motor linked with a propeller.
+ *
+ * The model is based on the constant velocity mobility model but introduces the physical
+ * constraints characteristics of the REMUS AUV [1][2]:
+ *
+ * - maximum operational depth, 100 m
+ * - minimum speed, 0.25 m/s
+ * - maximum speed, 2.8 m/s
+ * - pitch range, +/- 60 degrees
+ *
+ * References:
+ * [1] Hydroinc Products; http://www.hydroidinc.com/products.html
+ * [2] WHOI, Autonomous Underwater Vehicle, REMUS; http://www.whoi.edu/page.do?pid=29856
+ */
+class RemusMobilityModel : public AuvMobilityModel
+{
+public:
+ static TypeId GetTypeId (void);
+ RemusMobilityModel ();
+
+ /**
+ * \param node the node associated with the mobility model
+ */
+ void SetNode (const Ptr<Node> node);
+ /**
+ * \returns the associated node
+ */
+ Ptr<Node> GetNode (void) const;
+ /**
+ * Set a callback to be called at the end of the emerging process
+ *
+ * \param cb the callback to be set
+ */
+ virtual void SetEmergeCallback (Callback<void, Ptr<MobilityModel> > cb);
+ /**
+ * Set a callback to be called at the end of the submerging process
+ *
+ * \param cb the callback to be set
+ */
+ virtual void SetSubmergeCallback (Callback<void, Ptr<MobilityModel> > cb);
+
+private:
+ /**
+ * Round a Vector of double, to the given decimal precision
+ *
+ * \param pos the position vector to be rounded
+ * \param decimals the decimal precision
+ * \returns the rounded position vector
+ */
+ Vector RoundPosition (const Vector &pos, uint16_t decimals) const;
+ void Update (void);
+ void UpdatePowerConsumption (const double speed);
+
+ virtual Vector DoGetPosition (void) const;
+ virtual void DoSetPosition (const Vector &position);
+ virtual Vector DoGetVelocity (void) const;
+
+ virtual void DoMove (void);
+ virtual void DoStop (void);
+ virtual void DoEmerge (double depth);
+ virtual void DoSubmerge (double depth);
+ virtual double DoGetPitch () const;
+ virtual void DoSetPitch (double pitch);
+ virtual double DoGetDepth (void);
+ virtual double DoGetDirection (void) const;
+ virtual void DoSetDirection (double dir);
+ virtual double DoGetSpeed () const;
+ virtual void DoSetSpeed (double speed);
+ virtual void DoSetVelocity (const Vector &velocity);
+
+ ConstantVelocityHelper m_helper;
+ double m_direction;
+ double m_speed;
+ double m_pitch;
+ double m_depth;
+ double m_minSpeed;
+ double m_maxSpeed;
+ double m_maxDepth;
+ // maximum pitch value, in degrees
+ double m_maxPitch;
+ bool m_deployed;
+ EventId m_stop;
+ Ptr<Node> m_node;
+
+ Callback<void, Ptr<MobilityModel> > m_emergeCb;
+ Callback<void, Ptr<MobilityModel> > m_submergeCb;
+};
+
+}; // namespace ns3
+
+#endif /* REMUS_MOBILITY_MODEL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/test/auv-energy-model-test.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,493 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/test.h"
+#include "ns3/simple-device-energy-model.h"
+#include "ns3/uan-net-device.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/auv-glider-helper.h"
+#include "ns3/auv-remus-helper.h"
+#include "ns3/waypoint-mobility-model.h"
+#include "ns3/uan-helper.h"
+#include "ns3/basic-energy-source-helper.h"
+#include "ns3/acoustic-modem-energy-model-helper.h"
+#include "ns3/acoustic-modem-energy-model.h"
+#include "ns3/constant-position-mobility-model.h"
+#include "ns3/uan-channel.h"
+#include "ns3/uan-noise-model-default.h"
+#include "ns3/uan-prop-model-ideal.h"
+#include "ns3/uan-header-common.h"
+#include "ns3/uan-phy.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("AuvEnergyModelTestSuite");
+
+/*
+class AcousticModemEnergyTestCase : public TestCase
+{
+public:
+ AcousticModemEnergyTestCase ();
+ ~AcousticModemEnergyTestCase ();
+
+ bool RxPacket (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender);
+ void SendOnePacket (Ptr<Node> node);
+
+ void DoRun (void);
+
+ double m_simTime;
+ uint32_t m_bytesRx;
+ uint32_t m_sentPackets;
+ uint32_t m_packetSize;
+ Ptr<Node> m_node;
+ Ptr<Node> m_gateway;
+};
+
+AcousticModemEnergyTestCase::AcousticModemEnergyTestCase ()
+ : TestCase ("Acoustic Modem energy model test case"),
+ m_simTime (25),
+ m_bytesRx (0),
+ m_sentPackets (0),
+ m_packetSize (17)
+{
+}
+
+AcousticModemEnergyTestCase::~AcousticModemEnergyTestCase ()
+{
+ m_node = 0;
+ m_gateway = 0;
+}
+
+void
+AcousticModemEnergyTestCase::SendOnePacket (Ptr<Node> node)
+{
+ // create an empty 17 bytes packet
+ Ptr<Packet> pkt = Create<Packet> (m_packetSize);
+ // send the packet in broadcast
+ Ptr<UanNetDevice> dev = node->GetDevice (0)->GetObject<UanNetDevice> ();
+ dev->Send (pkt, dev->GetBroadcast (), 0);
+ // increase the sent packets number
+ ++m_sentPackets;
+
+ Simulator::Schedule (Seconds (10),
+ &AcousticModemEnergyTestCase::SendOnePacket,
+ this,
+ node);
+}
+
+bool
+AcousticModemEnergyTestCase::RxPacket (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender)
+{
+ // increase the total bytes received
+ m_bytesRx += pkt->GetSize ();
+
+ return true;
+}
+
+void
+AcousticModemEnergyTestCase::DoRun ()
+{
+ // create a generic node
+ m_node = CreateObject<Node> ();
+
+ // create a default underwater channel
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise = CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ // install the underwater communication stack
+ UanHelper uan;
+ Ptr<UanNetDevice> devNode = uan.Install (m_node, channel);
+
+ // compute a packet (header + payload) duration
+ uint32_t datarate = devNode->GetPhy ()->GetMode (0).GetDataRateBps ();
+ UanHeaderCommon hd;
+ double packetDuration = (m_packetSize + hd.GetSerializedSize ()) * 8.0 / (double) datarate;
+
+ // energy source
+ BasicEnergySourceHelper eh;
+ eh.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (10000000.0));
+ eh.Install (m_node);
+
+ // mobility model
+ Ptr<ConstantPositionMobilityModel> mobility = CreateObject<ConstantPositionMobilityModel> ();
+ mobility->SetPosition (Vector (0,0,-500));
+ m_node->AggregateObject (mobility);
+
+ // micro modem energy model
+ AcousticModemEnergyModelHelper modemHelper;
+ Ptr<EnergySource> source = m_node->GetObject<EnergySourceContainer> ()->Get (0);
+ DeviceEnergyModelContainer cont = modemHelper.Install (devNode,source);
+
+ // Schedule a packet every 10 seconds
+ Simulator::ScheduleNow (&AcousticModemEnergyTestCase::SendOnePacket,
+ this,
+ m_node);
+
+ // create a gateway node
+ m_gateway = CreateObject<Node> ();
+
+ // install the underwater communication stack
+ Ptr<UanNetDevice> devGateway = uan.Install (m_gateway, channel);
+
+ // energy source
+ eh.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (10000000.0));
+ eh.Install (m_gateway);
+
+ // mobility model
+ Ptr<ConstantPositionMobilityModel> mobility2 = CreateObject<ConstantPositionMobilityModel> ();
+ mobility2->SetPosition (Vector (0,0,0));
+ m_gateway->AggregateObject (mobility2);
+
+ // micro modem energy model
+ Ptr<EnergySource> source2 = m_gateway->GetObject<EnergySourceContainer> ()->Get (0);
+ DeviceEnergyModelContainer cont2 = modemHelper.Install (devGateway, source2);
+
+ // set the receive callback
+ Ptr<NetDevice> dev = m_gateway->GetDevice (0);
+ dev->SetReceiveCallback (MakeCallback (&AcousticModemEnergyTestCase::RxPacket,
+ this));
+
+ // run the simulation
+ Simulator::Stop (Seconds (m_simTime));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ uint32_t receivedPackets = m_bytesRx / m_packetSize;
+ Ptr<EnergySource> src1 = m_gateway->GetObject<EnergySourceContainer> ()->Get (0);
+ double consumed1 = src1->GetInitialEnergy () - src1->GetRemainingEnergy ();
+ double computed1 = cont2.Get (0)->GetObject<AcousticModemEnergyModel> ()->GetRxPowerW () * packetDuration * receivedPackets +
+ cont2.Get (0)->GetObject<AcousticModemEnergyModel> ()->GetIdlePowerW () * (m_simTime - (double) 2.0 / 3.0 - packetDuration * receivedPackets);
+
+ NS_TEST_ASSERT_MSG_EQ_TOL (consumed1, computed1, 1.0e-5,
+ "Incorrect gateway consumed energy!");
+
+ Ptr<EnergySource> src2 = m_node->GetObject<EnergySourceContainer> ()->Get (0);
+ double consumed2 = src2->GetInitialEnergy () - src2->GetRemainingEnergy ();
+ double computed2 = cont.Get (0)->GetObject<AcousticModemEnergyModel> ()->GetTxPowerW () * packetDuration * m_sentPackets +
+ cont.Get (0)->GetObject<AcousticModemEnergyModel> ()->GetIdlePowerW () * (m_simTime - 1 - packetDuration * m_sentPackets);
+
+ NS_TEST_ASSERT_MSG_EQ_TOL (consumed2, computed2, 1.0e-5,
+ "Incorrect node consumed energy!");
+
+ return;
+}
+
+class AcousticModemEnergyDepletionTestCase : public TestCase
+{
+public:
+ AcousticModemEnergyDepletionTestCase ();
+ ~AcousticModemEnergyDepletionTestCase ();
+
+ void DepletionHandler (void);
+ void SendOnePacket (Ptr<Node> node);
+
+ void DoRun (void);
+
+ double m_simTime;
+ uint32_t m_callbackCount;
+ uint32_t m_packetSize;
+ Ptr<Node> m_node;
+};
+
+AcousticModemEnergyDepletionTestCase::AcousticModemEnergyDepletionTestCase ()
+ : TestCase ("Acoustic Modem energy depletion test case"),
+ m_simTime (25),
+ m_callbackCount (0),
+ m_packetSize (17)
+{
+}
+
+AcousticModemEnergyDepletionTestCase::~AcousticModemEnergyDepletionTestCase ()
+{
+ m_node = 0;
+}
+
+void
+AcousticModemEnergyDepletionTestCase::DepletionHandler (void)
+{
+ // increase callback count
+ m_callbackCount++;
+}
+
+void
+AcousticModemEnergyDepletionTestCase::SendOnePacket (Ptr<Node> node)
+{
+ // create an empty packet
+ Ptr<Packet> pkt = Create<Packet> (m_packetSize);
+ // send the packet in broadcast
+ Ptr<UanNetDevice> dev = node->GetDevice (0)->GetObject<UanNetDevice> ();
+ dev->Send (pkt, dev->GetBroadcast (), 0);
+
+ Simulator::Schedule (Seconds (10),
+ &AcousticModemEnergyDepletionTestCase::SendOnePacket,
+ this,
+ node);
+}
+
+void
+AcousticModemEnergyDepletionTestCase::DoRun (void)
+{
+ // create a generic node
+ m_node = CreateObject<Node> ();
+
+ // create a default underwater channel
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise = CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ // install the underwater communication stack
+ UanHelper uan;
+ Ptr<UanNetDevice> devNode = uan.Install (m_node, channel);
+
+ // set an empty energy source
+ BasicEnergySourceHelper eh;
+ eh.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (0.0));
+ eh.Install (m_node);
+
+ // mobility model
+ Ptr<ConstantPositionMobilityModel> mobility = CreateObject<ConstantPositionMobilityModel> ();
+ mobility->SetPosition (Vector (0,0,0));
+ m_node->AggregateObject (mobility);
+
+ // micro modem energy model
+ AcousticModemEnergyModelHelper modemHelper;
+ Ptr<EnergySource> source = m_node->GetObject<EnergySourceContainer> ()->Get (0);
+ // set the depletion callback
+ AcousticModemEnergyModel::AcousticModemEnergyDepletionCallback callback =
+ MakeCallback (&AcousticModemEnergyDepletionTestCase::DepletionHandler, this);
+ modemHelper.SetDepletionCallback (callback);
+ DeviceEnergyModelContainer cont = modemHelper.Install (devNode,source);
+
+ // try to send a packet
+ Simulator::ScheduleNow (&AcousticModemEnergyDepletionTestCase::SendOnePacket,
+ this,
+ m_node);
+
+ Simulator::Stop (Seconds (m_simTime));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ NS_TEST_ASSERT_MSG_EQ (m_callbackCount, 1, "Callback not invoked");
+
+ return;
+}
+*/
+
+class GliderEnergyTestCase : public TestCase
+{
+public:
+ GliderEnergyTestCase ();
+ ~GliderEnergyTestCase ();
+
+ void DoRun (void);
+ void GetPosition (void);
+
+ double m_simTime;
+ Ptr<Node> m_node;
+};
+
+GliderEnergyTestCase::GliderEnergyTestCase ()
+ : TestCase ("Glider energy model test case")
+{
+}
+
+GliderEnergyTestCase::~GliderEnergyTestCase ()
+{
+ m_node = 0;
+}
+
+void
+GliderEnergyTestCase::GetPosition ()
+{
+ Ptr<WaypointMobilityModel> model = m_node->GetObject<WaypointMobilityModel> ();
+ Vector pos = model->GetPosition ();
+
+ Simulator::Schedule (Seconds (1),
+ &GliderEnergyTestCase::GetPosition,
+ this);
+}
+
+void
+GliderEnergyTestCase::DoRun ()
+{
+ m_node = CreateObject<Node> ();
+
+ // create a default underwater channel
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise = CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ // install the underwater communication stack
+ UanHelper uan;
+ Ptr<UanNetDevice> devNode = uan.Install (m_node, channel);
+
+ // install the glider components
+ AuvGliderHelper gh;
+ gh.Install (m_node);
+
+ double navTime = 20;
+ double commTime = 25;
+
+ // move the vehicle somewhere
+ Ptr<WaypointMobilityModel> mob = m_node->GetObject<WaypointMobilityModel> ();
+ mob->AddWaypoint (Waypoint (Seconds (0), Vector (0,0,0)));
+ mob->AddWaypoint (Waypoint (Seconds (navTime), Vector (4.5,0,-10)));
+ // GetPosition ();
+
+ // run the simulation
+ Simulator::Stop (Seconds (commTime + 0.1));
+ Simulator::Run ();
+
+ // get the motor energy source
+ Ptr<EnergySource> motorSrc = m_node->GetObject<EnergySourceContainer> ()->Get (0);
+ double motorConsumption = motorSrc->GetInitialEnergy () - motorSrc->GetRemainingEnergy ();
+ // dovrebbe essere 0.9702456448979383 da debug
+ double motorEstimated = (navTime - 1) * 0.970004254;
+ //double gliderConsumption = motorSrc->FindDeviceEnergyModels("ns3::GliderEnergyModel").Get(0)->GetTotalEnergyConsumption();
+
+ // get the communications energy source
+ Ptr<EnergySource> modemSrc = m_node->GetObject<EnergySourceContainer> ()->Get (1);
+ double modemConsumption = modemSrc->GetInitialEnergy () - modemSrc->GetRemainingEnergy ();
+ double modemEstimated = commTime * 0.158;
+
+
+ NS_TEST_ASSERT_MSG_EQ_TOL (motorConsumption, motorEstimated, 1.0e-3,
+ "Incorrect motor consumed energy!");
+
+ NS_TEST_ASSERT_MSG_EQ_TOL (modemConsumption, modemEstimated, 1.0e-3,
+ "Incorrect modem consumed energy!");
+
+ Simulator::Destroy ();
+
+ return;
+}
+
+class RemusEnergyTestCase : public TestCase
+{
+public:
+ RemusEnergyTestCase ();
+ ~RemusEnergyTestCase ();
+
+ void DoRun (void);
+ void GetPosition (void);
+
+ double m_simTime;
+ Ptr<Node> m_node;
+};
+
+RemusEnergyTestCase::RemusEnergyTestCase ()
+ : TestCase ("Remus energy model test case")
+{
+}
+
+RemusEnergyTestCase::~RemusEnergyTestCase ()
+{
+ m_node = 0;
+}
+
+void
+RemusEnergyTestCase::GetPosition ()
+{
+ Ptr<WaypointMobilityModel> model = m_node->GetObject<WaypointMobilityModel> ();
+ Vector pos = model->GetPosition ();
+
+ Simulator::Schedule (Seconds (1),
+ &RemusEnergyTestCase::GetPosition,
+ this);
+}
+
+void
+RemusEnergyTestCase::DoRun ()
+{
+ m_node = CreateObject<Node> ();
+
+ // create a default underwater channel
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise = CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ // install the underwater communication stack
+ UanHelper uan;
+ Ptr<UanNetDevice> devNode = uan.Install (m_node, channel);
+
+ // install the glider components
+ AuvRemusHelper gh;
+ gh.Install (m_node);
+
+ double navTime = 50.0;
+ double commTime = 55.0;
+
+ // move the vehicle somewhere
+ Ptr<WaypointMobilityModel> mob = m_node->GetObject<WaypointMobilityModel> ();
+ mob->AddWaypoint (Waypoint (Seconds (0), Vector (0,0,0)));
+ mob->AddWaypoint (Waypoint (Seconds (navTime), Vector (100,0,0)));
+ GetPosition ();
+
+ // run the simulation
+ Simulator::Stop (Seconds (commTime + 0.1));
+ Simulator::Run ();
+
+ Ptr<EnergySource> src = m_node->GetObject<EnergySourceContainer> ()->Get (0);
+ double consumed = src->GetInitialEnergy () - src->GetRemainingEnergy ();
+
+ // motor + modem idle energy
+ double estimated = 20 * (navTime -1) + 0.158 * commTime;
+
+ NS_TEST_ASSERT_MSG_EQ_TOL (consumed, estimated, 1.0e-5,
+ "Incorrect consumed energy!");
+
+ Simulator::Destroy ();
+
+ return;
+}
+
+// -------------------------------------------------------------------------- //
+
+/**
+ * Unit test suite for underwater energy model. Include test on acoustic modem,
+ * acoustic modem energy depletion, glider energy model, remus energy model.
+ */
+class AuvEnergyModelTestSuite : public TestSuite
+{
+public:
+ AuvEnergyModelTestSuite ();
+};
+
+AuvEnergyModelTestSuite::AuvEnergyModelTestSuite ()
+ : TestSuite ("auv-energy-model", UNIT)
+{
+ //AddTestCase (new AcousticModemEnergyTestCase);
+ //AddTestCase (new AcousticModemEnergyDepletionTestCase);
+ AddTestCase (new GliderEnergyTestCase);
+ AddTestCase (new RemusEnergyTestCase);
+}
+
+// create an instance of the test suite
+AuvEnergyModelTestSuite g_auvEnergyModelTestSuite;
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/test/auv-mobility-test.cc Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,436 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Andrea Sacco
+ *
+ * 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: Andrea Sacco <andrea.sacco85@gmail.com>
+ */
+
+#include "ns3/remus-mobility-model.h"
+#include "ns3/glider-mobility-model.h"
+#include "ns3/waypoint-mobility-model.h"
+#include "ns3/test.h"
+#include "ns3/simulator.h"
+#include "ns3/node.h"
+#include "ns3/nstime.h"
+#include "ns3/vector.h"
+#include "ns3/log.h"
+#include "ns3/gnuplot.h"
+#include "ns3/auv-glider-helper.h"
+#include "ns3/auv-remus-helper.h"
+#include "ns3/uan-channel.h"
+#include "ns3/uan-noise-model-default.h"
+#include "ns3/uan-prop-model-ideal.h"
+#include "ns3/uan-net-device.h"
+#include "ns3/uan-helper.h"
+
+#include <cmath>
+#include <iomanip>
+
+using namespace ns3;
+
+class RemusMobilityTestCase : public TestCase
+{
+public:
+ RemusMobilityTestCase (void);
+ ~RemusMobilityTestCase (void);
+
+ virtual void DoRun (void);
+ void DoSubmergeTest (void);
+ void DoEmergeTest (void);
+ void DoNavigationTest (int16_t dir);
+
+private:
+ void SubmergeCb (Ptr<MobilityModel> mob);
+ void EmergeCb (Ptr<MobilityModel> mob);
+ void SpeedCb (int16_t dir);
+
+ Ptr<RemusMobilityModel> m_remusMob;
+};
+
+RemusMobilityTestCase::RemusMobilityTestCase ()
+ : TestCase ("Test the Remus mobility model")
+{
+}
+
+RemusMobilityTestCase::~RemusMobilityTestCase ()
+{
+ m_remusMob = 0;
+}
+
+void
+RemusMobilityTestCase::DoSubmergeTest (void)
+{
+ m_remusMob->SetSubmergeCallback (MakeCallback (&RemusMobilityTestCase::SubmergeCb,
+ this));
+ // makes the vehicle submerge to 100m
+ m_remusMob->Submerge (-100);
+}
+
+void
+RemusMobilityTestCase::DoEmergeTest (void)
+{
+ m_remusMob->SetEmergeCallback (MakeCallback (&RemusMobilityTestCase::EmergeCb,
+ this));
+ m_remusMob->Emerge (0);
+}
+
+void
+RemusMobilityTestCase::DoNavigationTest (int16_t dir)
+{
+ Vector pos = m_remusMob->GetPosition ();
+
+ if (dir == 1)
+ {
+ m_remusMob->SetPitch (0.);
+ m_remusMob->SetDirection (90);
+ m_remusMob->SetSpeed (2);
+ }
+ if (dir == -1)
+ {
+ m_remusMob->SetVelocity (Vector (0,-2,0));
+ }
+
+ Simulator::Schedule (Seconds (2),
+ &RemusMobilityTestCase::SpeedCb,
+ this,
+ dir);
+}
+
+void
+RemusMobilityTestCase::SubmergeCb (Ptr<MobilityModel> mob)
+{
+ double depth = m_remusMob->GetDepth ();
+
+ // depth should be -100
+ NS_ASSERT (depth == -100);
+}
+
+void
+RemusMobilityTestCase::EmergeCb (Ptr<MobilityModel> mob)
+{
+ double depth = m_remusMob->GetDepth ();
+
+ // the depth should be 0m
+ NS_ASSERT (depth == 0);
+}
+
+void
+RemusMobilityTestCase::SpeedCb (int16_t dir)
+{
+ Vector pos = m_remusMob->GetPosition ();
+
+ if (dir == 1)
+ {
+ // after 2 seconds along +y at 2m/s
+ NS_ASSERT (pos.y == 4);
+ }
+ if (dir == -1)
+ {
+ // after 2 seconds along -y at 2m/s
+ NS_ASSERT (pos.y == 0);
+ }
+
+ m_remusMob->Stop ();
+}
+
+void
+RemusMobilityTestCase::DoRun (void)
+{
+ Ptr<Node> auv = CreateObject<Node> ();
+
+ // create a default underwater channel
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise = CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ // install the underwater communication stack
+ UanHelper uan;
+ Ptr<UanNetDevice> devNode = uan.Install (auv, channel);
+
+ AuvRemusHelper helper;
+ helper.Install (auv);
+
+ m_remusMob = auv->GetObject<WaypointMobilityModel> ()->GetMobilityModel ()->GetObject<RemusMobilityModel> ();
+ NS_ASSERT (m_remusMob != 0);
+
+ m_remusMob->SetPosition (Vector (0.,0.,0.));
+
+ Time now = Simulator::Now ();
+
+ // submerge
+ Simulator::Schedule (now,
+ &RemusMobilityTestCase::DoSubmergeTest,
+ this);
+
+ // emerge
+ now += Seconds (100);
+ Simulator::Schedule (now,
+ &RemusMobilityTestCase::DoEmergeTest,
+ this);
+
+ // direction, pitch, speed
+ now += Seconds (100);
+ Simulator::Schedule (now,
+ &RemusMobilityTestCase::DoNavigationTest,
+ this,
+ 1);
+
+ // velocity
+ now += Seconds (100);
+ Simulator::Schedule (now,
+ &RemusMobilityTestCase::DoNavigationTest,
+ this,
+ -1);
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return;
+}
+
+class GliderMobilityTestCase : public TestCase
+{
+public:
+ GliderMobilityTestCase (void);
+ ~GliderMobilityTestCase (void);
+
+ virtual void DoRun (void);
+ void DoSubmergeTest (void);
+ void DoEmergeTest (void);
+ void DoNavigationTest (int16_t dir);
+ void DoBuoyancyTest (void);
+
+private:
+ void SubmergeCb (Ptr<MobilityModel> mob);
+ void EmergeCb (Ptr<MobilityModel> mob);
+ void SpeedCb (int16_t dir);
+
+ Ptr<GliderMobilityModel> m_gliderMob;
+ EventId m_id;
+ Vector m_lastEndPos;
+};
+
+GliderMobilityTestCase::GliderMobilityTestCase ()
+ : TestCase ("Test the Seaglider mobility model")
+{
+}
+
+GliderMobilityTestCase::~GliderMobilityTestCase ()
+{
+ m_gliderMob = 0;
+}
+
+void
+GliderMobilityTestCase::DoSubmergeTest (void)
+{
+ m_gliderMob->SetSubmergeCallback (MakeCallback (&GliderMobilityTestCase::SubmergeCb,
+ this));
+ // submerge to 1000m
+ m_gliderMob->Submerge (-1000);
+}
+
+void
+GliderMobilityTestCase::DoEmergeTest (void)
+{
+ m_gliderMob->SetEmergeCallback (MakeCallback (&GliderMobilityTestCase::EmergeCb,
+ this));
+ // emerge to water surface
+ m_gliderMob->Emerge (0);
+}
+
+void
+GliderMobilityTestCase::DoNavigationTest (int16_t dir)
+{
+ Vector pos = m_gliderMob->GetPosition ();
+
+ if (dir == 1)
+ {
+ m_gliderMob->SetPitch (-60);
+ m_gliderMob->SetDirection (45);
+ m_gliderMob->SetSpeed (0.3);
+ }
+ else if (dir == -1)
+ {
+ m_gliderMob->SetVelocity (Vector (0.2, -0.2, 0.2));
+ }
+
+ // proceed along the set direction for 60 seconds
+ Simulator::Schedule (Seconds (60),
+ &GliderMobilityTestCase::SpeedCb,
+ this,
+ dir);
+}
+
+void
+GliderMobilityTestCase::DoBuoyancyTest (void)
+{
+ double U = 0.25;
+ double W = 0.3;
+
+ m_gliderMob->SetVelocity (Vector (U, .0, W));
+
+ double buoyancy = m_gliderMob->GetBuoyancy ();
+
+ // test the buoyancy error against 1e-15 tolerance
+ NS_ASSERT ((buoyancy - 139.05836821925641) < 1e-15);
+}
+
+void
+GliderMobilityTestCase::SubmergeCb (Ptr<MobilityModel> mob)
+{
+ double depth = m_gliderMob->GetDepth ();
+
+ // depth should be -1000
+ NS_ASSERT (depth == -1000);
+
+ m_lastEndPos = m_gliderMob->GetPosition ();
+}
+
+void
+GliderMobilityTestCase::EmergeCb (Ptr<MobilityModel> mob)
+{
+ double depth = m_gliderMob->GetDepth ();
+
+ // the depth should be 0m
+ NS_ASSERT (depth == 0);
+
+ m_lastEndPos = m_gliderMob->GetPosition ();
+}
+
+void
+GliderMobilityTestCase::SpeedCb (int16_t dir)
+{
+ Vector pos = m_gliderMob->GetPosition ();
+
+ if (dir == 1)
+ {
+ double x = pos.x - m_lastEndPos.x;
+ double y = pos.y - m_lastEndPos.y;
+ double z = pos.z - m_lastEndPos.z;
+
+ double dx = x - (std::cos (45 * M_PI / 180) * std::cos (-60 * M_PI / 180) * 0.3 * 60);
+ double dy = y - (std::sin (45 * M_PI / 180) * std::cos (-60 * M_PI / 180) * 0.3 * 60);
+ double dz = z - (std::sin (-60 * M_PI / 180) * 0.3 * 60);
+
+ // test the error against 0.1 mm tolerance
+ NS_ASSERT (dx < 1e-4);
+ NS_ASSERT (dy < 1e-4);
+ NS_ASSERT (dz < 1e-4);
+
+ m_lastEndPos = pos;
+ }
+ if (dir == -1)
+ {
+ double x = pos.x - m_lastEndPos.x;
+ double y = pos.y - m_lastEndPos.y;
+ double z = pos.z - m_lastEndPos.z;
+
+ double dx = x - 0.2 * 60;
+ double dy = y - (-0.2) * 60;
+ double dz = z - 0.2 * 60;
+
+ // test the error against 0.1 mm tolerance
+ NS_ASSERT (dx < 1e-4);
+ NS_ASSERT (dy < 1e-4);
+ NS_ASSERT (dz < 1e-4);
+
+ m_lastEndPos = pos;
+
+ Simulator::Cancel (m_id);
+ }
+
+ m_gliderMob->Stop ();
+}
+
+void
+GliderMobilityTestCase::DoRun (void)
+{
+ Ptr<Node> auv = CreateObject<Node> ();
+
+ // create a default underwater channel
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise = CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ // install the underwater communication stack
+ UanHelper uan;
+ Ptr<UanNetDevice> devNode = uan.Install (auv, channel);
+
+ AuvGliderHelper helper;
+ helper.Install (auv);
+
+ m_gliderMob = auv->GetObject<WaypointMobilityModel> ()->GetMobilityModel ()->GetObject<GliderMobilityModel> ();
+ NS_ASSERT (m_gliderMob != 0);
+
+ // deploy the AUV
+ m_gliderMob->SetPosition (Vector (0.,0.,0.));
+
+ // buoyancy
+ DoBuoyancyTest ();
+
+ Time now = Simulator::Now ();
+
+ // submerge
+ Simulator::Schedule (now,
+ &GliderMobilityTestCase::DoSubmergeTest,
+ this);
+
+ // emerge
+ now += Seconds (2010);
+ Simulator::Schedule (now,
+ &GliderMobilityTestCase::DoEmergeTest,
+ this);
+
+ // direction, pitch, speed
+ now += Seconds (2010);
+ Simulator::Schedule (now,
+ &GliderMobilityTestCase::DoNavigationTest,
+ this,
+ 1);
+
+ // velocity
+ now += Seconds (100);
+ Simulator::Schedule (now,
+ &GliderMobilityTestCase::DoNavigationTest,
+ this,
+ -1);
+
+ now += Seconds (100);
+
+ Simulator::Stop (now);
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return;
+}
+
+class AuvMobilityTestSuite : public TestSuite
+{
+public:
+ AuvMobilityTestSuite ();
+};
+
+AuvMobilityTestSuite::AuvMobilityTestSuite ()
+ : TestSuite ("auv-mobility", UNIT)
+{
+ AddTestCase (new RemusMobilityTestCase);
+ AddTestCase (new GliderMobilityTestCase);
+}
+
+// create an instance of the test suite
+AuvMobilityTestSuite g_auvMobilityTestSuite;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/uan/auv/wscript Sat Apr 16 00:38:20 2011 +0200
@@ -0,0 +1,31 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ module = bld.create_ns3_module ('auv', ['uan', 'mobility', 'energy'])
+ module.source = [
+ 'model/auv-mobility-model.cc',
+ 'model/glider-energy-model.cc',
+ 'model/glider-mobility-model.cc',
+ 'model/remus-energy-model.cc',
+ 'model/remus-mobility-model.cc',
+ 'helper/auv-glider-helper.cc',
+ 'helper/auv-mobility-helper.cc',
+ 'helper/auv-remus-helper.cc',
+ 'test/auv-energy-model-test.cc',
+ 'test/auv-mobility-test.cc',
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'auv'
+ headers.source = [
+ 'model/auv-mobility-model.h',
+ 'model/glider-energy-model.h',
+ 'model/glider-mobility-model.h',
+ 'model/remus-energy-model.h',
+ 'model/remus-mobility-model.h',
+ 'helper/auv-glider-helper.h',
+ 'helper/auv-mobility-helper.h',
+ 'helper/auv-remus-helper.h',
+ ]
+
+ if (bld.env['ENABLE_EXAMPLES']):
+ bld.add_subdirs('examples')
--- a/src/wscript Sat Apr 16 00:34:39 2011 +0200
+++ b/src/wscript Sat Apr 16 00:38:20 2011 +0200
@@ -56,6 +56,7 @@
'topology-read',
'contrib/energy',
'tools/visualizer',
+ 'uan/auv',
)
def set_options(opt):