Closed zanouni closed 4 months ago
The field object
in ObjectContainer
refers to a EnvironmentModelObject
managed by the environment model. Just do not set this field if the object container shall include an object that is not tracked by the environment model at all.
The failing assertion seems to be unrelated to your modification. Possibly an invalid object
is dereferenced (maybe by your receiving service?) and thus triggering the assertion because of a memory violation.
Thank you @riebl After successfully adding the objects to the object container of each packet, do you have any ideas on how to make them appear in the simulation? Thank you again for your help!
If you want your fake objects to become detectable by sensors, you will need to extend the GlobalEnvironmentModel
accordingly. For example, you could track these artificial objects in a secondary ObjectDB
.
Hi @riebl I tried to create this function in GlobalEnvironmentModel.cc:
bool GlobalEnvironmentModel::addFakeVehicle(traci::VehicleController* vehicle, std::shared_ptr
And I used a new ObjectDB FakeObjects, then I added the fake object that I created using this function like this:
res = const_cast<GlobalEnvironmentModel*>(globalenv)->addFakeVehicle(&FakevehicleController, object.lock(), id);
But during the simulation, I encountered this error: libsumo::TraCIException: .. Answered with error to command (164), [description: Vehicle '100' is not known.] – in module artery::GVattackService, World.node[0].middleware.GVattackService (id=100), at t=0.334426574409s, event 13.
Do you know what causes this error? And thank you again.
Currently the EnvironmentModelObject
is quite tightly bound to SUMO, e.g. it depends on traci::VehicleController
. I suggest making EnvironmentModelObject
an interface class and moving all the TraCI specific code to a child class TraCIEnvironmentModelObject
. For your fake objects, you can then instantiate objects of another child class FakeEnvironmentModelObject
, which does not depend on TraCI/SUMO at all. This approach should avoid too many headaches.
Thank you @riebl So, with this solution, will the fake object appear on the network where the presence of other nodes and modules? This is actually the core idea of my project: to assess the behavior of valid existing nodes when they detect fake objects sent or created by a malicious node.
All objects registered at the GlobalEnvironmentModel
are supposed to be "real". So if "fake" means in your context that the object has no meaningful interpretation at all, it should be registered at the global model. However, refactoring the EnvironmentModelObject
is still useful then: Within the GlobalEnvironmentModel
we can then use TraCIEnvironmentModelObject
s while you can forge "malicious" objects (type named MaliciousEnvironmentModelObject
?).
Thank you, Mr. @riebl , once again. I've updated the project by incorporating the TraCIEnvironmentModelObject
and BaseEnvironmentModelObject
, as you suggested. Then, I attempted to create a fake object using the following function:
std::shared_ptr<traci::API> traciApi = Inicontroller->getTraCI();
if (traciApi) {
traci::PersonController FakePersonController(traciApi, idString);
FakePersonController.setSpeed(1.2 * Inicontroller->getSpeed());
std::shared_ptr<TraCIEnvironmentModelObject> Fobject = std::make_shared<TraCIEnvironmentModelObject>(&FakePersonController, id);
if (Fobject) {
// Create the fake position
artery::Position Fakeposition;
using Length = decltype(Fakeposition.x);
Length deltaX = 10 * boost::units::si::meter;
Length deltaY = id * boost::units::si::meter;
Fakeposition.x = Inicontroller->getPosition().x + deltaX;
Fakeposition.y = Inicontroller->getPosition().y + deltaY;
Fobject->mCentrePoint = Fakeposition;
bool res = const_cast<GlobalEnvironmentModel*>(globalenv)->addFObject(Fobject, id);
I've also added a function in the GlobalEnvironmentModel:
bool GlobalEnvironmentModel::addFObject(std::shared_ptr<TraCIEnvironmentModelObject> object, uint32_t id) {
const std::string& idString = std::to_string(id);
auto insertion = FObjects.emplace(object->getExternalId(), object);
if (insertion.second) {
auto box = boost::geometry::return_envelope<geometry::Box>(object->getOutline());
FakeObjectRtree.insert(FObjectRtreeValue { std::move(box), object });
}
ASSERT(FObjects.size() == FakeObjectRtree.size());
return insertion.second;
}
And here are the types and variables used:
using FObjectDB = std::unordered_map<std::string, std::shared_ptr<TraCIEnvironmentModelObject>>;
using FObjectRtreeValue = std::pair<geometry::Box, std::shared_ptr<TraCIEnvironmentModelObject>>;
using FObjectRtree = boost::geometry::index::rtree<FObjectRtreeValue, boost::geometry::index::quadratic<16>>;
FObjectDB FObjects;
FObjectRtree FakeObjectRtree;
And these modifications were integrated into the initialization function of the service:
globalenv = getFacilities().get_mutable_ptr<GlobalEnvironmentModel>();
if (globalenv != nullptr) {
auto vehicle = inet::findContainingNode(this);
auto mMiddleware = inet::getModuleFromPar<artery::Middleware>(par("middlewareModule"), vehicle);
Inicontroller = globalenv->getController(vehicle);
} else {
std::cerr << "Error: Global environment model is not valid." << std::endl;
}
Despite these modifications, the issue persists. I encountered the error libsumo::TraCIException: .. Answered with error to command (206), [description: Person '100' is not known] -- in module (artery::CollectivePerceptionMockService) World.node[0].middleware.CollectivePerceptionMockService (id=100), at t=0.334426574409s, after using the function like this: createGV(100); In the generatePacket function. If anyone has a solution, I would greatly appreciate it. Thank you once again.
Hi,
for better readability, you could post your code in tags or push your code to a fork on GitHub so it is easier to follow your code and also see its context.
Your error is thrown by SUMO which does not know the object you are referencing in a TraCI call.
traci::PersonController FakePersonController(traciApi, idString);
FakePersonController.setSpeed(1.2 * Inicontroller->getSpeed());
As far as I understand your code, here, you create a new controller for an SUMO object with some ID and then you try to set its speed in SUMO. If the ID is arbitrary, SUMO might throw this error.
As @awillecke has pointed out, you are (probably) forging some idString
which does not refer to an actual SUMO entity. This approach is prone to fail.
You should create FakeEnvironmentModelObject
objects and use these instead of TraCIEnvironmentModelObject
. So far, no FakeEnvironmentModelObject
class exists yet but you can easily create one by sub-classing BaseEnvironmentModelObject
.
You can entirely abandon the FakePersonController
by adding setter methods to FakeEnvironmentModelObject
which simply store length, width etc. in the member attributes of the object.
If I change the type of the fake objects, for example, like this:
std::shared_ptr
You only need a controller, if your object relates to an object in SUMO. In that case, you can instantiate a controller with the ID of a SUMO object, e.g. vehicle ID, and request its attributes and such.
In your case, I suppose, you want an object in the EnvMod that is unrelated to SUMO objects. In that case, you do not need nor want a controller. With @riebl changes, you can implement your own envmod object, by creating a new class, that inherits from BaseEnvironmentModelObject
and behaves like you want it to.
The GlobalEnvironmentModel
still handles EnvironmentModelObject
, but it is an interface class now. When implementing a FakeEnvironmentModelObject
that inherits from the BaseEnvironmentModelObject
and thus, implements the EnvironmentModelObject
interface, it should be possible to add your fake objects to mObjects
or create sensor trackings for fake trackings in sensors.
Hi @riebl and @awillecke ,
Thank you again for your help.
Now, after I've created the FakeEnvironmentModelObject and instantiated the fake object as a FakeEnvironmentModelObject like this:
std::make_shared
Using the function I've created in the global environment:
GlobalEnvironmentModel::addFObject(std::shared_ptr
If your fake objects are added successfully to the mObjects
and mObjectRtree
by your function, they should be detectable by any FovSensor
(c.f. FovSensor::detectObjects()
) or SeeThroughSensor
that is attached to a vehicle or RSU, if they are in range (and line of sight).
You can check if it works as you expect with a debugger or by equipping the EnvmodPrinter
service.
You could also use the Envmod visualizer in Omnet++ GUI. Here, you would have to enable the drawing feature with:
*.node[*].environmentModel.*.drawSensorCone = true
*.node[*].environmentModel.*.drawLinesOfSight = true
*.node[*].environmentModel.*.drawDetectedObjects = true
*.node[*].environmentModel.*.drawBlockingObstacles = true
Hi @riebl I am using CollectivePerceptionMockService. I am trying to add a static object to the object container in the generatePacket function. To initiate this object, I tried the following: std::weak_ptr object;
auto& vehicle = getFacilities().get_const();
std::unique_ptr uniqueObject = std::make_unique(&vehicle, id);
And then:
uniqueObject->mCentrePoint = position;
object = std::weak_ptr(std::shared_ptr(std::move(uniqueObject)));
CollectivePerceptionMockMessage::ObjectContainer objc;
objc.object = object;
objc.objectId = id;
objc.sensorId = 0;
objc.timeOfMeasurement = omnetpp::simTime();
After that, I used this function to add the newly created object: objectContainers1.emplace_back(...) Now, when I try to run my project, I encounter the following error: "ASSERT: Condition 'mController' does not hold in function 'getVehicleController' at //artery/src/artery/traci/VehicleMobility.cc:36 -- in module (artery::VehiclePositionProvider) World.node[0].vanetza[0].position (id=105), during network initialization."
Can you help me understand the problem or provide any other ideas to create the static object? Thank you.