Removing entities sometimes doesn't work

Requests regarding how to set up experiments in ARGoS.
Elendurwen
Posts: 41
Joined: Sat Aug 24, 2013 5:08 pm
Contact:

Removing entities sometimes doesn't work

Postby Elendurwen » Tue Dec 10, 2013 4:01 pm

Hi,

I am running argos3 simulation where sometimes I need to remove an entity from a family of entity types. Rarely I get this error:

Code: Select all

[FATAL] CSpace::RemoveEntity() : Entity "pellet509" has not been found in the indexes.
which quits the application. I am not sure what I am doing wrong. Here is my code for how the entities are created:

Code: Select all

std::ostringstream pelletId; pelletId << "pellet" << pelletIdCounter; CBoxEntity* pellet = new CBoxEntity(pelletId.str(),CVector3(robotPosition + CVector3(0.1,0.1,0)),CQuaternion(),true,CVector3(0.1,0.1,0.1),0.1); AddEntity(*pellet); pellets.push_back(pellet); pelletIdCounter++;
where pellets is a vector of pointers to the CBoxEntities.

Then at some point later in the simulation, I randomly remove a pellet:

Code: Select all

if (pellets.size() > 0) { uint pelletId = uint(randNumGenerator->Uniform(CRange<Real>(0,pellets.size()-1))); //-- try if it still exists in space indexes CSpace::TMapPerType& pelletsInSpace = GetSpace().GetEntitiesByType("box"); CBoxEntity* pellet = any_cast<CBoxEntity*>(pelletsInSpace[pellets[pelletId]->GetId()]); if (pellet != NULL) { RemoveEntity(*pellet); } //-- remove from the array pellets.erase(pellets.begin()+pelletId); pellet = NULL; }
As you can see, I thought if I specifically double-check if the pellet can actually be found by trying to find it by its id between all box entities, it should be fine. Yet I still get the error. Is there a better way of doing this?

pincy
Site Admin
Posts: 632
Joined: Thu Mar 08, 2012 8:04 pm
Location: Boston, MA
Contact:

Re: Removing entities sometimes doesn't work

Postby pincy » Tue Dec 10, 2013 5:39 pm

Hi,

I tried the following code:

Code: Select all

randNumGenerator = CRandom::CreateRNG("argos"); CBoxEntity* b; for(size_t i = 0; i < 5000; ++i) { b = new CBoxEntity("b" + ToString(i), CVector3(0.1f + i * 0.2f, 0.1f, 0.0f), CQuaternion(), true, CVector3(0.1f, 0.1f, 0.1f), 0.1f); AddEntity(*b); pellets.push_back(b); fprintf(stderr, "[DEBUG] Added box '%s'\n", b->GetId().c_str()); }

Code: Select all

fprintf(stderr, "[DEBUG] \n[DEBUG] %d entities left\n", pellets.size()); if(! pellets.empty()) { UInt32 pelletId = randNumGenerator->Uniform(CRange<UInt32>(0,pellets.size())); CSpace::TMapPerType& pelletsInSpace = GetSpace().GetEntitiesByType("box"); CBoxEntity* pellet = any_cast<CBoxEntity*>(pelletsInSpace[pellets[pelletId]->GetId()]); if (pellet != NULL) { fprintf(stderr, "[DEBUG] Removing box '%s'...", pellet->GetId().c_str()); RemoveEntity(*pellet); fprintf(stderr, "done.\n"); } pellets.erase(pellets.begin()+pelletId); }
That is functionally equivalent to yours. The only (irrelevant) modification is:

Code: Select all

UInt32 pelletId = randNumGenerator->Uniform(CRange<UInt32>(0,pellets.size()));
that fixes a couple of bugs in the code you posted.

I tried this with multiple random seeds and 5000 boxes, and never managed to reproduce your problem :-(

Cheers,
Carlo
I made ARGoS.


Return to “How to... ?”