Traffic modelling on ns-3 network Simulator - ns-3

I am trying to simulate traffic of voice, video, and data in order to check the differences between EDCF and traditional CSMA/CA.
I am using an on off helper based on the example of http://www.scielo.org.co/pdf/dyna/v84n202/0012-7353-dyna-84-202-00055.pdf
for the video but on setAttribute(“OffTime”, StringValue(“ns3::LogNormalRandomVariable[Mu=0.4026,Sigma=0.0352]”));
I get error 'Attribute value "0.4026,Sigma=0.0352" is not properly formatted'
Any ideas for the error or suggestions on how to model the three types of traffic?
Thanks for your time

I couldn't find the version of ns3 in your provided reference. Also, the reference paper was published in September 2017. I think, they have used ns3.26 probably.
So, I've tried with ns3.29 and couldn't reproduce the above error. I've got somewhat different error. But I could fixed it by putting a space before '['.
The second solution I found by using Mu and Sigma separately.
onoff.SetAttribute ("OffTime", StringValue("ns3::LogNormalRandomVariable[Mu=0.4026]"));
onoff.SetAttribute ("OffTime", StringValue("ns3::LogNormalRandomVariable[Sigma=0.0352]"));

a4arshad's answer's compile and run, but they are not correct. The reason a4arshad's solution does not work is that the second SetAttribute call sets the OffTime attribute as a LogNormalRandomVariable with Sigma=0.0352. The second call does not add to the existing LogNormalRandomVariable with Mu=0.4026. The second call overwrites the first one.
a4arshad also suggested putting a space between LogNormalRandomVariable and [, but that doesn't work either; this will just cause ns-3 to ignore all parameters.
The correct way to set the attribute as the linked paper is to delimit parameters using a pipe, |. You should do something like
onoff.SetAttribute("OffTime", StringValue("ns3::LogNormalRandomVariable[Mu=0.4026|Sigma=0.0352]"));
I don't know when ns-3 switched to using a pipe to instead of a comma, but I am using the most recent release version, ns-3.30.1.
You can use the following program to check whether setting an attribute worked. The last lines are the relevant ones; the rest is boilerplate to set up the simulation. In the last lines, we extract the Attribute from the Application, and print the Mu and Sigma values. Try commenting/uncommenting the correct/incorrect methods and look at the different outputs. According to the documentation of LogNormalRandomVariable, the default values of Mu and Sigma are 0 and 1, respectively.
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
// setting a LogNormalRandomVariable with multiple parameters as the OffTime
// of an OnOffApplication
// https://stackoverflow.com/questions/60791009
// Author: Sagar
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/applications-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("RandomVariableAttirbuteTest");
int
main(int argc, char *argv[]) {
NodeContainer nodes;
nodes.Create(2);
PointToPointHelper p2pLink;
NetDeviceContainer devices = p2pLink.Install(nodes);
InternetStackHelper stack;
stack.InstallAll();
// assign IP addresses to NetDevices
Ipv4AddressHelper address ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer ipInterfaces = address.Assign(devices);
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
// configure and install server app
int serverPort = 8080;
UdpServerHelper serverApp (serverPort);
serverApp.Install(nodes.Get(0));
Address serverAddress = InetSocketAddress(ipInterfaces.GetAddress(0), serverPort);
// configure and install client apps
OnOffHelper onoff ("ns3::UdpSocketFactory", serverAddress);
// incorrect (two separate SetAttribute calls)
// onoff.SetAttribute("OffTime", StringValue("ns3::LogNormalRandomVariable[Mu=0.4026]"));
// onoff.SetAttribute("OffTime", StringValue("ns3::LogNormalRandomVariable[Sigma=0.0352]"));
// also incorrect (adding a space)
// onoff.SetAttribute("OffTime", StringValue("ns3::LogNormalRandomVariable [Mu=0.4026,Sigma=0.0352]"));
// correct
onoff.SetAttribute("OffTime", StringValue("ns3::LogNormalRandomVariable[Mu=0.4026|Sigma=0.0352]"));
onoff.Install(nodes.Get(1));
// print Attirbutes to check if they were correctly set
Ptr<Application> app = nodes.Get(1)->GetApplication(0);
PointerValue pv;
app->GetAttribute("OffTime", pv);
Ptr<LogNormalRandomVariable> rv = pv.Get<LogNormalRandomVariable>();
NS_LOG_UNCOND("Mu = " << rv->GetMu());
NS_LOG_UNCOND("Sigma = " << rv->GetSigma());
return 0;
}

Related

(STM32) Wrinting into flash with HAL_FLASH_PROGRAM does not work

I am trying to write on the flash memory of an STM32L476RG with the HAL_FLASH_Program function but it always returns an error.
static FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PAGEError;
uint32_t Address = 0x080FFF10;
uint64_t data = 5;
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
/* Erase the user Flash area*/
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = Address;
EraseInitStruct.NbPages = 1;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
{
/*Error occurred while page erase.*/
HAL_FLASH_GetError ();
}
/*Write into flash*/
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, 0x1FFF7000, data);
if (status== HAL_OK)
{
printf("it works\n\r");
}
else
{
/* Error occurred while writing data in Flash memory*/
HAL_FLASH_GetError();
}
HAL_FLASH_Lock();
I tried to find wthe flash error code with the HAL_FLASH_GetError() function.
The error code I get is "168" (0xa8 in Hex) and I have no idea to what it corresponds.
My questions :
What error is the code 168 (0xa8 in Hex)
what do i need to change so that HAL_FLASH_Program works properly
The problem is how the fields in EraseInitStruct are being set. The HAL driver for some STM32 parts expects an address. However, the HAL library for the STM32L476 expects a page number.
typedef struct
{
uint32_t TypeErase; /*!< Mass erase or page erase.
This parameter can be a value of #ref FLASH_Type_Erase */
uint32_t Banks; /*!< Select bank to erase.
This parameter must be a value of #ref FLASH_Banks
(FLASH_BANK_BOTH should be used only for mass erase) */
uint32_t Page; /*!< Initial Flash page to erase when page erase is disabled
This parameter must be a value between 0 and (max number of pages in the bank - 1)
(eg : 255 for 1MB dual bank) */
uint32_t NbPages; /*!< Number of pages to be erased.
This parameter must be a value between 1 and (max number of pages in the bank - value of initial page)*/
} FLASH_EraseInitTypeDef;
So you need to set the page number correctly, and also specify which flash bank you are trying to erase:
EraseInitStruct.Banks = FLASH_BANK_2;
EraseInitStruct.Page = 255u;
It is good practice to check the result of all HAL function calls, and abort the operation if there is an error.
#Lundin brought up a good point about possibly being unable to erase / program the flash bank that you are running code from. This is an issue for some devices, but the reference manual for the STM32L476 (in section 3.3.5) says this is ok:
... during a program/erase operation to the Flash memory, any attempt to read the same Flash memory bank will stall the bus. The read operation will proceed correctly once the program/erase operation has completed.

I have a problem about YouTube API with ESP8266

I try to make youtube subscribe counter but it a problem with youtube api library here the error message
Arduino: 1.8.12 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"
The sketch name had to be modified.
Sketch names must start with a letter or number, followed by letters,
numbers, dashes, dots and underscores. Maximum length is 63 characters.
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp:95:11: error: DynamicJsonBuffer is a class from ArduinoJson 5. Please see arduinojson.org/upgrade to learn how to upgrade your program to ArduinoJson version 6
DynamicJsonBuffer jsonBuffer;
^
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp: In member function 'bool YoutubeApi::getChannelStatistics(String)':
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp:95:20: error: 'jsonBuffer' was not declared in this scope
DynamicJsonBuffer jsonBuffer;
^
C:\Users\Um Sythat\Documents\Arduino\libraries\arduino-youtube-api-master\src\YoutubeApi.cpp:97:10: error: 'ArduinoJson::JsonObject' has no member named 'success'
if(root.success()) {
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
Invalid library found in C:\Program Files (x86)\Arduino\libraries\libraries: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\libraries
Invalid library found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino
Invalid library found in C:\Program Files (x86)\Arduino\libraries\libraries: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\libraries
Invalid library found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\youtube_control_arduino
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
I already download youtube api library and arduino json library and import it to arduino ide I always get error from it i dont know why it gone like this someone who know please help me. I like to hear from you.
And here my code :
/*******************************************************************
* Read YouTube Channel statistics from the YouTube API *
* *
* By Brian Lough *
* https://www.youtube.com/channel/UCezJOfu7OtqGzd5xrP3q6WA *
*******************************************************************/
#include <YoutubeApi.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h> // This Sketch doesn't technically need this, but the library does so it must be installed.
//------- Replace the following! ------
char ssid[] = "xxx"; // your network SSID (name)
char password[] = "yyyy"; // your network key
#define API_KEY "zzzz" // your google apps API Token
#define CHANNEL_ID "UCezJOfu7OtqGzd5xrP3q6WA" // makes up the url of channel
WiFiClientSecure client;
YoutubeApi api(API_KEY, client);
unsigned long api_mtbs = 60000; //mean time between api requests
unsigned long api_lasttime; //last time api request has been done
long subs = 0;
void setup() {
Serial.begin(115200);
// Set WiFi to station mode and disconnect from an AP if it was Previously
// connected
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
// Attempt to connect to Wifi network:
Serial.print("Connecting Wifi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
IPAddress ip = WiFi.localIP();
Serial.println(ip);
}
void loop() {
if (millis() - api_lasttime > api_mtbs) {
if(api.getChannelStatistics(CHANNEL_ID))
{
Serial.println("---------Stats---------");
Serial.print("Subscriber Count: ");
Serial.println(api.channelStats.subscriberCount);
Serial.print("View Count: ");
Serial.println(api.channelStats.viewCount);
Serial.print("Comment Count: ");
Serial.println(api.channelStats.commentCount);
Serial.print("Video Count: ");
Serial.println(api.channelStats.videoCount);
// Probably not needed :)
//Serial.print("hiddenSubscriberCount: ");
//Serial.println(api.channelStats.hiddenSubscriberCount);
Serial.println("------------------------");
}
api_lasttime = millis();
}
}
I would ditch the libraray - it uses
#include <ArduinoJson.h>
and the error tells us whats wrong
error: DynamicJsonBuffer is a class from ArduinoJson 5 <=== you have probably version 6.x.x installed
which is a memory hog. Often one single function is used by libraries and the rest is useless. To solve your problem, you have to
downgrade ArduinoJson.h to version 5.13.5
The other reason I do not like it, breaking changes in nearly all major releases (real big breaking). So another option you have (if skilled enough) replace the ArduinoJson functions with
a lighter JSON library
or replace it with self written JSON functions - often a simple buffer and some char handling does the trick
Read the issues and PRs on github to inform yourself about missing updates and other problems. Development stopped March 2018 since then no adaption to the (breaking) changes in the youtube API

OpenNI 1.5::Could not run code from documentation

I am trying to run a sample code from the OpenNI 1.5 documentation.I have imported the library required XnCppWrapper.h so that I can use C++.The code has only one error on a particular variable "bshouldrun".I know that it should be declared as something but since I am new at this and the documentation does not contain anything above the main, I dont know what to declare it as..Please help!!
And thanks in advance.
#include <XnOpenNI.h>
#include <XnCppWrapper.h>
#include <stdio.h>
int main()
{
XnStatus nRetVal = XN_STATUS_OK;
xn::Context context;
// Initialize context object
nRetVal = context.Init();
// TODO: check error code
// Create a DepthGenerator node
xn::DepthGenerator depth;
nRetVal = depth.Create(context);
// TODO: check error code
// Make it start generating data
nRetVal = context.StartGeneratingAll();
// TODO: check error code
// Main loop
while (bShouldRun) //<-----------------------------**ERROR;bShouldRun Undefined**
{
// Wait for new data to be available
nRetVal = context.WaitOneUpdateAll(depth);
if (nRetVal != XN_STATUS_OK)
{
printf("Failed updating data: %s\n", xnGetStatusString(nRetVal));
continue;
}
// Take current depth map
const XnDepthPixel* pDepthMap = depth.GetDepthMap();
// TODO: process depth map
}
// Clean-up
context.Shutdown();
}
Here's what I did to run a sample from Visual Studio 2010 Express on Windows (8):
Opened the NiSimpleViewer.vcxproj VS2010 project from C:\Program Files (x86)\OpenNI\Samples\NiSimpleViewer
Edited OpenNI.rc to comment out #include "afxres.h" on line 10(might be missing this because I'm using Express version, not sure. Your machine might compile this fine/not complain about the missing header file)
Enabled Tools > Options > Debugging > Symbols > Microsoft Symbol Servers (to get past missing pdb files issue)
Optionally edit the SAMPLE_XML_PATH to "SamplesConfig.xml" rather than the default "../../../Data/SamplesConfig.xml", otherwise you need to run the sample executable from ..\Bin\Debug\NiSimpleViewer.exe by navigating to there rather than using the Ctrl+F5. A;so copy the SamplesConfig.xml file into your sample folder as you can see bellow
Here are a few images to illustrate some of the above steps:
You can also compile the NiHandTracker sample, which sounds closer to what you need.
So this explains the setup for OpenNI 1.5 which is what your question is about.
I've noticed your OpenNI 2 lib issue in the comments. It should be a matter of linking against SimpleHandTracker.lib which you can do via Project Properties (right-click project->select Properties) > Linker > Input > Additional Dependencies > Edit.
I don't have OpenNI2 setup on this machine, but assuming SimpleHandTracker.lib would be in OpenNI_INSTALL_FOLDER\Lib. Try a file search in case I might be wrong.

User triggered event in libevent

I am currently writing a multi-threaded application using libevent.
Some events are triggered by IO, but I need a couple of events that are triggered accross threads by the code itself, using event_active().
I have tried to write a simple program that shows where my problem is:
The event is created using event_new(), and the fd set to -1.
When calling event_add(), if a timeout struct is used, the event is later properly handled by event_base_dispatch.
If event_add(ev, NULL) is used instead, it returns 0 (apparently successful), but event_base_dispatch() returns 1 (which means no the event was not properly registered.)
This behavior can be tested using the following code and swapping the event_add lines:
#include <event2/event.h>
#include <unistd.h>
void cb_func (evutil_socket_t fd, short flags, void * _param) {
puts("Callback function called!");
}
void run_base_with_ticks(struct event_base *base)
{
struct timeval one_sec;
one_sec.tv_sec = 1;
one_sec.tv_usec = 0;
struct event * ev1;
ev1 = event_new(base, -1, EV_PERSIST, cb_func, NULL);
//int result = event_add(ev1, NULL);
int result = event_add(ev1, &one_sec);
printf("event_add result: %d\n",result);
while (1) {
result = event_base_dispatch(base);
if (result == 1) {
printf("Failed: event considered as not pending dispite successful event_add\n");
sleep(1);
} else {
puts("Tick");
}
}
}
int main () {
struct event_base *base = event_base_new();
run_base_with_ticks(base);
return 0;
}
Compilation: g++ sample.cc -levent
The thing is, I do not need the timeout, and do not want to use a n-years timeout as a workaround. So if this is not the right way to use user-triggered events, I would like to know how it is done.
Your approach is sound. In Libevent 2.0, you can use event_active() to activate an event from another thread. Just make sure that you use evthread_use_windows_threads() or evthread_use_pthreads() as appropriate beforehand, to tell Libevent to use the right threading library.
As for needing an extra event: in Libevent 2.0 and earlier, an event loop will exit immediately when there are no pending events added. Your best bet there is probably the timeout trick you discovered.
If you don't like that, you can use the internal "event_base_add_virtual" function to tell the event_base that it has a virtual event. This function isn't exported, though, so you'll have to say something like:
void event_base_add_virtual(struct event_base *);
// ...
base = event_base_new();
event_base_add_virtual(base); // keep it from exiting
That's a bit of a hack, though, and it uses an undocumented function, so you'd need to watch out in case it doesn't work with a later version of Libevent.
Finally, this method won't help you now, but there's a patch pending for future versions of Libevent (2.1 and later) to add a new flag to event_base_loop() to keep it from exiting when the loop is out of events. The patch is over on Github; it is mainly waiting for code review, and for a better name for the option.
I just got burned by this with libevent-2.0.21-stable. It is quite clearly a bug. I hope they fix it in a future release. In the meantime, updating the docs to warn us about it would be helpful.
The best workaround seems to be the fake timeout as described in the question.
#nickm, you didn't read the question. His example code uses event_new() like you described; there is a bug in libevent that causes it to fail when using a NULL timeout (but return 0 when you call event_add()).

C Callback in Objective-C (IOKIT)

I am trying to write some code that interacts with an USB device in Objective C, and I got stuck on setting the callback function for incoming reports. In my case it's an IOKIT function but I think the problem is more general as I (apparently) don't know how to correctly set a C callback function in Objective-C. I've got a Class "USBController" that handles the io functions
USBController.m:
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDLib.h>
#import "USBController.h"
static void Handle_IOHIDDeviceIOHIDReportCallback(
void * inContext, // context from IOHIDDeviceRegisterInputReportCallback
IOReturn inResult, // completion result for the input report operation
void * inSender, // IOHIDDeviceRef of the device this report is from
IOHIDReportType inType, // the report type
uint32_t inReportID, // the report ID
uint8_t * inReport, // pointer to the report data
CFIndex InReportLength) // the actual size of the input report
{
printf("hello"); //just to see if the function is called
}
#implementation USBController
- (void)ConnectToDevice {
...
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
...
}
...
#end
All the functions are also declared in the header file.
I think I did pretty much the same as what I've found here, but it doesn't work. The project compiles nicely and everything works up till the moment there is input and the callback function is to be called. Then I get an "EXC_BAD_ACCESS" error. The first three arguments of the function are correct. I'm not so sure about the context..
What did I do wrong?
I am not sure at all that your EXEC_BAD_ACCESS depends on your callback. Indeed, if you say that it is called (I suppose you see the log) and since it only logs a message, there should be no problem with this.
EXEC_BAD_ACCESS is caused by an attempt to access an already deallocated object. You can get more information in two ways:
execute the program in debug mode, so when it crashes you will be able to see the stack content;
activate NSZombies or run the program using the performance tool Zombies; this will tell you exactly which object was accessed after its deallocation.
I know how to fix this. When calling this:
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,(void*)self);
You don't include the code for the creation/type of the value called report. However the method name "Handle_IOHIDDeviceIOHIDReportCallback" comes from an Apple document where there is an error in the creation of the report value. https://developer.apple.com/library/archive/technotes/tn2187/_index.html
CFIndex reportSize = 64;
uint8_t report = malloc( reportSize ); // <---- WRONG
IOHIDDeviceRegisterInputReportCallback( deviceRef,
report,
reportSize,
Handle_IOHIDDeviceIOHIDReportCallback,
context );
Instead do this:
uint8_t *report = (uint8_t *)malloc(reportSize);