add BSM application and vanet-routing-compare example
This commit is contained in:
@@ -270,4 +270,22 @@ MobilityHelper::AssignStreams (NodeContainer c, int64_t stream)
|
||||
return (currentStream - stream);
|
||||
}
|
||||
|
||||
double
|
||||
MobilityHelper::GetDistanceSquaredBetween (Ptr<Node> n1, Ptr<Node> n2)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
double distSq = 0.0;
|
||||
|
||||
Ptr<MobilityModel> rxPosition = n1->GetObject<MobilityModel> ();
|
||||
NS_ASSERT (rxPosition != 0);
|
||||
|
||||
Ptr<MobilityModel> txPosition = n2->GetObject<MobilityModel> ();
|
||||
NS_ASSERT (txPosition != 0);
|
||||
|
||||
double dist = rxPosition -> GetDistanceFrom (txPosition);
|
||||
distSq = dist * dist;
|
||||
|
||||
return distSq;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -260,6 +260,13 @@ public:
|
||||
*/
|
||||
int64_t AssignStreams (NodeContainer c, int64_t stream);
|
||||
|
||||
/**
|
||||
* \param n1 node 1
|
||||
* \param n2 node 2
|
||||
* \return the distance (squared), in meters, between two nodes
|
||||
*/
|
||||
static double GetDistanceSquaredBetween (Ptr<Node> n1, Ptr<Node> n2);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
||||
1515
src/wave/examples/low99-ct-unterstrass-1day.filt.7.adj.mob
Normal file
1515
src/wave/examples/low99-ct-unterstrass-1day.filt.7.adj.mob
Normal file
File diff suppressed because it is too large
Load Diff
2450
src/wave/examples/vanet-routing-compare.cc
Normal file
2450
src/wave/examples/vanet-routing-compare.cc
Normal file
File diff suppressed because it is too large
Load Diff
164
src/wave/helper/wave-bsm-helper.cc
Normal file
164
src/wave/helper/wave-bsm-helper.cc
Normal file
@@ -0,0 +1,164 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 North Carolina State University
|
||||
*
|
||||
* 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: Scott E. Carpenter <scarpen@ncsu.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ns3/wave-bsm-helper.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("WaveBsmHelper");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
std::vector<int> WaveBsmHelper::nodesMoving;
|
||||
|
||||
WaveBsmHelper::WaveBsmHelper ()
|
||||
: m_waveBsmStats ()
|
||||
{
|
||||
m_txSafetyRangesSq.resize (10, 0);
|
||||
m_txSafetyRangesSq[0] = 50.0 * 50.0;
|
||||
m_txSafetyRangesSq[1] = 100.0 * 100.0;
|
||||
m_txSafetyRangesSq[2] = 200.0 * 200.0;
|
||||
m_txSafetyRangesSq[3] = 300.0 * 300.0;
|
||||
m_txSafetyRangesSq[4] = 400.0 * 400.0;
|
||||
m_txSafetyRangesSq[5] = 500.0 * 500.0;
|
||||
m_txSafetyRangesSq[6] = 600.0 * 600.0;
|
||||
m_txSafetyRangesSq[7] = 800.0 * 800.0;
|
||||
m_txSafetyRangesSq[8] = 1000.0 * 1000.0;
|
||||
m_txSafetyRangesSq[9] = 1500.0 * 1500.0;
|
||||
|
||||
m_factory.SetTypeId ("ns3::BsmApplication");
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmHelper::SetAttribute (std::string name, const AttributeValue &value)
|
||||
{
|
||||
m_factory.Set (name, value);
|
||||
}
|
||||
|
||||
ApplicationContainer
|
||||
WaveBsmHelper::Install (Ptr<Node> node) const
|
||||
{
|
||||
return ApplicationContainer (InstallPriv (node));
|
||||
}
|
||||
|
||||
ApplicationContainer
|
||||
WaveBsmHelper::Install (Ipv4InterfaceContainer i) const
|
||||
{
|
||||
ApplicationContainer apps;
|
||||
for (Ipv4InterfaceContainer::Iterator itr = i.Begin (); itr != i.End (); ++itr)
|
||||
{
|
||||
std::pair<Ptr<Ipv4>, uint32_t> interface = (*itr);
|
||||
Ptr<Ipv4> pp = interface.first;
|
||||
Ptr<Node> node = pp->GetObject<Node> ();
|
||||
apps.Add (InstallPriv (node));
|
||||
}
|
||||
|
||||
return apps;
|
||||
}
|
||||
|
||||
Ptr<Application>
|
||||
WaveBsmHelper::InstallPriv (Ptr<Node> node) const
|
||||
{
|
||||
Ptr<Application> app = m_factory.Create<Application> ();
|
||||
node->AddApplication (app);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmHelper::Install (Ipv4InterfaceContainer & i,
|
||||
Time totalTime, // seconds
|
||||
uint32_t wavePacketSize, // bytes
|
||||
Time waveInterval, // seconds
|
||||
double gpsAccuracyNs, // clock drift range in number of ns
|
||||
std::vector <double> ranges, // m
|
||||
int chAccessMode, // channel access mode
|
||||
Time txMaxDelay) // max delay prior to transmit
|
||||
{
|
||||
int size = ranges.size ();
|
||||
m_txSafetyRangesSq.clear ();
|
||||
m_txSafetyRangesSq.resize (size, 0);
|
||||
for (int index = 0; index < size; index++)
|
||||
{
|
||||
// stored as square of value, for optimization
|
||||
m_txSafetyRangesSq[index] = ranges[index] * ranges[index];
|
||||
}
|
||||
|
||||
// install a BsmApplication on each node
|
||||
ApplicationContainer bsmApps = Install (i);
|
||||
// start BSM app immediately (BsmApplication will
|
||||
// delay transmission of first BSM by 1.0 seconds)
|
||||
bsmApps.Start (Seconds (0));
|
||||
bsmApps.Stop (totalTime);
|
||||
|
||||
// for each app, setup the app parameters
|
||||
ApplicationContainer::Iterator aci;
|
||||
int nodeId = 0;
|
||||
for (aci = bsmApps.Begin (); aci != bsmApps.End (); ++aci)
|
||||
{
|
||||
Ptr<BsmApplication> bsmApp = DynamicCast<BsmApplication> (*aci);
|
||||
bsmApp->Setup (i,
|
||||
nodeId,
|
||||
totalTime,
|
||||
wavePacketSize,
|
||||
waveInterval,
|
||||
gpsAccuracyNs,
|
||||
m_txSafetyRangesSq,
|
||||
GetWaveBsmStats (),
|
||||
&nodesMoving,
|
||||
chAccessMode,
|
||||
txMaxDelay);
|
||||
nodeId++;
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<WaveBsmStats>
|
||||
WaveBsmHelper::GetWaveBsmStats ()
|
||||
{
|
||||
return &m_waveBsmStats;
|
||||
}
|
||||
|
||||
int64_t
|
||||
WaveBsmHelper::AssignStreams (NodeContainer c, int64_t stream)
|
||||
{
|
||||
int64_t currentStream = stream;
|
||||
Ptr<Node> node;
|
||||
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
|
||||
{
|
||||
node = (*i);
|
||||
for (uint32_t j = 0; j < node->GetNApplications (); j++)
|
||||
{
|
||||
Ptr<BsmApplication> bsmApp = DynamicCast<BsmApplication> (node->GetApplication (j));
|
||||
if (bsmApp)
|
||||
{
|
||||
currentStream += bsmApp->AssignStreams (currentStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (currentStream - stream);
|
||||
}
|
||||
|
||||
std::vector<int>&
|
||||
WaveBsmHelper::GetNodesMoving ()
|
||||
{
|
||||
return nodesMoving;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
147
src/wave/helper/wave-bsm-helper.h
Normal file
147
src/wave/helper/wave-bsm-helper.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 North Carolina State University
|
||||
*
|
||||
* 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: Scott E. Carpenter <scarpen@ncsu.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WAVE_BSM_HELPER_H
|
||||
#define WAVE_BSM_HELPER_H
|
||||
|
||||
#include <vector>
|
||||
#include "ns3/wave-bsm-stats.h"
|
||||
#include "ns3/bsm-application.h"
|
||||
#include "ns3/object-factory.h"
|
||||
#include "ns3/application-container.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/internet-stack-helper.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
|
||||
namespace ns3 {
|
||||
/**
|
||||
* \ingroup wave
|
||||
* \brief The WaveBsmHelper class manages
|
||||
* IEEE 1609 WAVE (Wireless Access in Vehicular Environments)
|
||||
* Basic Safety Messages (BSMs) and uses the WaveBsmStats class
|
||||
* to manage statistics about BSMs transmitted and received
|
||||
* The BSM is a ~200-byte packet that is
|
||||
* generally broadcast from every vehicle at a nominal rate of 10 Hz.
|
||||
*/
|
||||
class WaveBsmHelper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Constructor
|
||||
* \return none
|
||||
*/
|
||||
WaveBsmHelper ();
|
||||
|
||||
/**
|
||||
* Helper function used to set the underlying application attributes.
|
||||
*
|
||||
* \param name the name of the application attribute to set
|
||||
* \param value the value of the application attribute to set
|
||||
*/
|
||||
void SetAttribute (std::string name, const AttributeValue &value);
|
||||
|
||||
/**
|
||||
* Install an ns3::BsmApplication on each node of the input container
|
||||
* configured with all the attributes set with SetAttribute.
|
||||
*
|
||||
* \param i Ipv4InterfaceContainer of the set of interfaces on which an BsmApplication
|
||||
* will be installed on the nodes.
|
||||
* \returns Container of Ptr to the applications installed.
|
||||
*/
|
||||
ApplicationContainer Install (Ipv4InterfaceContainer i) const;
|
||||
|
||||
/**
|
||||
* Install an ns3::BsmApplication on the node configured with all the
|
||||
* attributes set with SetAttribute.
|
||||
*
|
||||
* \param node The node on which an BsmApplication will be installed.
|
||||
* \returns Container of Ptr to the applications installed.
|
||||
*/
|
||||
ApplicationContainer Install (Ptr<Node> node) const;
|
||||
|
||||
/**
|
||||
* \brief Installs BSM generation on devices for nodes
|
||||
* and their interfaces
|
||||
* \param i IPv4 interface container
|
||||
* \param totalTime total amount of time that BSM packets should be transmitted
|
||||
* \param wavePacketSize the size, in bytes, of a WAVE BSM
|
||||
* \param waveInterval the time, in seconds, between each WAVE BSM transmission,
|
||||
* typically 10 Hz (0.1 second)
|
||||
* \param gpsAccuracy the timing synchronization accuracy of GPS time, in seconds.
|
||||
* GPS time-sync is ~40-100 ns. Universally synchronized time among all vehicles
|
||||
* will result in all vehicles transmitting safety messages simultaneously, leading
|
||||
* to excessive wireless collisions.
|
||||
* \param range the expected transmission range, in m.
|
||||
* \return none
|
||||
*/
|
||||
void Install (Ipv4InterfaceContainer & i,
|
||||
Time totalTime, // seconds
|
||||
uint32_t wavePacketSize, // bytes
|
||||
Time waveInterval, // seconds
|
||||
double gpsAccuracyNs, // clock drift range in number of ns
|
||||
std::vector <double> ranges, // m
|
||||
int chAccessMode, // channel access mode (0=continuous; 1=switching)
|
||||
Time txMaxDelay); // max delay prior to transmit
|
||||
|
||||
/**
|
||||
* \brief Returns the WaveBsmStats instance
|
||||
* \return the WaveBsmStats instance
|
||||
*/
|
||||
Ptr<WaveBsmStats> GetWaveBsmStats ();
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
* have been assigned. The Install() method should have previously been
|
||||
* called by the user.
|
||||
*
|
||||
* \param stream first stream index to use
|
||||
* \param c NodeContainer of the set of nodes for which the BsmApplication
|
||||
* should be modified to use a fixed stream
|
||||
* \return the number of stream indices assigned by this helper
|
||||
*/
|
||||
int64_t AssignStreams (NodeContainer c, int64_t stream);
|
||||
|
||||
/**
|
||||
* \brief Returns the list of moving nove indicators
|
||||
* \return the list of moving node indicators
|
||||
*/
|
||||
static std::vector<int>& GetNodesMoving ();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Install an ns3::BsmApplication on the node
|
||||
*
|
||||
* \param node The node on which an BsmApplication will be installed.
|
||||
* \returns Ptr to the application installed.
|
||||
*/
|
||||
Ptr<Application> InstallPriv (Ptr<Node> node) const;
|
||||
|
||||
ObjectFactory m_factory; //!< Object factory.
|
||||
WaveBsmStats m_waveBsmStats;
|
||||
// tx safety range squared, for optimization
|
||||
std::vector <double> m_txSafetyRangesSq;
|
||||
static std::vector<int> nodesMoving;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* WAVE_BSM_HELPER_H*/
|
||||
190
src/wave/helper/wave-bsm-stats.cc
Normal file
190
src/wave/helper/wave-bsm-stats.cc
Normal file
@@ -0,0 +1,190 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 North Carolina State University
|
||||
*
|
||||
* 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: Scott E. Carpenter <scarpen@ncsu.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/wave-bsm-stats.h"
|
||||
#include "ns3/integer.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("WaveBsmStats");
|
||||
|
||||
WaveBsmStats::WaveBsmStats ()
|
||||
: m_wavePktSendCount (0),
|
||||
m_waveByteSendCount (0),
|
||||
m_wavePktReceiveCount (0),
|
||||
m_log (0)
|
||||
{
|
||||
m_wavePktExpectedReceiveCounts.resize (10, 0);
|
||||
m_wavePktInCoverageReceiveCounts.resize (10, 0);
|
||||
m_waveTotalPktExpectedReceiveCounts.resize (10, 0);
|
||||
m_waveTotalPktInCoverageReceiveCounts.resize (10, 0);
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::IncTxPktCount ()
|
||||
{
|
||||
m_wavePktSendCount++;
|
||||
}
|
||||
|
||||
int
|
||||
WaveBsmStats::GetTxPktCount ()
|
||||
{
|
||||
return m_wavePktSendCount;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::IncExpectedRxPktCount (int index)
|
||||
{
|
||||
m_wavePktExpectedReceiveCounts[index - 1]++;
|
||||
m_waveTotalPktExpectedReceiveCounts[index - 1]++;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::IncRxPktCount ()
|
||||
{
|
||||
m_wavePktReceiveCount++;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::IncRxPktInRangeCount (int index)
|
||||
{
|
||||
m_wavePktInCoverageReceiveCounts[index - 1]++;
|
||||
m_waveTotalPktInCoverageReceiveCounts[index - 1]++;
|
||||
}
|
||||
|
||||
int
|
||||
WaveBsmStats::GetRxPktCount ()
|
||||
{
|
||||
return m_wavePktReceiveCount;
|
||||
}
|
||||
|
||||
int
|
||||
WaveBsmStats::GetExpectedRxPktCount (int index)
|
||||
{
|
||||
return m_wavePktExpectedReceiveCounts[index - 1];
|
||||
}
|
||||
|
||||
int
|
||||
WaveBsmStats::GetRxPktInRangeCount (int index)
|
||||
{
|
||||
return m_wavePktInCoverageReceiveCounts[index - 1];
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::SetTxPktCount (int count)
|
||||
{
|
||||
m_wavePktSendCount = count;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::SetRxPktCount (int count)
|
||||
{
|
||||
m_wavePktReceiveCount = count;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::IncTxByteCount (int bytes)
|
||||
{
|
||||
m_waveByteSendCount += bytes;
|
||||
}
|
||||
|
||||
int
|
||||
WaveBsmStats::GetTxByteCount ()
|
||||
{
|
||||
return m_waveByteSendCount;
|
||||
}
|
||||
|
||||
double
|
||||
WaveBsmStats::GetBsmPdr (int index)
|
||||
{
|
||||
double pdr = 0.0;
|
||||
|
||||
if (m_wavePktExpectedReceiveCounts[index - 1] > 0)
|
||||
{
|
||||
pdr = (double) m_wavePktInCoverageReceiveCounts[index - 1] / (double) m_wavePktExpectedReceiveCounts[index - 1];
|
||||
// due to node movement, it is
|
||||
// possible to receive a packet that is not slightly "within range" that was
|
||||
// transmitted at the time when the nodes were slightly "out of range"
|
||||
// thus, prevent overflow of PDR > 100%
|
||||
if (pdr > 1.0)
|
||||
{
|
||||
pdr = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return pdr;
|
||||
}
|
||||
|
||||
double
|
||||
WaveBsmStats::GetCumulativeBsmPdr (int index)
|
||||
{
|
||||
double pdr = 0.0;
|
||||
|
||||
if (m_waveTotalPktExpectedReceiveCounts[index - 1] > 0)
|
||||
{
|
||||
pdr = (double) m_waveTotalPktInCoverageReceiveCounts[index - 1] / (double) m_waveTotalPktExpectedReceiveCounts[index - 1];
|
||||
// due to node movement, it is
|
||||
// possible to receive a packet that is not slightly "within range" that was
|
||||
// transmitted at the time when the nodes were slightly "out of range"
|
||||
// thus, prevent overflow of PDR > 100%
|
||||
if (pdr > 1.0)
|
||||
{
|
||||
pdr = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return pdr;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::SetLogging (int log)
|
||||
{
|
||||
m_log = log;
|
||||
}
|
||||
|
||||
int
|
||||
WaveBsmStats::GetLogging ()
|
||||
{
|
||||
return m_log;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::SetExpectedRxPktCount (int index, int count)
|
||||
{
|
||||
m_wavePktExpectedReceiveCounts[index - 1] = count;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::SetRxPktInRangeCount (int index, int count)
|
||||
{
|
||||
m_wavePktInCoverageReceiveCounts[index - 1] = count;
|
||||
}
|
||||
|
||||
void
|
||||
WaveBsmStats::ResetTotalRxPktCounts (int index)
|
||||
{
|
||||
m_waveTotalPktInCoverageReceiveCounts[index - 1] = 0;
|
||||
m_waveTotalPktExpectedReceiveCounts[index - 1] = 0;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
235
src/wave/helper/wave-bsm-stats.h
Normal file
235
src/wave/helper/wave-bsm-stats.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 North Carolina State University
|
||||
*
|
||||
* 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: Scott E. Carpenter <scarpen@ncsu.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WAVE_BSM_STATS_H
|
||||
#define WAVE_BSM_STATS_H
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
class WaveBsmStats : public Object
|
||||
/**
|
||||
* \ingroup wave
|
||||
* \brief The WaveBsmStats class implements a stats collector for
|
||||
* IEEE 1609 WAVE (Wireless Access in Vehicular Environments)
|
||||
* Basic Safety Messages (BSMs). The BSM is a ~200-byte packet that is
|
||||
* generally broadcast from every vehicle at a nominal rate of 10 Hz.
|
||||
*/
|
||||
/*
|
||||
* Note: This class collects data elements and accessors
|
||||
* along with methods that calculate metrics from the data
|
||||
* elements. The data and metrics calculation algorithms
|
||||
* are collected together here purely to keep them together.
|
||||
* Future work may need to add additional metric calculations,
|
||||
* and for now, we are trying to keep all related data and
|
||||
* algorithms together, although these could easily be
|
||||
* refactored in the future and moved to separate classes.
|
||||
* However, it seems that for now, moving the data elements
|
||||
* or the algorithms separately into different classes could
|
||||
* lead to confusion over usage.
|
||||
*/
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Constructor
|
||||
* \return none
|
||||
*/
|
||||
WaveBsmStats ();
|
||||
|
||||
/**
|
||||
* \brief Increments the count of transmitted packets
|
||||
* \return none
|
||||
*/
|
||||
void IncTxPktCount ();
|
||||
|
||||
/**
|
||||
* \brief Returns the count of transmitted packets
|
||||
* \return count of packets transmitted
|
||||
*/
|
||||
int GetTxPktCount ();
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* The WAVE Basic Safety Message (BSM) is broadcast and
|
||||
* unacknowledged. In order to calculate packet delivery
|
||||
* ratio (PDR), we must count i) the packets that are
|
||||
* actually received and ii) the transmitted packets that
|
||||
* are expected to be received. Both are relative to a
|
||||
* specified (circular) coverage area.
|
||||
*
|
||||
* For example: Say we have three nodes, A, B, and C, each
|
||||
* separated by 40m, as follows:
|
||||
*
|
||||
* A --<40m>-- B --<40m>-- C
|
||||
*
|
||||
* Let's assume that the transmission range is 50m, and only
|
||||
* A is transmitting (i.e. broadcasting). B can receive A's
|
||||
* broadcasts, while C cannot. Let's assume no dropped packets.
|
||||
* If we set the coverage area to 100m, then the PDR is 50%,
|
||||
* because B receives every transmission from A, while C receives
|
||||
* none of them. However, if we change the effective
|
||||
* coverage area to 75m then the PDR improves to 100%, because
|
||||
* B receives 100% of A's transmissions, and C is outside of the
|
||||
* coverage area, and so does not factor in to the PDR.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Increments the count of (broadcast) packets expected
|
||||
* to be received within the coverage area1. Broadcast packets
|
||||
* (i.e. WAVE Basic Safety Messages) are not ACK'd. For packet
|
||||
* delivery ratio (PDR), we need to count transmitted packets that
|
||||
* are expected to be received within the coverage area, even
|
||||
* though they may not be physically received (due to collisions
|
||||
* or receiver power thresholds).
|
||||
* \return none
|
||||
*/
|
||||
void IncExpectedRxPktCount (int index);
|
||||
|
||||
/**
|
||||
* \brief Increments the count of actual packets received
|
||||
* (regardless of coverage area).
|
||||
* \return none
|
||||
*/
|
||||
void IncRxPktCount ();
|
||||
|
||||
/**
|
||||
* \brief Increments the count of actual packets received within
|
||||
* the coverage area(index). Broadcast packets
|
||||
* (i.e. WAVE Basic Safety Messages) are not ACK'd. For packet
|
||||
* delivery ratio (PDR), we need to count only those received packets
|
||||
* that are actually received within the (circular) coverage area.
|
||||
* \return none
|
||||
*/
|
||||
void IncRxPktInRangeCount (int index);
|
||||
|
||||
/**
|
||||
* \brief Returns the count of packets received
|
||||
* \return the count of packets received
|
||||
*/
|
||||
int GetRxPktCount ();
|
||||
|
||||
/**
|
||||
* \brief Returns the count of expected packets received within range(index)
|
||||
* \return the count of expected packets received within range(index)
|
||||
*/
|
||||
int GetExpectedRxPktCount (int index);
|
||||
|
||||
/**
|
||||
* \brief Increments the count of actual packets recevied within range(index)
|
||||
* \return the count of actual packets received within range(index)
|
||||
*/
|
||||
int GetRxPktInRangeCount (int index);
|
||||
|
||||
/**
|
||||
* \brief Sets the count of packets expected to received
|
||||
* \param range index
|
||||
* \param count the count of packets
|
||||
* \return none
|
||||
*/
|
||||
void SetExpectedRxPktCount (int index, int count);
|
||||
|
||||
/**
|
||||
* \brief Sets the count of packets within range that are received
|
||||
* \param range index
|
||||
* \param count the count of packets
|
||||
* \return none
|
||||
*/
|
||||
void SetRxPktInRangeCount (int index, int count);
|
||||
|
||||
/**
|
||||
* \brief Resets the count of total packets
|
||||
* expected and/or within range(index) that are received
|
||||
* \return none
|
||||
*/
|
||||
void ResetTotalRxPktCounts (int index);
|
||||
|
||||
/**
|
||||
* \brief Sets the count of packets transmitted
|
||||
* \param count the count of packets transmitted
|
||||
* \return none
|
||||
*/
|
||||
void SetTxPktCount (int count);
|
||||
|
||||
/**
|
||||
* \brief Sets the count of packets received
|
||||
* \param count the count of packets received
|
||||
* \return none
|
||||
*/
|
||||
void SetRxPktCount (int count);
|
||||
|
||||
/**
|
||||
* \brief Increments the count of (application data) bytes transmitted
|
||||
* not including MAC/PHY overhead
|
||||
* \param bytes the bytes of application-data transmitted
|
||||
* \return none
|
||||
*/
|
||||
void IncTxByteCount (int bytes);
|
||||
|
||||
/**
|
||||
* \brief Returns the count of (application data) bytes transmitted
|
||||
* not include MAC/PHY overhead
|
||||
* \return number of bytes of application-data transmitted
|
||||
*/
|
||||
int GetTxByteCount ();
|
||||
|
||||
/**
|
||||
* \brief Returns the BSM Packet Delivery Ratio (PDR)
|
||||
* which is the percent of expected packets within range(index) that
|
||||
* are actually received
|
||||
* \return the packet delivery ratio (PDR) of BSMs.
|
||||
*/
|
||||
double GetBsmPdr (int index);
|
||||
|
||||
/**
|
||||
* \brief Returns the cumulative BSM Packet Delivery Ratio (PDR)
|
||||
* which is the percent of cumulative expected packets within range(index)
|
||||
* that are actually received
|
||||
* \return the packet delivery ratio (PDR) of BSMs.
|
||||
*/
|
||||
double GetCumulativeBsmPdr (int index);
|
||||
|
||||
/**
|
||||
* \brief Enables/disables logging
|
||||
* \return none
|
||||
*/
|
||||
void SetLogging (int log);
|
||||
|
||||
/**
|
||||
* \brief Gets logging state
|
||||
* \return logging state
|
||||
*/
|
||||
int GetLogging ();
|
||||
|
||||
private:
|
||||
int m_wavePktSendCount;
|
||||
int m_waveByteSendCount;
|
||||
int m_wavePktReceiveCount;
|
||||
std::vector <int> m_wavePktInCoverageReceiveCounts;
|
||||
std::vector <int> m_wavePktExpectedReceiveCounts;
|
||||
std::vector <int> m_waveTotalPktInCoverageReceiveCounts;
|
||||
std::vector <int> m_waveTotalPktExpectedReceiveCounts;
|
||||
int m_log;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* WAVE_BSM_STATS_H*/
|
||||
413
src/wave/model/bsm-application.cc
Normal file
413
src/wave/model/bsm-application.cc
Normal file
@@ -0,0 +1,413 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 North Carolina State University
|
||||
*
|
||||
* 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: Scott E. Carpenter <scarpen@ncsu.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ns3/bsm-application.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/seq-ts-header.h"
|
||||
#include "ns3/wave-net-device.h"
|
||||
#include "ns3/wave-mac-helper.h"
|
||||
#include "ns3/wave-helper.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
#include "ns3/mobility-helper.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("BsmApplication");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
// (Arbitrary) port for establishing socket to transmit WAVE BSMs
|
||||
int BsmApplication::wavePort = 9080;
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (BsmApplication);
|
||||
|
||||
TypeId
|
||||
BsmApplication::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::BsmApplication")
|
||||
.SetParent<Application> ()
|
||||
.AddConstructor<BsmApplication> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
BsmApplication::BsmApplication ()
|
||||
: m_waveBsmStats (0),
|
||||
m_txSafetyRangesSq (),
|
||||
m_TotalSimTime (Seconds (10)),
|
||||
m_wavePacketSize (200),
|
||||
m_numWavePackets (1),
|
||||
m_waveInterval (MilliSeconds (100)),
|
||||
m_gpsAccuracyNs (10000),
|
||||
m_adhocTxInterfaces (0),
|
||||
m_nodesMoving (0),
|
||||
m_unirv (0),
|
||||
m_nodeId (0),
|
||||
m_chAccessMode (0),
|
||||
m_txMaxDelay (MilliSeconds (10)),
|
||||
m_prevTxDelay (MilliSeconds (0))
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
BsmApplication::~BsmApplication ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
void
|
||||
BsmApplication::DoDispose (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
// chain up
|
||||
Application::DoDispose ();
|
||||
}
|
||||
|
||||
// Application Methods
|
||||
void BsmApplication::StartApplication () // Called at time specified by Start
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
// setup generation of WAVE BSM messages
|
||||
Time waveInterPacketInterval = m_waveInterval;
|
||||
|
||||
// BSMs are not transmitted for the first second
|
||||
Time startTime = Seconds (1.0);
|
||||
// total length of time transmitting WAVE packets
|
||||
Time totalTxTime = m_TotalSimTime - startTime;
|
||||
// total WAVE packets needing to be sent
|
||||
m_numWavePackets = (uint32_t) (totalTxTime.GetDouble () / m_waveInterval.GetDouble ());
|
||||
|
||||
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
|
||||
|
||||
// every node broadcasts WAVE BSM to potentially all other nodes
|
||||
Ptr<Socket> recvSink = Socket::CreateSocket (GetNode (m_nodeId), tid);
|
||||
recvSink->SetRecvCallback (MakeCallback (&BsmApplication::ReceiveWavePacket, this));
|
||||
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), wavePort);
|
||||
recvSink->Bind (local);
|
||||
recvSink->BindToNetDevice (GetNetDevice (m_nodeId));
|
||||
recvSink->SetAllowBroadcast (true);
|
||||
|
||||
// dest is broadcast address
|
||||
InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), wavePort);
|
||||
recvSink->Connect (remote);
|
||||
|
||||
// Transmission start time for each BSM:
|
||||
// We assume that the start transmission time
|
||||
// for the first packet will be on a ns-3 time
|
||||
// "Second" boundary - e.g., 1.0 s.
|
||||
// However, the actual transmit time must reflect
|
||||
// additional effects of 1) clock drift and
|
||||
// 2) transmit delay requirements.
|
||||
// 1) Clock drift - clocks are not perfectly
|
||||
// synchronized across all nodes. In a VANET
|
||||
// we assume all nodes sync to GPS time, which
|
||||
// itself is assumed accurate to, say, 40-100 ns.
|
||||
// Thus, the start transmission time must be adjusted
|
||||
// by some value, t_drift.
|
||||
// 2) Transmit delay requirements - The US
|
||||
// minimum performance requirements for V2V
|
||||
// BSM transmission expect a random delay of
|
||||
// +/- 5 ms, to avoid simultanous transmissions
|
||||
// by all vehicles congesting the channel. Thus,
|
||||
// we need to adjust the start trasmission time by
|
||||
// some value, t_tx_delay.
|
||||
// Therefore, the actual transmit time should be:
|
||||
// t_start = t_time + t_drift + t_tx_delay
|
||||
// t_drift is always added to t_time.
|
||||
// t_tx_delay is supposed to be +/- 5ms, but if we
|
||||
// allow negative numbers the time could drift to a value
|
||||
// BEFORE the interval start time (i.e., at 100 ms
|
||||
// boundaries, we do not want to drift into the
|
||||
// previous interval, such as at 95 ms. Instead,
|
||||
// we always want to be at the 100 ms interval boundary,
|
||||
// plus [0..10] ms tx delay.
|
||||
// Thus, the average t_tx_delay will be
|
||||
// within the desired range of [0..10] ms of
|
||||
// (t_time + t_drift)
|
||||
|
||||
// WAVE devices sync to GPS time
|
||||
// and all devices would like to begin broadcasting
|
||||
// their safety messages immediately at the start of
|
||||
// the CCH interval. However, if all do so, then
|
||||
// significant collisions occur. Thus, we assume there
|
||||
// is some GPS sync accuracy on GPS devices,
|
||||
// typically 40-100 ns.
|
||||
// Get a uniformly random number for GPS sync accuracy, in ns.
|
||||
Time tDrift = NanoSeconds (m_unirv->GetInteger (0, m_gpsAccuracyNs));
|
||||
|
||||
// When transmitting at a default rate of 10 Hz,
|
||||
// the subsystem shall transmit every 100 ms +/-
|
||||
// a random value between 0 and 5 ms. [MPR-BSMTX-TXTIM-002]
|
||||
// Source: CAMP Vehicle Safety Communications 4 Consortium
|
||||
// On-board Minimum Performance Requirements
|
||||
// for V2V Safety Systems Version 1.0, December 17, 2014
|
||||
// max transmit delay (default 10ms)
|
||||
// get value for transmit delay, as number of ns
|
||||
uint32_t d_ns = static_cast<uint32_t> (m_txMaxDelay.GetInteger ());
|
||||
// convert random tx delay to ns-3 time
|
||||
// see note above regarding centering tx delay
|
||||
// offset by 5ms + a random value.
|
||||
Time txDelay = NanoSeconds (m_unirv->GetInteger (0, d_ns));
|
||||
m_prevTxDelay = txDelay;
|
||||
|
||||
Time txTime = startTime + tDrift + txDelay;
|
||||
// schedule transmission of first packet
|
||||
Simulator::ScheduleWithContext (recvSink->GetNode ()->GetId (),
|
||||
txTime, &BsmApplication::GenerateWaveTraffic, this,
|
||||
recvSink, m_wavePacketSize, m_numWavePackets, waveInterPacketInterval, m_nodeId);
|
||||
}
|
||||
|
||||
void BsmApplication::StopApplication () // Called at time specified by Stop
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
void
|
||||
BsmApplication::Setup (Ipv4InterfaceContainer & i,
|
||||
int nodeId,
|
||||
Time totalTime,
|
||||
uint32_t wavePacketSize, // bytes
|
||||
Time waveInterval,
|
||||
double gpsAccuracyNs,
|
||||
std::vector <double> rangesSq, // m ^2
|
||||
Ptr<WaveBsmStats> waveBsmStats,
|
||||
std::vector<int> * nodesMoving,
|
||||
int chAccessMode,
|
||||
Time txMaxDelay)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
m_unirv = CreateObject<UniformRandomVariable> ();
|
||||
|
||||
m_TotalSimTime = totalTime;
|
||||
m_wavePacketSize = wavePacketSize;
|
||||
m_waveInterval = waveInterval;
|
||||
m_gpsAccuracyNs = gpsAccuracyNs;
|
||||
int size = rangesSq.size ();
|
||||
m_waveBsmStats = waveBsmStats;
|
||||
m_nodesMoving = nodesMoving;
|
||||
m_chAccessMode = chAccessMode;
|
||||
m_txSafetyRangesSq.clear ();
|
||||
m_txSafetyRangesSq.resize (size, 0);
|
||||
|
||||
for (int index = 0; index < size; index++)
|
||||
{
|
||||
// stored as square of value, for optimization
|
||||
m_txSafetyRangesSq[index] = rangesSq[index];
|
||||
}
|
||||
|
||||
m_adhocTxInterfaces = &i;
|
||||
m_nodeId = nodeId;
|
||||
m_txMaxDelay = txMaxDelay;
|
||||
}
|
||||
|
||||
void
|
||||
BsmApplication::GenerateWaveTraffic (Ptr<Socket> socket, uint32_t pktSize,
|
||||
uint32_t pktCount, Time pktInterval,
|
||||
uint32_t sendingNodeId)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
// more packets to send?
|
||||
if (pktCount > 0)
|
||||
{
|
||||
// for now, we cannot tell if each node has
|
||||
// started mobility. so, as an optimization
|
||||
// only send if this node is moving
|
||||
// if not, then skip
|
||||
int txNodeId = sendingNodeId;
|
||||
Ptr<Node> txNode = GetNode (txNodeId);
|
||||
Ptr<MobilityModel> txPosition = txNode->GetObject<MobilityModel> ();
|
||||
NS_ASSERT (txPosition != 0);
|
||||
|
||||
int senderMoving = m_nodesMoving->at (txNodeId);
|
||||
if (senderMoving != 0)
|
||||
{
|
||||
// send it!
|
||||
socket->Send (Create<Packet> (pktSize));
|
||||
// count it
|
||||
m_waveBsmStats->IncTxPktCount ();
|
||||
m_waveBsmStats->IncTxByteCount (pktSize);
|
||||
int wavePktsSent = m_waveBsmStats->GetTxPktCount ();
|
||||
if ((m_waveBsmStats->GetLogging () != 0) && ((wavePktsSent % 1000) == 0))
|
||||
{
|
||||
NS_LOG_UNCOND ("Sending WAVE pkt # " << wavePktsSent );
|
||||
}
|
||||
|
||||
// find other nodes within range that would be
|
||||
// expected to receive this broadbast
|
||||
int nRxNodes = m_adhocTxInterfaces->GetN ();
|
||||
for (int i = 0; i < nRxNodes; i++)
|
||||
{
|
||||
Ptr<Node> rxNode = GetNode (i);
|
||||
int rxNodeId = rxNode->GetId ();
|
||||
|
||||
if (rxNodeId != txNodeId)
|
||||
{
|
||||
Ptr<MobilityModel> rxPosition = rxNode->GetObject<MobilityModel> ();
|
||||
NS_ASSERT (rxPosition != 0);
|
||||
// confirm that the receiving node
|
||||
// has also started moving in the scenario
|
||||
// if it has not started moving, then
|
||||
// it is not a candidate to receive a packet
|
||||
int receiverMoving = m_nodesMoving->at (rxNodeId);
|
||||
if (receiverMoving == 1)
|
||||
{
|
||||
double distSq = MobilityHelper::GetDistanceSquaredBetween (txNode, rxNode);
|
||||
if (distSq > 0.0)
|
||||
{
|
||||
// dest node within range?
|
||||
int rangeCount = m_txSafetyRangesSq.size ();
|
||||
for (int index = 1; index <= rangeCount; index++)
|
||||
{
|
||||
if (distSq <= m_txSafetyRangesSq[index - 1])
|
||||
{
|
||||
// we should expect dest node to receive broadcast pkt
|
||||
m_waveBsmStats->IncExpectedRxPktCount (index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// every BSM must be scheduled with a tx time delay
|
||||
// of +/- (5) ms. See comments in StartApplication().
|
||||
// we handle this as a tx delay of [0..10] ms
|
||||
// from the start of the pktInterval boundary
|
||||
uint32_t d_ns = static_cast<uint32_t> (m_txMaxDelay.GetInteger ());
|
||||
Time txDelay = NanoSeconds (m_unirv->GetInteger (0, d_ns));
|
||||
|
||||
// do not want the tx delay to be cumulative, so
|
||||
// deduct the previous delay value. thus we adjust
|
||||
// to schedule the next event at the next pktInterval,
|
||||
// plus some new [0..10] ms tx delay
|
||||
Time txTime = pktInterval - m_prevTxDelay + txDelay;
|
||||
m_prevTxDelay = txDelay;
|
||||
|
||||
Simulator::ScheduleWithContext (socket->GetNode ()->GetId (),
|
||||
txTime, &BsmApplication::GenerateWaveTraffic, this,
|
||||
socket, pktSize, pktCount - 1, pktInterval, socket->GetNode ()->GetId ());
|
||||
}
|
||||
else
|
||||
{
|
||||
socket->Close ();
|
||||
}
|
||||
}
|
||||
|
||||
void BsmApplication::ReceiveWavePacket (Ptr<Socket> socket)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
Ptr<Packet> packet;
|
||||
while ((packet = socket->Recv ()))
|
||||
{
|
||||
Ptr<Node> rxNode = socket->GetNode ();
|
||||
|
||||
SocketAddressTag tag;
|
||||
bool found;
|
||||
found = packet->PeekPacketTag (tag);
|
||||
|
||||
if (found)
|
||||
{
|
||||
InetSocketAddress addr = InetSocketAddress::ConvertFrom (tag.GetAddress ());
|
||||
int nodes = m_adhocTxInterfaces->GetN ();
|
||||
for (int i = 0; i < nodes; i++)
|
||||
{
|
||||
if (addr.GetIpv4 () == m_adhocTxInterfaces->GetAddress (i) )
|
||||
{
|
||||
Ptr<Node> txNode = GetNode (i);
|
||||
HandleReceivedBsmPacket (txNode, rxNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BsmApplication::HandleReceivedBsmPacket (Ptr<Node> txNode,
|
||||
Ptr<Node> rxNode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
m_waveBsmStats->IncRxPktCount ();
|
||||
|
||||
Ptr<MobilityModel> rxPosition = rxNode->GetObject<MobilityModel> ();
|
||||
NS_ASSERT (rxPosition != 0);
|
||||
// confirm that the receiving node
|
||||
// has also started moving in the scenario
|
||||
// if it has not started moving, then
|
||||
// it is not a candidate to receive a packet
|
||||
int rxNodeId = rxNode->GetId ();
|
||||
int receiverMoving = m_nodesMoving->at (rxNodeId);
|
||||
if (receiverMoving == 1)
|
||||
{
|
||||
double rxDistSq = MobilityHelper::GetDistanceSquaredBetween (rxNode, txNode);
|
||||
if (rxDistSq > 0.0)
|
||||
{
|
||||
int rangeCount = m_txSafetyRangesSq.size ();
|
||||
for (int index = 1; index <= rangeCount; index++)
|
||||
{
|
||||
if (rxDistSq <= m_txSafetyRangesSq[index - 1])
|
||||
{
|
||||
m_waveBsmStats->IncRxPktInRangeCount (index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t
|
||||
BsmApplication::AssignStreams (int64_t streamIndex)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
NS_ASSERT (m_unirv); // should be set by Setup() prevoiusly
|
||||
m_unirv->SetStream (streamIndex);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Ptr<Node>
|
||||
BsmApplication::GetNode (int id)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
std::pair<Ptr<Ipv4>, uint32_t> interface = m_adhocTxInterfaces->Get (id);
|
||||
Ptr<Ipv4> pp = interface.first;
|
||||
Ptr<Node> node = pp->GetObject<Node> ();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
Ptr<NetDevice>
|
||||
BsmApplication::GetNetDevice (int id)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
std::pair<Ptr<Ipv4>, uint32_t> interface = m_adhocTxInterfaces->Get (id);
|
||||
Ptr<Ipv4> pp = interface.first;
|
||||
Ptr<NetDevice> device = pp->GetObject<NetDevice> ();
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
175
src/wave/model/bsm-application.h
Normal file
175
src/wave/model/bsm-application.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014 North Carolina State University
|
||||
*
|
||||
* 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: Scott E. Carpenter <scarpen@ncsu.edu>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BSM_APPLICATION_H
|
||||
#define BSM_APPLICATION_H
|
||||
|
||||
#include "ns3/application.h"
|
||||
#include "ns3/wave-bsm-stats.h"
|
||||
#include "ns3/random-variable-stream.h"
|
||||
#include "ns3/internet-stack-helper.h"
|
||||
|
||||
namespace ns3 {
|
||||
/**
|
||||
* \ingroup wave
|
||||
* \brief The BsmApplication class sends and receives the
|
||||
* IEEE 1609 WAVE (Wireless Access in Vehicular Environments)
|
||||
* Basic Safety Messages (BSMs) and uses the WaveBsmStats class
|
||||
* to manage statistics about BSMs transmitted and received
|
||||
* The BSM is a ~200-byte packet that is
|
||||
* generally broadcast from every vehicle at a nominal rate of 10 Hz.
|
||||
*/
|
||||
class BsmApplication : public Application
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
* \return none
|
||||
*/
|
||||
BsmApplication ();
|
||||
virtual ~BsmApplication ();
|
||||
|
||||
/**
|
||||
* \brief Setup BSM generation parameters for a node
|
||||
* \param i IPv4 interface container
|
||||
* \param nodeId identifier of the node (index into container)
|
||||
* \param totalTime total amount of time that BSM packets should be transmitted
|
||||
* \param wavePacketSize the size, in bytes, of a WAVE BSM
|
||||
* \param waveInterval the time, in seconds, between each WAVE BSM transmission,
|
||||
* typically 10 Hz (0.1 second)
|
||||
* \param gpsAccuracy the timing synchronization accuracy of GPS time, in seconds.
|
||||
* GPS time-sync is ~40-100 ns. Universally synchronized time among all vehicles
|
||||
* will result in all vehicles transmitting safety messages simultaneously, leading
|
||||
* to excessive wireless collisions.
|
||||
* \param range the expected transmission range, in m ^ 2.
|
||||
* \param collection class for WAVE BSM statistics
|
||||
* \param indicators of whether or not node(s) are moving
|
||||
* \return none
|
||||
*/
|
||||
void Setup (Ipv4InterfaceContainer & i,
|
||||
int nodeId,
|
||||
Time totalTime,
|
||||
uint32_t wavePacketSize, // bytes
|
||||
Time waveInterval,
|
||||
double gpsAccuracyNs,
|
||||
std::vector <double> rangesSq, // m ^ 2
|
||||
Ptr<WaveBsmStats> waveBsmStats,
|
||||
std::vector<int> * nodesMoving,
|
||||
int mode,
|
||||
Time txDelay);
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
* have been assigned. The Install() method should have previously been
|
||||
* called by the user.
|
||||
*
|
||||
* \param stream first stream index to use
|
||||
* \return the number of stream indices assigned by this helper
|
||||
*/
|
||||
int64_t AssignStreams (int64_t streamIndex);
|
||||
|
||||
/**
|
||||
* (Arbitrary) port number that is used to create a socket for transmitting WAVE BSMs.
|
||||
*/
|
||||
static int wavePort;
|
||||
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
|
||||
private:
|
||||
// inherited from Application base class.
|
||||
virtual void StartApplication (void); // Called at time specified by Start
|
||||
virtual void StopApplication (void); // Called at time specified by Stop
|
||||
|
||||
/**
|
||||
* \brief Creates and transmits a WAVE BSM packet
|
||||
* \param socket socket to use for transmission
|
||||
* \param pktSize the size, in bytes, of the WAVE BSM packet
|
||||
* \param pktCount the number of remaining WAVE BSM packets to be transmitted
|
||||
* \param pktInterval the interval, in seconds, until the next packet
|
||||
* should be transmitted
|
||||
* \return none
|
||||
*/
|
||||
void GenerateWaveTraffic (Ptr<Socket> socket, uint32_t pktSize,
|
||||
uint32_t pktCount, Time pktInterval,
|
||||
uint32_t sendingNodeId);
|
||||
|
||||
/**
|
||||
* \brief Receive a WAVE BSM packet
|
||||
* \param socket the receiving socket
|
||||
* \return none
|
||||
*/
|
||||
void ReceiveWavePacket (Ptr<Socket> socket);
|
||||
|
||||
/**
|
||||
* \brief Handle the receipt of a WAVE BSM packet from sender to receiver
|
||||
* \param txNode the sending node
|
||||
* \param rxNode the receiving node
|
||||
* \return none
|
||||
*/
|
||||
void HandleReceivedBsmPacket (Ptr<Node> txNode,
|
||||
Ptr<Node> rxNode);
|
||||
|
||||
/**
|
||||
* \brief Get the node for the desired id
|
||||
* \param id the id of the desired node
|
||||
* \return ptr to the desired node
|
||||
*/
|
||||
Ptr<Node> GetNode (int id);
|
||||
|
||||
/**
|
||||
* \brief Get the net device for the desired id
|
||||
* \param id the id of the desired net device
|
||||
* \return ptr to the desired net device
|
||||
*/
|
||||
Ptr<NetDevice> GetNetDevice (int id);
|
||||
|
||||
Ptr<WaveBsmStats> m_waveBsmStats;
|
||||
// tx safety range squared, for optimization
|
||||
std::vector <double> m_txSafetyRangesSq;
|
||||
Time m_TotalSimTime;
|
||||
uint32_t m_wavePacketSize; // bytes
|
||||
uint32_t m_numWavePackets;
|
||||
Time m_waveInterval;
|
||||
double m_gpsAccuracyNs;
|
||||
Ipv4InterfaceContainer * m_adhocTxInterfaces;
|
||||
std::vector<int> * m_nodesMoving;
|
||||
Ptr<UniformRandomVariable> m_unirv;
|
||||
int m_nodeId;
|
||||
// WAVE channel access mode. 0=continuous PHY; 1=channel-switching
|
||||
int m_chAccessMode;
|
||||
// When transmitting at a default rate of 10 Hz,
|
||||
// the subsystem shall transmit every 100 ms +/-
|
||||
// a random value between 0 and 5 ms. [MPR-BSMTX-TXTIM-002]
|
||||
// Source: CAMP Vehicle Safety Communications 4 Consortium
|
||||
// On-board Minimum Performance Requirements
|
||||
// for V2V Safety Systems Version 1.0, December 17, 2014
|
||||
// max transmit delay (default 10ms)
|
||||
Time m_txMaxDelay;
|
||||
Time m_prevTxDelay;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* BSM_APPLICATION_H*/
|
||||
Reference in New Issue
Block a user