Instant Veins 4.7-i1 Localization Time of Arrival - omnet++

I am a masters student working on localization, using ranging (time of arrival between vehicle and RSU) and relative location (Using emulated Inertial Navigation System).
I have done an implementation of my kalman filter based localization logic on Matlab, now I would like to implement this on veins. I want only the RSU to send out a message comprising of its location and ID
1) I know that i can use
double Coord = mobility->getCurrentPosition().x;
double Coord = mobility->getCurrentPosition().y;
to the location of RSU(and my vehicle as well), I do not understand how I should assign these coordinates to the message. I cannot use sstream since I understand that the message are supposed to be of type const char *
Thanks for any input
Edit 1: So this is what my new code on RSU looks like:
#include "RsuScOne.h"
#include <sstream>
Define_Module(RsuScOne);
void RsuScOne::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
//Initializing members and pointers of your application goes here
//WaveShortMessage* wsm = new WaveShortMessage();
EV << "Initializing " << std::endl;
}
else if (stage == 1) {
//Initializing members that require initialized other modules goes here
}
}
void RsuScOne::finish() {
BaseWaveApplLayer::finish();
//statistics recording goes here
cancelEvent(sendWSAEvt);
}
void RsuScOne::onWSM(WaveShortMessage* wsm) {
//Your application has received a data message from another car or RSU
//code for handling the message goes here, see TraciDemo11p.cc for examples
populateWSM(wsm);
std::stringstream ss;
ss<<mobility->getCurrentPosition().x<<mobility->getCurrentPosition().y;
wsm->setWsmData(ss.str().c_str());
scheduleAt(simTime()+par("beaconInterval").doubleValue(), sendWSAEvt);
EV<<wsm;
}
void RsuScOne::handleSelfMsg(cMessage* msg) {
BaseWaveApplLayer::handleSelfMsg(msg);
}
But I realize that all that being done now is my RSU constantly sending a generic BSM, Why is this so?

Related

How to make one node communicate with multiple nodes?

I am trying to make my nodes communicate among themselves without changing any data in the message.
Like node one and two echos tictocMsg with themselves node two and three echos the different message in this case rndMsg.
How ever this did not work with me.
simple Txc1
{
gates:
input in1;
input in2;
output out1;
output out2;
}
//
// Two instances (tic and toc) of Txc1 connected both ways.
// Tic and toc will pass messages to one another.
//
network Tictoc1
{
#display("bgb=628,433");
submodules:
tic: Txc1 {
#display("p=264,321");
}
toc: Txc1;
rnd: Txc1 {
#display("p=474,100");
}
connections allowunconnected:
toc.out1 --> tic.in1;
tic.out1 --> toc.in1;
toc.out2 --> rnd.in1;
rnd.out1 --> toc.in2;
}
I want to make toc node to send tictocMsg to tic node only and rndMsg to rnd node only
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
/**
* Derive the Txc1 class from cSimpleModule. In the Tictoc1 network,
* both the `tic' and `toc' modules are Txc1 objects, created by OMNeT++
* at the beginning of the simulation.
*/
class Txc1 : public cSimpleModule
{
protected:
// The following redefined virtual function holds the algorithm.
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
// The module class needs to be registered with OMNeT++
Define_Module(Txc1);
void Txc1::initialize()
{
// Initialize is called at the beginning of the simulation.
// To bootstrap the tic-toc-tic-toc process, one of the modules needs
// to send the first message. Let this be `tic'.
// Am I Tic or Toc?
if (strcmp("tic", getName()) == 0) {
// create and send first message on gate "out". "tictocMsg" is an
// arbitrary string which will be the name of the message object.
cMessage *msg = new cMessage("tictocMsg");
send(msg, "out1");
}
if (strcmp("rnd",getName())==0){
cMessage *msg = new cMessage("rndMsg");
send(msg, "out1");
}
}
void Txc1::handleMessage(cMessage *msg)
{
// The handleMessage() method is called whenever a message arrives
// at the module. Here, we just send it to the other module, through
// gate `out'. Because both `tic' and `toc' does the same, the message
send(msg,"out1");
// send out the message
}
I have tried to change it to
send(msg,"in1","out1") ;
send(msg,"in2","out2") ;
tried
send(msg,out1)}
else{
send(msg,out2)}
}
by far both did not work for me is there any way to make it happen?
The node in the middle (i.e. toc) has to somehow recognize received messages. For example it may check the name of the message. Let's assume that:
toc after receiving message with the name tictocMsg sends it to tic,
toc after receiving message with the name rndMsg sends it to rnd,
tic and rnd after receiving message send it to toc.
The following piece of code performs the above rules:
void Txc1::handleMessage(cMessage *msg) {
if (isName("toc")) {
if (msg->isName("tictocMsg")) {
send(msg,"out1");
} else if (msg->isName("rndMsg")) {
send(msg,"out2");
}
} else {
// other nodes just sends this message back
send(msg,"out1");
}
}

The external ID of wsm message sender

I am using OMNET 5.0, SUMO-0.25.0 and VEINS-4.4. When a vehicle receive a message; onData() is called. I can get external ID of the current vehicle using mobility->getExternalId(); but how I know the the external ID of wsm message sender
The code for initialize():
void TraCIDemo11p::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
mobility = TraCIMobilityAccess().get(getParentModule());
traci = mobility->getCommandInterface();
traciVehicle = mobility->getVehicleCommandInterface();
annotations = AnnotationManagerAccess().getIfExists();
ASSERT(annotations);
getExternalID = mobility->getExternalId();
sentMessage = false;
lastDroveAt = simTime();
findHost()->subscribe(parkingStateChangedSignal, this);
isParking = false;
sendWhileParking = par("sendWhileParking").boolValue();
}
}
The code for onData():
void TraCIDemo11p::onData(WaveShortMessage* wsm) {
std::cout << " I am "<< getExternalID <<"and I received a message from ???? "<<endl;
findHost()->getDisplayString().updateWith("r=16,green");
annotations->scheduleErase(1, annotations->drawLine(wsm->getSenderPos(), mobility->getPositionAt(simTime()), "blue"));
if (mobility->getRoadId()[0] != ':')
traciVehicle->changeRoute(wsm->getWsmData(), 9999);
if (!sentMessage)
sendMessage(wsm->getWsmData());
}
A vehicle can be represented by two identifiers, either that one gotten from SUMO (i.e., calling getExternalId()) or that one of veins (myId normally), the one used in WaveShortMessage after calling getSenderAddress() is myId so I suggest that you focus on that last one.
Take a look on these two files to get a better idea on the used identifier and the existing methods: "BaseWaveApplLayer.h/.cc" & "WaveShortMessage_m.h/.cc"
I hope this helps.

How do I build a string from individual characters over BLE HC-08?

I am testing a BLE module (HC-08), which looks like a UART to the Arduino Uno.
This should be simple, but I have spent hours trying to build a string or char array from the response from commands sent over the software serial port.
first, here's the code:
#include <SoftwareSerial.h>
int data = 0;
SoftwareSerial Blue(10, 11); // RX, TX
void setup() {
Serial.begin(115200);
Blue.begin(9600);
Serial.println("BLE_Test started");
}
void loop() {
Blue.write("AT+VERSION?");
if (Blue.available()) {
data = Blue.read();
Serial.write(data);
}
delay(50);
}
And here's the output:
BLE_Test started
OK:SH-V1.251
OK:SH-V1.251
OK:SH-V1.251
OK:SH-V1.251
Each line ends with a CR-LF (13,10), so it looks fine on the screen.
So, here's my problem.
How can I build a string or char array out of the bytes coming from the BLE module? My goal is to make a function that simply sends a command string to the BLE module and return a string from the function. (Similar to Serial.readstring(), but SoftwareSerial has no readstring() property).
Like I said, it should be straightforward, but I am getting nowhere. Any tips would be appreciated.
it is readString with capital S and it is implemented in Stream which is a common base class for Serial implementations and SoftwareSerial and many other classes like LCD, EthernetClient, WiFiClient, ...
Doh!
That works, here's my working code:
//Send the command to the BLE module, returns with response in global inData
void getBlue(char* blueCmd) {
inData = "";
Blue.write(blueCmd);
delay(15);
while (Blue.available() > 0)
{
inData = Blue.readString();
}
}

Pulse sensor coding for Netduino Plus 2 gone wrong

I'm currently doing a project on Netduino Plus 2 using .net micro framework which requires me to code for a pulse sensor. I have tried finding codes for pulse sensor but to no avail. I tried using AnalogInput codes for pulse sensor but the output values seemed wrong (there was a constant high value despite no heartbeat placed near the sensor). Please advise!
Here are my current codes for the heartbeat sensor:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
namespace heartrate
{
public class Program
{
public static void Main()
{
SecretLabs.NETMF.Hardware.AnalogInput rate =
new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0);
int sensorvalue = 0;
while (true)
{
sensorvalue = rate.Read();
Debug.Print("" + sensorvalue);
Thread.Sleep(1000);
}
}
}
}
Here are the specs of the sensor, how it looks like and how it is connected.
http://www.elecrow.com/wiki/index.php?title=Pulse_Sensor
(This tutorial is for arduino, but I think the wiring is similar to that of Netduino)
Hard to tell without specs on your pulse device and how it is attached. For Analog input & output in my latest project (https://github.com/osstekz/cncBuddy) I use classes InputPort & OutputPort (Microsoft.SPOT.Hardware)
ex:
public NESControllerAdapter(Cpu.Pin pinClk, Cpu.Pin pinLatch, Cpu.Pin pinData1/*, Cpu.Pin pinData2 = Cpu.Pin.GPIO_NONE*/) {
// Binds to all pins
this._outpClk = new OutputPort(pinClk, false);
this._outpLatch = new OutputPort(pinLatch, false);
this._inpData1 = new InputPort(pinData1, false, Port.ResistorMode.Disabled);
//if (pinData2 != Cpu.Pin.GPIO_NONE) this._inpData2 = new InputPort(pinData2, false, Port.ResistorMode.Disabled);
}
...then like your rate.Read(); loop
public int ButtonPressed() {
// Locks all parms
this._PinTick(this._outpLatch);
// Reads plug state value
for (int i = 0; i < CncBuddyShared.iTOTALNESCONTROLLERBUTTONS; ++i) {
// Read the value, if true return this index as the first pressed button
if (this._inpData1.Read() == false) return i;
// Selects the next value
this._PinTick(this._outpClk);
}
return NESCONTROLLER_PRESSEDBUTTOM_NONE;
}

Monitor and ReaderWriterLockSlim aren't working

I tried to implement a typical threading application where one thread asks a device is data is available, copies the data to its own memory and sends an event to the main thread that the data is available. The main thread copies the data to its own memory and displays it on the GUI.
For this I used Visual Studio 2012 and C++/CLI with Winforms.
There is a class “Work” which holds the thread method “checkDataIsAvailable”. The “Work” class implements an interface (rather an abstract class) with a delegate “OnRetrievedData” which works as event and calls “BeginInvoke” in “Form1” to have an asynchronous behavior. And there is a method “getData” where the main thread can get the data from the “checkDataIsAvailable” thread. Furthermore the “Work” class tries to get the data from the class “ValueGenerator” which could represents any real device. I identifies a critical section for the “data” in the “Work” class called “array^ m_Data;”. The problem is that neither the “Monitor” nor the “ReaderWriterLockSlim” work approach is working.
With “Monitor” the GUI has a delayed responding and many updates are missing.
With “ReaderWriterLockSlim” the application crashes.
And without saving the critical section the application works. But I don’t know the reason because I’m sure that the data must be saved.
I would like to simplify the source code and emphasize the important things.
Most important is the thread method:
System::Void Work::checkDataIsAvailable()
{
while ( ( Thread::CurrentThread->ThreadState & Threading::ThreadState::Running) == Threading::ThreadState::Running )
{
m_WaitForDoCheckDataIsAvailableHandle->WaitOne();
//Monitor::Enter(m_LockData);
m_rwlock->EnterWriteLock();
m_Data = m_ValueGenerator->getData();
m_rwlock->ExitWriteLock();
//Monitor::Exit(m_LockData);
if ( nullptr != OnRetrievedData)
{
OnRetrievedData();
}
}
}
Here you see the copy process from the "ValueGenerator" to the variable m_Data. In my eyes this is a critical section. Then the event "OnRetrievedData" will be send that the data is available.
This event will get the Form1:
System::Void Form1::OnAcquisitionUpdate()
{
if(this->InvokeRequired == true)
{
OnAcquisitionUpdateDelegate^ onAcquisitionUpdateDelegate = gcnew OnAcquisitionUpdateDelegate(this, &Form1::OnAcquisitionUpdate);
this->BeginInvoke(onAcquisitionUpdateDelegate);
//this->Invoke(onAcquisitionUpdateDelegate);
}
else
{
if ( nullptr != m_Work )
{
//Thread::Sleep(5000);
array<System::Int32>^ data;
m_Work->getData(data);
dataResult_label->Text = data->Length.ToString();
}
}
}
"Form1::OnAcquisitionUpdate" changes it to the main thread via "BeginInvoke" and calls again the "Form1::OnAcquisitionUpdate" but now "InvokeRequired" is false so the "Work" class be called to get the data from the main thread.
System::Void Work::getData(array<System::Int32>^% data)
{
//Monitor::Enter(m_LockData);
m_rwlock->EnterReadLock();
Console::WriteLine(" getData() -> Data length = {0}", m_Data->Length);
data = m_Data;
m_rwlock->EnterReadLock();
//Monitor::Exit(m_LockData);
}
Here I see the next critical section where the data will be copied for the caller Form1.
It would be nice if anybody could help in this case.
I found a solution with a bool flag. Th flag is called "System::Boolean m_bCanWriteData;" and will be used in "Work::checkDataIsAvailable()" and "Work::getData(...)" in this way.
System::Void Work::checkDataIsAvailable()
{
while ( ( Thread::CurrentThread->ThreadState & Threading::ThreadState::Running) == Threading::ThreadState::Running )
{
m_WaitForDoCheckDataIsAvailableHandle->WaitOne();
#ifdef Use_Monitor
Monitor::Enter(m_LockData);
#endif
#ifdef Use_RW_Lock
m_rwlock->EnterWriteLock();
#endif
if ( m_bCanWriteData )
{
m_bCanWriteData = false;
m_Data = m_ValueGenerator->getData();
debugOutput("Work::checkDataIsAvailable() -> Data length = " + m_Data->Length);
if ( nullptr != OnRetrievedData)
{
OnRetrievedData();
}
}
#ifdef Use_RW_Lock
m_rwlock->ExitWriteLock();
#endif
#ifdef Use_Monitor
Monitor::Exit(m_LockData);
#endif
}
}
System::Void Work::getData(array<System::Int32>^% data)
{
debugOutput("Work::getData() START");
#ifdef Use_Monitor
Monitor::Enter(m_LockData);
debugOutput("Work::getData() + Monitor::Enter");
#endif
#ifdef Use_RW_Lock
m_rwlock->EnterReadLock();
#endif
m_WaitForDoCheckDataIsAvailableHandle->Reset(); // Block the thread method.
debugOutput("Work::getData() -> Data length = " + m_Data->Length);
data = m_Data;
m_bCanWriteData = true;
if ( m_bIsRunning )
{
m_WaitForDoCheckDataIsAvailableHandle->Set(); // Start the thread method.
}
#ifdef Use_RW_Lock
m_rwlock->EnterReadLock();
#endif
#ifdef Use_Monitor
Monitor::Exit(m_LockData);
#endif
debugOutput("Work::getData() END");
}
As you see the writting into and reading out is controlled and it works for the Monitor.

Resources