Count of nodes in an specific range - omnet++

I'm using veins 5 and I am trying to obtain the position of nodes around in a certain distance from a node. More specifically, I'm trying to get a mapping position of all nodes in an instant to work with the positions of the nodes.
I read this question How to get count of cars in specific range, however it centered in veins 4.6 and also I didn't get how to use the method suggested by Christoph Sommer. Is it possible to get the mapping in veins 5? How can I work this?
I'll appreciate any help
Thanks!

Finally I got the position of all nodes in the simulation and calculate their distance from a tagged car.
To do this I "translate" the answer of Ahmad Ahsan in the question How to get Coordinates of each vehicle in VEINS? to veins 5.0 in the following way:
void MessageGenerator::getMapping(){
// Get my position on the scenario
veins::Coord myPosition = mobility->getPositionAt(simTime());
EV << myPosition << endl;
// Get all available nodes in simulation
std::map<std::string, cModule*> allNodes = mobility->getManager()->getManagedHosts();
// Iterate through collection and find distance,
std::map<std::string, cModule*>::iterator it;
for(it = allNodes.begin(); it != allNodes.end(); it++)
{
TraCIMobility* auxMobility = TraCIMobilityAccess().get(it->second);
veins::Coord receiverPosition = auxMobility->getPositionAt(simTime());
//returns distance in meters
double dist = myPosition.distance(receiverPosition);
EV << "Distance: " << dist << endl;
}
}
The key change is in the getPositionAt(simTime()) method.
One additional comment, as discussed in this post the method of obtain all vehicles in simulation is a bad practice if this data is used for realistic simulation purposes, because it is rarely possible to obtain all positions in one time step. In my case, I used it for only evaluation purposes.

Related

OpenVR Teleportation Problem (Forward direction calculation)

So I am trying to implement teleportation in my VR application (not in Unity). I am able to get the pose matrices for each controller from
if (auto error = vr::VRInput()->GetPoseActionDataForNextFrame(hand[eHand].pose_handle, vr::TrackingUniverseStanding, &poseData, sizeof(poseData), vr::k_ulInvalidInputValueHandle) != vr::VRInputError_None
|| !poseData.bActive || !poseData.pose.bPoseIsValid)
{
std::cerr << "pose invalid " << error << std::endl;
}
else
{
hand[eHand].pose = ConvertSteamVRMatrixToMatrix4(poseData.pose.mDeviceToAbsoluteTracking);
}
I then use glm::decompose() to get the position and orientation (orientation must be conjugated). Then I try to get the forward direction from it by multiplying the orientation matrix by vec4(0,0,1,0) but the resultant vector is incorrect. Is there a flaw in my logic?
So it turns out I had a few issues with my methodology. Firstly, OpenVR defines the forward direction of the controllers as vec4(0,0,-1,0), and secondly, it is defined with respect to the HMD camera. In order to move around the scene, I use a second camera matrix for translation and rotation. Thus had to take this into account.
My final calculation is as follows
auto forward = glm::normalize(glm::inverse(nonHMDViewMat) *
vr.GetControllerPose(Right) * glm::vec4(0,0,-1,0));
Where vr.GetControllerPose(Right) returns the matrix in hand[eHand].pose for the right hand.

Keep the correct lane on road

I am trying to make a Traffic Simulator for my bachelor thesis.
I created a map with OpenStreetMap osm and now I am trying to put some cars on roads.
I created a graph for the roads. The graph is like this:
A->B,C,D
C->A,B,E
B->A,C
D->A
E->C
and I generate random the cars on random points A,B,C,D,E,F. After this I use function getShortestPath(start,end) to get the shortest path for every car and I put the cars to move:
foreach(Car c in allCars){
Move(c,path)
}
But, I have a problem, I don't know how to keep the correct lane of road for every car, all my cars are on the same lane of road.
I am thinking about the direction between two points and the car will be at the right side of the direction.
But I have no idea how to do this....
Thank you!
Here is my answer to update your movement and car code, taking into account our conversation in the comments.
Add a variable to your car class:
Class Car {
// your other variables
Vector3 progressPosition; // This will only be set to the from nodes position whenever you get a new path.
}
Your update code will be like this:
void UpdateCarMethod()
{
car.car.progressPosition = Vector3.MoveTowards(car.car.progressPosition, car.path[car.index].point + lane, Time.deltaTime * speed);
car.car.transform.position = car.car.progressPosition + car.car.transform.right;
}

How to get Coordinates of each vehicle in VEINS?

I am using Veins 4.6, Sumo 0.25 and Omnet++ 5.2. I need to get the coordinates of two vehicles (nodes) at a given time, to calculate the distance between them.
I have tried to modify the TraCIDemo11p.cc file in the function handlePositionUpdate(). The Problem is when the veh0 returns its coordinate at the same time there is coordinate sent by veh1 which is very small.
How can I get the position of both the vehicles at the given time and find the distance between them?
void TraCIDemo11p :: handlePositionUpdate(cObject* obj) {
BaseWaveApplLayer::handlePositionUpdate(obj);
// Get vehicle ID
std::string vehID = mobility->getExternalId().c_str();
// Get coordinates of first vehicle
if (vehID == "veh0"){
firstVehX = mobility->getCurrentPosition().x;
firstVehY = mobility->getCurrentPosition().y;
firstVehZ = mobility->getCurrentPosition().z;
calculateDistance(vehID, firstVehX, firstVehY,firstVehZ);
}
//Get coordinates of second vehicle
if (vehID == "veh1"){
secondVehX = mobility->getCurrentPosition().x;
secondVehY = mobility->getCurrentPosition().y;
secondVehZ = mobility->getCurrentPosition().z;
calculateDistance(vehID, secondVehX, secondVehY, secondVehZ);
}
}
As far as I understood, you want to calculate the distance from the vehicle this code is running on to some other car. However, I am not sure what this other vehicle is. Is it firstVeh for instance?
If this is the case, with this code you can not have achieve what you want (as you figured out already). This code runs on every vehicle in the simulation but is independent from all other vehicles. Therefore, mobility points only to the mobility module of the current vehicle this code is running on. Thus, mobility->getCurrentPosition() always gives you only the position of exactly this vehicle.
For calculating the distance to firstVeh for example, you need its coordinates. Usually, however, you do not have any knowledge about arbitrary other vehicles in the simulation, unless you receive a message from them which includes its position (see Calculating distance between cars nodes VEINS).
If you really need to calculate the distance to an other, arbitrary vehicle (i.e. not an aforementioned sender of a message), you could get a pointer to that vehicle from the TraCIScenarioManager (see How to get count of cars in specific range). This, however, is bad practice in my opinion, since in reality you would not be aware of any other cars in the scenario, other than some sender of a message, either.
On sink node you can get list of all modules in simulation, access their coordinates and then find the distance between them using following snippet in handlePositionUpdate method of TraCIDemo11p.cc:
//Get current position of the node which is going to send message
Coord senderPosition = mobility->getCurrentPosition();
//Get all available nodes in simulation
std::map<std::string, cModule*> availableCars = mobility->getManager()->getManagedHosts();
//Iterate through collection and find distance,
std::map<std::string, cModule*>::iterator it;
for(it = availableCars.begin(); it != availableCars.end(); it++)
{
TraCIMobility* mobility1 = TraCIMobilityAccess().get(it->second);
Coord receiverPosition = mobility1->getCurrentPosition();
//returns distance in meters
senderPosition.distance(receiverPosition)
}
Ref: How to get count of cars in specific range

How to move a SCNNode in the direction it is pointing at after an rotation is applied

My dilemma is this:
I have a spaceship positioned somewhere in space between stars and planets. The camera is added as a child of the spaceshipNode and you always look at the back of the spaceship (raised a few units above).
I use CoreMotion to rotate the spaceship like this:
func startMonitoringMotion() {
self.motionManager?.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: { (data, error) in
guard let data = data else { return }
let attitude: CMAttitude = data.attitude
self.ship.eulerAngles = SCNVector3Make(Float(attitude.roll - M_PI_2), Float(attitude.yaw), Float(attitude.pitch))
})
}
and the rotation works as expected.
Now I want to move the spaceship in the direction it is facing but I have no clue how to do it. I have tried different approaches but I have failed miserably.
I have searched this forum countless times for several days but with no luck.
I hope someone can point me (and my spaceship) in the right direction.
Thank you in advance.
I've found that the easiest way to do this is to grab the third row of the node's worldTransform property, which corresponds to its z-forward axis.
func getZForward(node: SCNNode) -> SCNVector3 {
return SCNVector3(node.worldTransform.m31, node.worldTransform.m32, node.worldTransform.m33)
}
ship.position += getZForward(ship) * speed // nb scalar multiply requires overload of * func
// if node has a physics body, you might need to use the presentationNode, eg:
// getZForward(ship.presentationNode)
// though you probably don't want to be directly modifying the position of a node with a physics body
See the discussion here Getting direction that SCNNode is facing
iOS 11 update
iOS 11 adds handy convenience functions for getting the orientation of a node. In this case the worldForward property is the one you want. Also, all of the properties on SCNNode that return SCNVector and matrix types now have versions that return simd types. Because simd already has overloads for the arithmetic operators, you no longer need to add sets of arithmetic overrides for the SCNVector and SCNMatrix types.
So we can get rid of out getZForward method above, and just have the line:
ship.simdPosition += ship.simdWorldFront * speed

Random World Generation

I'm starting to go into random world generating, I have an idea on how random number generating works (Actually pseudorandom numbers), but I don't have a good idea of how to make the world look "nice", in other words not just place blocks based on a random x, y that it gives me, but make it look smooth.
This will be a 1 time generation per world. So everything is created at start.
I was thinking of an algorithm a few moments ago, but the problem is that it would just use be an endless amount of nested if loops, which would probably take a more than the necessary time. I was thinking of the following:
Choose a random location on the map and place the spawn point in that location.
Start building the street based on the spawn location, like if the spawn location is 16
spaces near the edge of the world build a house, otherwise start building a street.
Based on the previously generated street's place structures around.
Place misc.
Conceptualizing the algorithm isn't much of a problem, what I'm having difficulty with is starting the actual code from step 2 and below. Based on the above algorithm or an algorithm you think of, how would you start the code? I'm not asking for the actual code to be made, just an idea of how it would look.
I know this question isn't precise and can have multiple answers, but I've seen many questions similar to this one having a strange approach.
hmm looks like planar(or cubic) map filling. from my point of view firstly you need some databases
struct _object
{
string name,help,info; // texts for later use
int siz[3]; // grid size of object
int pos[3]; // placement pos (center or what ever)
// other stuff like: mesh-id,color,hit points,...
};
struct _dependency
{
int objid
List<int> near; // can be near this objects (can add probability)
List<int> far; // cannot be near this objects (can add probability,min distance)
};
List<_object> object; // DBS of all object types
List<_dependency> depend; // DBS of object dependency
Then you need to initialize this DBS from ini files or whatever. After that you need to create world map. For simplicity let it by only a single squared town and single layer(no sub-terrain), size and placement can be random.
List<_object> obj; // DBS of placed objects, could be lesser derivate of previous _object to conserve memory requirements
const int N=100;
int[N][N] map; // placement map, containing placed obj id, or -1 for empty space
so now you need some town generating function that fills map[N][N]:
void genere()
{
int i,j,x,y,xx,yy,objid,objix;
int _min_complexity=N/10; // this can also be random
int _max_complexity=N; // this can also be random
// clear map
for (i=0;i<N;i++)
for (j=0;j<N;j++)
map[i][j]=-1;
int complexity=_min_complexity+random(_max_complexity-_min_complexity);
for (i=0;i<complexity;)
{
// random placenet position
x=random(N);
y=random(N);
// random object, should take in mind object[].near and closest objects in map[y][x]
objid=random(object.num);
if (check if map[][] is empty enough to place object[objid] to x,y,z)
if (check if near x,y position is not bad type of object already object[].far)
{
// add new object to list
objix=obj.add(object[objid]);
// add new object to map
int *siz=obj[objix].siz
int *pos=obj[objix].pos
x+=pos[0];
y+=pos[1];
for (yy=0;yy<siz[1];yy++)
for (xx=0;xx<siz[0];xx++)
map[y+yy][x+xx]=objid;
i++;
}
}
}
also the position can be double[3] + orientation matrix and map coordinates will than be aligned to grid. There are many ways to tweak this code, its just an starting template. Hope it helps a little.
P.S.
List<type> l;
l.num - number of items in list
l[i] - i item from list
i=l.add(a) - add new item a to list and returns its index

Resources