A strange finding on collision number

2,820 views
Skip to first unread message

Ke

unread,
Jun 29, 2011, 5:26:41 PM6/29/11
to ns-3-users
Hello,

I am testing 802.11 protocol's performance. The network scenario and
parameters are as follows,
2 static nodes; 802.11b; with RTS/CTS; adhoc mode;
2 UDP flows(node1=>node2; node2=>node1) with different ports; packet
size: 1024B;

I run the simulation for 10 seconds every time, and the only parameter
I changed is "interPacketInterval" for UDP.(or you can consider it as
packet arrival rate) The result is:

interPacketInterval(s) collision# throughput(Mbps)
0.02 3 0.8192
0.01 69 1.638
0.008333 212 1.966
0.00625 302 2.619
0.005 0 2.811
0.004 0 2.811
0.002 0 2.811
0.001 0 2.811

I define that the collision happens when the backoff count has reached
zero and that the medium is busy. So I got the collision number from
the log "collision" (DcaTxop::NotifyCollision in dca-txop.cc). I refer
to this poster:
http://groups.google.com/group/ns-3-users/browse_thread/thread/887072e0e15b915d/2a9a7ee3ddf15afd?hl=en&lnk=gst&q=collision#2a9a7ee3ddf15afd

From the result the throughout increases and reaches the saturation
level when the packet arrival rate increases. The collision number
goes up but suddenly drops to zero.

I think the collision number is incorrect when saturation. From some
famous theoretical models for 802.11, the collision probability stays
to be stable when saturation. So the collision number should keep
increasing for this experiment instead of zeros. Dose anyone have some
explanation or thoughts about this?

Thanks,
Ke Xu

Jaume

unread,
Jun 30, 2011, 5:21:15 AM6/30/11
to ns-3-users
Hi Ke,
I am also quite interested in collisions, and when I look into the
logs, I must confess I don't understand what is going on. As an
example:
3.27635s [mac=00:00:00:00:00:02]
DcaTxop:NotifyAccessGranted(0x93428d0)
3.27635s [mac=00:00:00:00:00:02] DcaTxop:NotifyAccessGranted(): tx
unicast
3.2768s [mac=00:00:00:00:00:04] DcaTxop:Queue(0x9346020, 0x9373f48,
0xbfd27b48)
3.2768s [mac=00:00:00:00:00:04] DcaTxop:StartAccessIfNeeded(0x9346020)
3.2768s [mac=00:00:00:00:00:04] DcaTxop:NotifyCollision(0x9346020)
3.2768s [mac=00:00:00:00:00:04] DcaTxop:NotifyCollision(): collision
3.2768s [mac=00:00:00:00:00:04]
DcaTxop:RestartAccessIfNeeded(0x9346020)
3.27688s [mac=00:00:00:00:00:04] DcaTxop:Queue(0x93453a0, 0x93624c8,
0xbfd267ec)
3.27688s [mac=00:00:00:00:00:04]
DcaTxop:StartAccessIfNeeded(0x93453a0)
3.27694s [mac=00:00:00:00:00:02] DcaTxop:GotAck(0x93428d0, 1453.92,
OfdmRate6Mbps)
3.27694s [mac=00:00:00:00:00:02] DcaTxop:GotAck(): got ack. tx done.

In the literature, a collision is defined as a receiver failing to
correctly receive a transmission because of the interference caused by
another transmission that overlaps in time. This happens when two
stations reach a backoff counter equal to zero simultaneously, or when
there is a hidden node situation. However, it seems that the concept
of collision is somewhat different in ns-3.

Quoting Mathieu:
"Well, it really depends on what you define as being a collision but
this
debug statement will be triggered when the user has just requested
access to the medium, that the backoff count has reached zero and that
the medium is busy. "

I will look closer into it to understand the details. My
recommendation is that you also take a look at the "missed ack" log
messages, since those can be an indicator of a collision.

Please, keep me updated if you make any progress. Could you post a
copy of the ns-3 code that you are using to obtain the results in your
previous post?

Thanks,
Jaume

On Jun 29, 11:26 pm, Ke <kxu1...@gmail.com> wrote:
> Hello,
>
> I am testing 802.11 protocol's performance. The network scenario and
> parameters are as follows,
> 2 static nodes; 802.11b; with RTS/CTS; adhoc mode;
> 2 UDP flows(node1=>node2; node2=>node1) with different ports; packet
> size: 1024B;
>
> I run the simulation for 10 seconds every time, and the only parameter
> I changed is "interPacketInterval" for UDP.(or you can consider it as
> packet arrival rate) The result is:
>
> interPacketInterval(s)  collision#           throughput(Mbps)
> 0.02                                    3                    0.8192
> 0.01                                    69                   1.638
> 0.008333                                212                  1.966
> 0.00625                         302                  2.619
> 0.005                           0                    2.811
> 0.004                           0                    2.811
> 0.002                           0                    2.811
> 0.001                           0                    2.811
>
> I define that the collision happens when the backoff count has reached
> zero and that the medium is busy. So I got the collision number from
> the log "collision" (DcaTxop::NotifyCollision in dca-txop.cc). I refer
> to this poster:http://groups.google.com/group/ns-3-users/browse_thread/thread/887072...

Ke

unread,
Jun 30, 2011, 11:11:38 AM6/30/11
to ns-3-users
Hi Jaume,

Thank you for replying. I'll also trace the log to see the details.
Here is my code. Please just ignore the term "sink" and "source" in
the code; the two nodes both send the traffic and I didn't change the
name.

Ke

//==================================
// A simple UDP test
//
// Ke Xu, PhD candidate
// ECE, Clemson University
// k...@clemson.edu
//==================================

#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace ns3;

int
main (int argc, char *argv[])
{
uint32_t nsource = 1;// number of source stations
uint32_t nsink = 1;// number of sink stations
uint32_t i;// iteration index

// Enable rts/cts all the time
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",
StringValue ("0"));

// Create wifi nodes
NodeContainer sta;
sta.Create (nsource+nsink);

YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
phy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
phy.SetChannel (channel.Create ());

WifiHelper wifi = WifiHelper::Default ();
wifi.SetRemoteStationManager ("ns3::AarfWifiManager"); //rate
control algorithm
wifi.SetStandard(WIFI_PHY_STANDARD_80211b);// IEEE 802.11g

NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();

// Set it to adhoc mode
mac.SetType ("ns3::AdhocWifiMac");
NetDeviceContainer devices = wifi.Install (phy, mac, sta);

//Specify wifi modes to be stationary but randomly allocated within
a disc
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::RandomDiscPositionAllocator",
"Theta", RandomVariableValue
(UniformVariable (0.0, 6.2830)),
"Rho", RandomVariableValue
(UniformVariable (0.0, 100.0)),
"X", DoubleValue (0.0),
"Y", DoubleValue (0.0));
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (sta);

// Internet and Stack
InternetStackHelper stack;
stack.Install (sta);

Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer ipadd = address.Assign (devices);


// Generate traffic

// UDP: 10.1.1.1 ===>>> 10.1.1.2
// Create one udpServer applications on 10.1.1.2
uint16_t port_1 = 4000;
UdpServerHelper server_1 (port_1);
ApplicationContainer apps_1 = server_1.Install (sta.Get(1));
apps_1.Start (Seconds (0.0));
// Create one UdpClient application to send UDP datagrams from
10.1.1.1 to 10.1.1.2.
uint32_t MaxPacketSize = 1024;
Time interPacketInterval = Seconds (0.001);
uint32_t maxPacketCount = 400000000;
UdpClientHelper client_1 (ipadd.GetAddress (1), port_1);
client_1.SetAttribute ("MaxPackets", UintegerValue
(maxPacketCount));
client_1.SetAttribute ("Interval", TimeValue (interPacketInterval));
client_1.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
apps_1 = client_1.Install (sta.Get (0));
apps_1.Start (Seconds (0.0));

// UDP: 10.1.1.2 ===>>> 10.1.1.1
// Create one udpServer applications on 10.1.1.1
uint16_t port_2 = 2000;
UdpServerHelper server_2 (port_2);
ApplicationContainer apps_2 = server_2.Install (sta.Get(0));
apps_2.Start (Seconds (0.0));
// Create one UdpClient application to send UDP datagrams from
10.1.1.1 to 10.1.1.2.
UdpClientHelper client_2 (ipadd.GetAddress (0), port_2);
client_2.SetAttribute ("MaxPackets", UintegerValue
(maxPacketCount));
client_2.SetAttribute ("Interval", TimeValue (interPacketInterval));
client_2.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
apps_2 = client_2.Install (sta.Get (1));
apps_2.Start (Seconds (0.0));

// Set routing
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

// Set simulation stop time
Simulator::Stop (Seconds (10.0));

// Save pcap file for each station
for (i=0; i<nsource+nsink; i+=2) {
phy.EnablePcap ("src", devices.Get (i));
phy.EnablePcap ("sink", devices.Get (i+1));
}

// Start the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;

Jaume Barcelo

unread,
Jul 1, 2011, 10:24:35 AM7/1/11
to ns-3-users
Thanks Ke,
I took your code and added a function to populate the ARP cache and
also changed the starting times for the applications. If they are
started simultaneously, they are synchronized and collide again and
again.
(See https://www.nsnam.org/bugzilla/show_bug.cgi?id=388 )

Then I counted the number of collisions. To do so, I counted the
number of 'missed cts' and divided by two, since in every collision,
two cts are lost.

This is what I obtained:
InterPacketArrival => collisions
0.1 => 0
0.01 => 2
0.001 => 143
0.0001 => 143

An interesting exercise would be to count also the number of
successful transmissions and check that the collision/success ratio
coincides with the one that can be derived analytically.

I have used
export 'NS_LOG=DcaTxop=level_all|prefix_func|prefix_time'
to enable logging and this is your code after the modifications I
made.
#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace ns3;

void
PopulateArpCache ()
{
Ptr<ArpCache> arp = CreateObject<ArpCache> ();
arp->SetAliveTimeout (Seconds(3600 * 24 * 365));
for (NodeList::Iterator i = NodeList::Begin(); i != NodeList::End();
++i)
{
Ptr<Ipv4L3Protocol> ip = (*i)->GetObject<Ipv4L3Protocol> ();
NS_ASSERT(ip !=0);
ObjectVectorValue interfaces;
ip->GetAttribute("InterfaceList", interfaces);
for(ObjectVectorValue::Iterator j = interfaces.Begin(); j !=
interfaces.End (); j ++)
{
Ptr<Ipv4Interface> ipIface = (*j)->GetObject<Ipv4Interface> ();
NS_ASSERT(ipIface != 0);
Ptr<NetDevice> device = ipIface->GetDevice();
NS_ASSERT(device != 0);
Mac48Address addr = Mac48Address::ConvertFrom(device->GetAddress
());
for(uint32_t k = 0; k < ipIface->GetNAddresses (); k ++)
{
Ipv4Address ipAddr = ipIface->GetAddress (k).GetLocal();
if(ipAddr == Ipv4Address::GetLoopback())
continue;
ArpCache::Entry * entry = arp->Add(ipAddr);
entry->MarkWaitReply(0);
entry->MarkAlive(addr);
}
}
}
for (NodeList::Iterator i = NodeList::Begin(); i != NodeList::End();
++i)
{
Ptr<Ipv4L3Protocol> ip = (*i)->GetObject<Ipv4L3Protocol> ();
NS_ASSERT(ip !=0);
ObjectVectorValue interfaces;
ip->GetAttribute("InterfaceList", interfaces);
for(ObjectVectorValue::Iterator j = interfaces.Begin(); j !=
interfaces.End (); j ++)
{
Ptr<Ipv4Interface> ipIface = (*j)->GetObject<Ipv4Interface> ();
ipIface->SetAttribute("ArpCache", PointerValue(arp));
apps_1.Start (Seconds (1.1));

// UDP: 10.1.1.2 ===>>> 10.1.1.1
// Create one udpServer applications on 10.1.1.1
uint16_t port_2 = 2000;
UdpServerHelper server_2 (port_2);
ApplicationContainer apps_2 = server_2.Install (sta.Get(0));
apps_2.Start (Seconds (0.0));
// Create one UdpClient application to send UDP datagrams from
10.1.1.1 to 10.1.1.2.
UdpClientHelper client_2 (ipadd.GetAddress (0), port_2);
client_2.SetAttribute ("MaxPackets", UintegerValue
(maxPacketCount));
client_2.SetAttribute ("Interval", TimeValue (interPacketInterval));
client_2.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
apps_2 = client_2.Install (sta.Get (1));
apps_2.Start (Seconds (1.1234));

// Set routing
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

// Populate ARP cache
PopulateArpCache ();

// Set simulation stop time
Simulator::Stop (Seconds (10.0));

// Save pcap file for each station
for (i=0; i<nsource+nsink; i+=2) {
phy.EnablePcap ("src", devices.Get (i));
phy.EnablePcap ("sink", devices.Get (i+1));
}

// Start the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;

}

Have a nice weekend!
Jaume

On Jun 30, 5:11 pm, Ke <kxu1...@gmail.com> wrote:
> HiJaume,

Ke

unread,
Jul 1, 2011, 3:00:40 PM7/1/11
to ns-3-users
Thank you Jaume,

That makes sense. Yesterday I also found that the same start time
causes more collisions at the very beginning. Later I will generate
random start time, use more nodes and compare the collision
probability with the theoretical analysis.

Thanks again,
Ke
> ...
>
> read more »

Jaume Barcelo

unread,
Jul 5, 2011, 1:03:30 PM7/5/11
to ns-3-users
Hi Ke,

I will be very thankful if you share your results and code with me.

I am working on the use of a deterministic backoff after successful
transmissions (we call it CSMA/ECA) that substantially reduces the
number of collisions when the stations are saturated. I created a
patch for NS-3 that implements CSMA/ECA and I used the code you sent
me last week to validate that the patch works for two contenders. It
reduced the number of collisions to 4 when the interPacketArrival was
0.001!

Now I want to check if my patch also works for a larger number of
contenders, and then I will send the patch to the list to share it
with the NS-3 community.

Cheers,
Jaume

On Jul 1, 9:00 pm, Ke <kxu1...@gmail.com> wrote:
> Thank youJaume,
>
> That makes sense. Yesterday I also found that the same start time
> causes more collisions at the very beginning. Later I will generate
> random start time, use more nodes and compare the collision
> probability with the theoretical analysis.
>
> Thanks again,
> Ke
>
> ...
>
> read more »

Jaume Barcelo

unread,
Jul 6, 2011, 5:47:14 AM7/6/11
to ns-3-users
Hi Ke,
how do you compute the probability of collision? I would expect a
value around 0.06

I solved the system of equations in Bianchi's 2000 JSAC paper in
octave

function y=f(x)
y(1)=(2*(1-x(1)))/((32+1)*(1-2*x(1))+x(1)*32*(1+(2*x(1))^4))-x(2);
y(2)=-x(1)+1-(1-x(2));
endfunction

[x,info]=fsolve("f",[0.6;0.6])

and I obtain

x =

0.060724
0.060724

In order to compute the collision probability from the simulation, I
enable logging:
export 'NS_LOG=DcaTxop=level_all|prefix_func|prefix_time'
I redirect the output of the simulation to a file:
./waf --run scratch/kexu 2>output.txt
And I count the number of rts and the number of "missed cts":
jbarcelo@antartida:~/repos/ns-3-allinone/ns-3.11$ grep rts output.txt |
wc
3052 18312 240772
jbarcelo@antartida:~/repos/ns-3-allinone/ns-3.11$ grep 'missed cts'
output.txt |wc
186 930 12069
Finally, I take the division of the two values:
octave:3> 186/3052
ans = 0.060944

which seems to be in agreement with the result that we obtained
analytically.

Cheers,
Jaume

Ke

unread,
Jul 6, 2011, 10:29:51 AM7/6/11
to ns-3-users
Hey Jaume,

I computed the collision probability exactly as the same as you did,
using (missed cts #) / (rts #).

From the result I got for 2 nodes (please refer to the figure I send
you), the average of collision probability when saturation is around
0.04. In Bianchi's model, it does not consider the retransmission
limit. I think for our test the default retransmission limit is 7(But
I don't think it will influence your result got from octave a lot).
From simulation results for 4 nodes and 8 nodes, the average of
collision probability when saturation is around 0.11 and 0.20,
respectively. You can use apply Bianchi's model to check again.

Please check out my updated ns3 code. I generate random start time,
and fix the rate for sending data and control packets. Also, I changed
the radius of the disc area to 50, which makes sure the maximum
distance of two nodes is 100(guarantee they can talk to each other). I
added two input parameters, which are "PacketArrivalRate" and
"StationNumber". For "StationNumber" you only can use even number, I
created the udp flows for pairs. You can run the command like:
./waf --run "scratch/kexu --PacketArrivalRate=1000 --StationNumber=4"
2> output.txt

Here is the code.

#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <sstream>

using namespace ns3;

void PopulateArpCache ();

int
main (int argc, char *argv[])
{
uint32_t n_sta = 2;// number of stations
uint32_t i;// iteration index
uint32_t pkt_arrv_rate = 50;// pkt/s
float pkt_interval; // sec

float randtime_1,randtime_2;// random start time
srand(time(NULL));

std::string controlRate ("DsssRate1Mbps");
std::string dataRate ("DsssRate11Mbps");

CommandLine cmd;
cmd.AddValue ("PacketArrivalRate", "packet arrival rate on each
station(/s)", pkt_arrv_rate);
cmd.AddValue ("StationNumber", "the number of stations", n_sta);
cmd.Parse (argc, argv);

// Calcuate packet arrival interval
pkt_interval = 1.00 / pkt_arrv_rate;

// Enable rts/cts all the time
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",
StringValue ("0"));
// Fix non-unicast data rate to be the same as that of unicast
Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
StringValue (controlRate));

// Create wifi nodes
NodeContainer sta;
sta.Create (n_sta);
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
phy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
phy.SetChannel (channel.Create ());

WifiHelper wifi = WifiHelper::Default ();
// wifi.SetRemoteStationManager ("ns3::AarfWifiManager"); //rate
control algorithm
// Set data rate as 12Mbps; control rate as 1Mbps
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode",StringValue(dataRate),

"ControlMode",StringValue(controlRate));
wifi.SetStandard(WIFI_PHY_STANDARD_80211b);// IEEE 802.11g
NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();

// Set it to adhoc mode
mac.SetType ("ns3::AdhocWifiMac");
NetDeviceContainer devices = wifi.Install (phy, mac, sta);

//Specify wifi modes to be stationary but randomly allocated within
a disc
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::RandomDiscPositionAllocator",
"Theta", RandomVariableValue
(UniformVariable (0.0, 6.2830)),
"Rho", RandomVariableValue
(UniformVariable (0.0, 50.0)),
"X", DoubleValue (0.0),
"Y", DoubleValue (0.0));
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (sta);

// Internet and Stack
InternetStackHelper stack;
stack.Install (sta);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer ipadd = address.Assign (devices);

//============================== Generate traffic
=======================================
// define UDP port
uint16_t port_1 = 4000;
uint16_t port_2 = 2000;
// define UDP maximum packet number and packet size
uint32_t maxPacketCount = 400000000;
uint32_t MaxPacketSize = 1024;

for (i=0; i<n_sta; i+=2) {

// Generate random time
randtime_1 = (rand()%1000+1)/1000.00;//random time 1: [0,1]sec
randtime_2 = (rand()%1000+1)/1000.00;//random time 2: [0,1]sec

// UDP: 10.1.1.(i) ===>>> 10.1.1.(i+1)
// Create one udpServer applications on 10.1.1.(i+1)
UdpServerHelper server_1 (port_1);
ApplicationContainer apps_1 = server_1.Install (sta.Get(i+1));
apps_1.Start (Seconds (0.0));
// Create one UdpClient application to send UDP datagrams from
10.1.1.(i) to 10.1.1.(i+1).
Time interPacketInterval = Seconds (pkt_interval);
UdpClientHelper client_1 (ipadd.GetAddress (i+1), port_1);
client_1.SetAttribute ("MaxPackets", UintegerValue
(maxPacketCount));
client_1.SetAttribute ("Interval", TimeValue
(interPacketInterval));
client_1.SetAttribute ("PacketSize", UintegerValue
(MaxPacketSize));
apps_1 = client_1.Install (sta.Get (i));
apps_1.Start (Seconds (randtime_1));

// UDP: 10.1.1.(i+1) ===>>> 10.1.1.(i)
// Create one udpServer applications on 10.1.1.(i)
UdpServerHelper server_2 (port_2);
ApplicationContainer apps_2 = server_2.Install (sta.Get(i));
apps_2.Start (Seconds (0.0));
// Create one UdpClient application to send UDP datagrams from
10.1.1.(i+1) to 10.1.1.(i).
UdpClientHelper client_2 (ipadd.GetAddress (i), port_2);
client_2.SetAttribute ("MaxPackets", UintegerValue
(maxPacketCount));
client_2.SetAttribute ("Interval", TimeValue
(interPacketInterval));
client_2.SetAttribute ("PacketSize", UintegerValue
(MaxPacketSize));
apps_2 = client_2.Install (sta.Get (i+1));
apps_2.Start (Seconds (randtime_2));
}

// Set routing
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

// Populate ARP cache
PopulateArpCache ();

// Set simulation stop time
Simulator::Stop (Seconds (30.0));

// Save pcap file for each station
for (i=0; i<n_sta; i++) {
phy.EnablePcap ("sta", devices.Get (i));
}

// Start the simulation
Simulator::Run ();
Simulator::Destroy ();
return 0;
}

//=========== Below are functions ====================
Thanks,
Ke

Jaume Barcelo

unread,
Jul 11, 2011, 7:02:38 AM7/11/11
to ns-3-...@googlegroups.com
Thanks again for your code, Ke, it is very useful to me.

I wanted to evaluate the collision probability for an increasing number of stations.
I enabled logging
export 'NS_LOG=DcaTxop=level_all|prefix_func|prefix_time'
and then I used this script, that perform the tests for 2,4,6,8 and 10 stations, to count the number of rts and missed cts:
i=2;
while [ $i -le 10 ]
do
  ./waf --run "scratch/kexu --PacketArrivalRate=3000 --StationNumber=$i" 2> output.txt
  rts=`grep rts output.txt |wc -l`
  cts=`grep 'missed cts' output.txt |wc -l`
  pcc=`echo "scale=4;$cts/$rts" | bc`
  echo "Sta:$i Pc:$pcc"
  i=`expr $i + 2`
done

And I obtained this result:
Sta:2 Pc:.0613
Sta:4 Pc:.1161
Sta:6 Pc:.1688
Sta:8 Pc:.2032
Sta:10 Pc:.2186

When I use Bianchi's model to evaluate the collision probability for 10 stations, I obtain a different result. I use this octave script
zero=0

function y=f(x)
y(1)=(2*(1-x(1)))/((32+1)*(1-2*x(1))+x(1)*32*(1+(2*x(1))^7))-x(2);
y(2)=-x(1)+1-(1-x(2))^(10-1);

endfunction

[x,info]=fsolve("f",[0.6;0.6])

and I obtain this result:
zero = 0
x =

   0.397296
   0.054705

info =

   8.7507e-10   6.2120e-10
which is a collision probability close to 0.4, which seems to be in agreement with the value presented in Fig. 7 in this article:
http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=5191039

Do you know why the simulation results are not in agreement with the analytical results? Am I doing something wrong?

Cheers,
Jaume

Ke

unread,
Jul 11, 2011, 2:46:38 PM7/11/11
to ns-3-users
Hey Jaume,

The same problem I met as yours. I have tested basic access and RTS/
CTS mode both. If you want to change to basic access mode, just
comment this line in ns3 code:
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",
StringValue ("0"));
and grep "missed ack" after running.

For 4 nodes, when saturation the collision probabilities are around:
basic access: 0.125
RTS/CTS: 0.115

I calculated transmission probability p_tr using above values, please
refer to equation (9) and (10) in this Bianchi's paper:
http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=840210
basic access: 0.1631
RTS/CTS: 0.1503

Then I checked the experiment log:
basic access:
missed ack: 2800; tx unicast: 22199; got ack: 19398
RTS/CTS:
missed cts: 1786; rts: 15509; got cts: 13723

I estimated the transmission time for successful tx packets, for
example for RTS/CTS mode,
13723*1024*8/11Mbps = 10.22 s
The total simulation time is 30s. So the channel occupancy probability
for only successful packet transmission which is already larger than
0.3, far away from 0.1503 we got.

Now I've no idea about what's the reason and am still thinking about
it. Btw, the throughput I got is also different from theoretical
analysis (simulate results are larger than theoretical results).
Please let me know if any ideas or progress.

Thank you,
Ke

Nicola Baldo

unread,
Jul 13, 2011, 4:36:07 PM7/13/11
to ns-3-users
I used extensively the Bianchi model some time ago, so I had my own
octave code similar to the one reported by Jaume.
For your reference, here are (using the notation in Bianchi's paper)
the values that I get for m=7 and W=31:

for N=2:
p = 0.058716
tau = 0.058716

for N=3:
p = 0.10734
tau = 0.055192

for N=4:
p = 0.14786
tau = 0.051938

for N=5:
p = 0.18190
tau = 0.048953

for N=6:
p = 0.21073
tau = 0.046227

for N=7:
p = 0.23539
tau = 0.043746

for N=8:
p = 0.25670
tau = 0.041494

for N=9:
p = 0.27529
tau = 0.039449


Remember that ,for low values of N, Bianchi's model is expected not to
be accurate because the assumption that the collision probability is
not dependent on the particular slot considered does not hold.

Nicola Baldo

unread,
Jul 13, 2011, 4:59:38 PM7/13/11
to ns-3-users


On Jul 11, 1:02 pm, Jaume Barcelo <jaume.barc...@gmail.com> wrote:
> Thanks again for your code, Ke, it is very useful to me.
>
> I wanted to evaluate the collision probability for an increasing number of
> stations.
> I enabled logging
> export 'NS_LOG=DcaTxop=level_all|prefix_func|prefix_time'
> and then I used this script, that perform the tests for 2,4,6,8 and 10
> stations, to count the number of rts and missed cts:
> i=2;
> while [ $i -le 10 ]
> do
>   ./waf --run "scratch/kexu --PacketArrivalRate=3000 --StationNumber=$i" 2>
> output.txt
>   rts=`grep rts output.txt |wc -l`
>   cts=`grep 'missed cts' output.txt |wc -l`
>   pcc=`echo "scale=4;$cts/$rts" | bc`
>   echo "Sta:$i Pc:$pcc"
>   i=`expr $i + 2`
> done


Your procedure seems reasonable (didn't investigate deeply), but just
for double-checking may I suggest to count the number of times the
following traces are triggered:

/NodeList/*/DeviceList/*/Phy/State/RxOk
/NodeList/*/DeviceList/*/Phy/State/RxError

and measure the collision probability as

p = numRxError / (numRxOk + numRxError)

of course the above assumes you made sure that there are no noise-
related errors in your setup.

For how to connect to these traces, I suggest to have a look at
examples/wireless/wifi-ap.cc

Nicola Baldo

unread,
Jul 13, 2011, 5:35:08 PM7/13/11
to ns-3-users

By the way, I had a quick look at your sim program, and I suggest to
try the following changes:

1) set disc radius to 0. It's Bianchi model after all, why do you want
something bigger? you need to avoid not only packet losses, but also
the capture effect.

2) set the packet arrival consistently with the PHY data rate to make
sure you have saturation. With 3000 pkts/s and 1024 byte payload you
get less than 3Mbps, with an 11Mbps PHY rate it is not enough, unless
the number of users is high.

3) use ns-3's random number generators instead of rand(), and repeat
the experiment with different rng replication numbers.


One last thing, and probably the most important... I just remembered
that in order to match with the Bianchi model you need to set the
retransmission limit to infinity, i.e., set the MaxSsrc and MaxSlrc
attributes of WifiRemoteStationManager to a big enoug number. In fact,
W in Bianchi's model refers to the calculation of CWMAX, not to the
retry limit. If I remember correctly, this makes a significant
difference in the collision probability.

Nicola Baldo

unread,
Jul 13, 2011, 5:37:32 PM7/13/11
to ns-3-users


On Jul 13, 11:35 pm, Nicola Baldo <nba...@cttc.es> wrote:
> 1) set disc radius to 0. It's Bianchi model after all, why do you want
> something bigger? you need to avoid not only packet losses, but also
> the capture effect.

...and avoid using the 1Mbps mode because it has very good capture
properties.

Jaume Barcelo

unread,
Jul 14, 2011, 5:16:15 AM7/14/11
to ns-3-users
Thanks Nicola for all your messages and tips :)

Jaume Barcelo

unread,
Jul 14, 2011, 5:58:45 AM7/14/11
to ns-3-users
I just wanted to clarify that the octave code I posted above is wrong.
That is the reason the results I obtained are not in agreement with
Nicola's results. These are the correct equations for N=9, CW=31, and
m=7

function y=f(x)
y(1)=(2*(1-2*x(1)))/((31+1)*(1-2*x(1))+x(1)*31*(1-(2*x(1))^7))-x(2);
y(2)=-x(1)+1-(1-x(2))^(9-1);
endfunction

[x,info]=fsolve("f",[0.06;0.06])

and this is the result that coincides with Nicola's.
x =

0.275293
0.039449

info =

-3.9374e-10 -8.1998e-10

Taking a second look at Bianchi's jsac paper, I realize that the
definition of CWmin is slightly different in the paper than in the
standard. I would say that in the equations we should use W=32 and not
W=31. Well, this is a tiny difference.

Cheers,
Jaume

Ke

unread,
Jul 18, 2011, 3:00:05 PM7/18/11
to ns-3-users
Hi Nicola,

Thank you for you hints. I have modified the code following your
suggestions. Here are the results,

N RXERROR RXOK CollisionProb
4 2990 114408 0.04967
6 9041 186170 0.08853
8 16989 255122 0.11753
10 26884 321498 0.14328

I set the packet arrival rate as 1000 pkt/s to guarantee the traffic
load in the network is in saturation. And I used basic access mode and
calculated the collision probability as
p = RXERROR# / ( RXERROR# + RXOK# / 2 )

Compared to the theoretical results, it seems there are bigger
differences than our previous method. Did I do something wrong?

Thanks,
Ke

Jaume Barcelo

unread,
Jul 19, 2011, 4:25:44 AM7/19/11
to ns-3-users
Thanks Ke.

Can you share the new code?

Cheers,
Jaume

Ke

unread,
Jul 19, 2011, 1:46:17 PM7/19/11
to ns-3-users
Hey Jaume,

Here is the code.

Ke

#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/config-store-module.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <sstream>
#include <iostream>

using namespace ns3;

static bool g_verbose = true;

void
DevTxTrace (std::string context, Ptr<const Packet> p)
{
if (g_verbose)
{
std::cout << " TX p: " << *p << std::endl;
}
}

void
DevRxTrace (std::string context, Ptr<const Packet> p)
{
if (g_verbose)
{
std::cout << " RX p: " << *p << std::endl;
}
}

void
PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double
snr, WifiMode mode, enum WifiPreamble preamble)
{
if (g_verbose)
{
std::cout << "PHYRXOK mode=" << mode << " snr=" << snr << " " <<
*packet << std::endl;
}
}

void
PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double
snr)
{
if (g_verbose)
{
std::cout << "PHYRXERROR snr=" << snr << " " << *packet <<
std::endl;
}
}

void
PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode
mode, WifiPreamble preamble, uint8_t txPower)
{
if (g_verbose)
{
std::cout << "PHYTX mode=" << mode << " " << *packet <<
std::endl;
}
}

void
PhyStateTrace (std::string context, Time start, Time duration, enum
WifiPhy::State state)
{
if (g_verbose)
{
std::cout << " state=" << state << " start=" << start << "
duration=" << duration << std::endl;
}
}

void PopulateArpCache ();

int main (int argc, char *argv[])
{
uint32_t n_sta = 10;// number of stations
uint32_t i;// iteration index
uint32_t pkt_arrv_rate = 1000;// pkt/s
float pkt_interval; // sec

float randtime_1,randtime_2;// random start time
srand(time(NULL));

std::string controlRate ("DsssRate1Mbps");
std::string dataRate ("DsssRate11Mbps");

CommandLine cmd;
cmd.AddValue ("PacketArrivalRate", "packet arrival rate on each
station(/s)", pkt_arrv_rate);
cmd.AddValue ("StationNumber", "the number of stations", n_sta);
cmd.Parse (argc, argv);

// Calcuate packet arrival interval
pkt_interval = 1.00 / pkt_arrv_rate;

// Enable rts/cts all the time
//
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",
StringValue ("0"));
// Fix non-unicast data rate to be the same as that of unicast
Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
StringValue (controlRate));

// Set the retransmission limit
Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc",
StringValue("1000"));
Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc",
StringValue("1000"));


// Create wifi nodes
NodeContainer sta;
sta.Create (n_sta);
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
phy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
phy.SetChannel (channel.Create ());

WifiHelper wifi = WifiHelper::Default ();
// wifi.SetRemoteStationManager ("ns3::AarfWifiManager"); //rate
control algorithm
// Set data rate as 12Mbps; control rate as 1Mbps
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode",StringValue(dataRate),
"ControlMode",StringValue(dataRate));//
controlRate
wifi.SetStandard(WIFI_PHY_STANDARD_80211b);// IEEE 802.11g
NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();

// Set it to adhoc mode
mac.SetType ("ns3::AdhocWifiMac");
NetDeviceContainer devices = wifi.Install (phy, mac, sta);

//Specify wifi modes to be stationary but randomly allocated within
a disc
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::RandomDiscPositionAllocator",
"Theta", RandomVariableValue
(UniformVariable (0.0, 6.2830)),
"Rho", RandomVariableValue
(UniformVariable (0.0, 0.0)),
// apps_1.Start (Seconds (DoubleValue
(RandomVariableValue( (UniformVariable (0.0, 1.0))))));

// UDP: 10.1.1.(i+1) ===>>> 10.1.1.(i)
// Create one udpServer applications on 10.1.1.(i)
UdpServerHelper server_2 (port_2);
ApplicationContainer apps_2 = server_2.Install (sta.Get(i));
apps_2.Start (Seconds (0.0));
// Create one UdpClient application to send UDP datagrams from
10.1.1.(i+1) to 10.1.1.(i).
UdpClientHelper client_2 (ipadd.GetAddress (i), port_2);
client_2.SetAttribute ("MaxPackets", UintegerValue
(maxPacketCount));
client_2.SetAttribute ("Interval", TimeValue
(interPacketInterval));
client_2.SetAttribute ("PacketSize", UintegerValue
(MaxPacketSize));
apps_2 = client_2.Install (sta.Get (i+1));
apps_2.Start (Seconds (randtime_2));
// apps_2.Start (Seconds (RandomVariableValue (UniformVariable
(0.0, 1.0))));
}

// Set routing
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

// Populate ARP cache
PopulateArpCache ();

// Set simulation stop time
Simulator::Stop (Seconds (30.0));

Config::Connect ("/NodeList/*/DeviceList/*/Mac/MacTx", MakeCallback
(&DevTxTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Mac/MacRx", MakeCallback
(&DevRxTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxOk",
MakeCallback (&PhyRxOkTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxError",
MakeCallback (&PhyRxErrorTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/Tx",
MakeCallback (&PhyTxTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/State",
MakeCallback (&PhyStateTrace));

// Save pcap file for each station
// for (i=0; i<n_sta; i++) {
// phy.EnablePcap ("sta", devices.Get (i));

Jaume Barcelo

unread,
Jul 21, 2011, 10:06:55 AM7/21/11
to ns-3-users
Hi Ke,
Sorry for the delayed answer.
I am currently a bit overwhelmed with other tasks and I didn't have
time to take a look at your code until now.

Did you create an additional "monitor" node to take the measures as
Nicola suggested? Nicola's idea was to take measures only in that
node. He warns that, otherwise, we will get 0 collisions in the 2 node
scenario. And that is exactly what I obtained when I tried your code.

Thanks for all your coding efforts and please accept my apologies for
not contributing.

Cheers,
Jaume

On Jul 19, 7:46 pm, Ke <kxu1...@gmail.com> wrote:
> HeyJaume,
> ...
>
> read more »

Nicola Baldo

unread,
Jul 13, 2011, 5:08:48 PM7/13/11
to ns-3-users


On Jul 13, 10:59 pm, Nicola Baldo <nba...@cttc.es> wrote:
> for double-checking may I suggest to count the number of times the
> following traces are triggered:
>
> /NodeList/*/DeviceList/*/Phy/State/RxOk
> /NodeList/*/DeviceList/*/Phy/State/RxError
>
> and measure the collision probability as
>
> p = numRxError / (numRxOk + numRxError)

I forgot to say that the cleanest approach would be to have in the
simulation an additional "monitor" node that is not transmitting
anything, and to count RxOk and RxError only for that node. Otherwise,
for example, you'll get 0 collision for a 2 node scenario.

Another thing that I forgot to say, is that, in basic access mode, you
should probably divide RxOk by two because of ACKs; in RTS/CTS mode,
you should divide by...

Jaume Barcelo

unread,
Jul 21, 2011, 11:47:24 AM7/21/11
to ns-3-users
Hi Ke,
I changed the code you provided to add an additional node and to print
context information.
Then I run the simulator for two contending stations:
jbarcelo@antartida:~/repos/ns-3-allinone/ns-3.11$ ./waf --run "scratch/
jaumebarcelo --PacketArrivalRate=30000 --StationNumber=2" &>
output.txt
yes, I know 30000 is a crazy value :)
Then I count the number of errors measured at node 2 (this is the
monitor node):
jbarcelo@antartida:~/repos/ns-3-allinone/ns-3.11$ grep NodeList/2
output.txt |grep RxError|wc
602 1806 42742
I also count the number of successes measured at node 2:
jbarcelo@antartida:~/repos/ns-3-allinone/ns-3.11$ grep NodeList/2
output.txt |grep RxOk|wc
37938 151752 3205761
I will assume that a successful transmission triggers the RxOk twice
(one for the packet and one for the ack).
I will also assume that a collision (which is in fact two collisions,
since each station is transmitting) is counted only once.
With this assumptions, I will compute the collision probability as
2*RxError/(2*RxError+RxOk/2)
2*602/(2*602+37938/2) = 0.059684

which is similar to the analytical value provided by Nicola in his
previous email (p = 0.058716)

I copy&paste the code that I used:
#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/config-store-module.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <sstream>
#include <iostream>

using namespace ns3;

static bool g_verbose = true;

void
DevTxTrace (std::string context, Ptr<const Packet> p)
{
if (g_verbose)
{
std::cout << context << " TX p: " << *p << std::endl;
}

}

void
DevRxTrace (std::string context, Ptr<const Packet> p)
{
if (g_verbose)
{
std::cout << context << " RX p: " << *p << std::endl;
}

}

void
PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double
snr, WifiMode mode, enum WifiPreamble preamble)
{
if (g_verbose)
{
std::cout << context << " PHYRXOK mode=" << mode << " snr=" <<
snr << " " <<
*packet << std::endl;
}

}

void
PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double
snr)
{
if (g_verbose)
{
std::cout << context << " PHYRXERROR snr=" << snr << " " <<
*packet <<
std::endl;
}

}

void
PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode
mode, WifiPreamble preamble, uint8_t txPower)
{
if (g_verbose)
{
std::cout << context << " PHYTX mode=" << mode << " " << *packet
sta.Create (n_sta+1);
Cheers,
Jaume
> ...
>
> read more »

Kang Hailong

unread,
Dec 8, 2015, 9:33:17 PM12/8/15
to ns-3-users
Hi,Jaume

I run the code you posted in new version 3.23 and find that the results is the  same with yours.
I am trying to validate the 802.11b MAC model  with Bianchi model ( delay throughput ...)
Do you have some advice?


在 2011年7月21日星期四 UTC+8下午11:47:24,Jaume Barcelo写道:

Amr ABDELFATTAH

unread,
Dec 21, 2015, 12:16:19 PM12/21/15
to ns-3-users
Hi, 
I have some results which i like to share it with you and have your comments on it. I had used the equations of bianchi's' paper titled 'Refinements on IEEE 802.11 Distributed Coordination Function Modeling Approaches'. More precisely, equations (15) through (24) for basic access (without RTS/CTS).
And ns3 simulation parameters was

1/ channel bit rate = 6 Mbps.
2/ packet size = 512 byte at application layer using ON/OFF application thats is means (512+8+20+36) bytes at Mac layer.  (Bianchi uses 1500 byte at PHY layer)
3 / the throughput has been evaluated at the application layer in constract to bianchi throughput which calculated just before the MAC layer. 

So, Normaly My figures should be the same like Binachi's figure at page 1064 for the probability of collision since it does not depend on the packet size whereas for the throughput it is different (I had customise its equation of thoughput to meet my simulation results). 
Bianchi Vs Ns3.jpg

Mahesh M

unread,
Dec 14, 2017, 10:49:12 PM12/14/17
to ns-3-users
Sir I am unable to work with is code. can you please help me

Masood Abbasi

unread,
Dec 15, 2018, 2:26:08 AM12/15/18
to ns-3-users
Hi Jaume, i was running your code  but "/NodeList/*/DeviceList/*/Phy/State/RxOk" trace is not being generated, i have just removed "theta" and "Rho" from node position ns3::RandomDiscPositionAllocator as they were generating error as msg="Invalid value for Theta" and msg="Invalid value for Rho" only "X and "Y" values are set. 
Reply all
Reply to author
Forward
0 new messages