Obtaining Differential Drive Pose -- a definitive answer

I know this has been discussed previously, but I spent a good 6 hours last night mulling over forum posts, desperately trying to get this to work, and still no luck.

I need to obtain the pose information from a simulated differential drive. It looks like the simulator does not update this data, as the state always returns the position as 0,0,0 and rotation at 180 deg.

One post on here suggests that perhaps this is a matter of just enabling the DoCompletePhysicsUpdate flag for the differential drive entity. I've tried this with no luck.

I've also tried using Trevor T's simulated differential drive (SimulatedDifferentialDriveTT.Y2007.M06.dll) by replacing the contract identifier for the differential drive in my manifest with the one for the TT drive and making changes in my service lookup accordingly. However for reasons I don't fully understand this doesn't work -- the service is never found when I do a directory lookup after launching the simulation. Anyway I'm not entirely sure that I'm even on the right track here... I get the feeling that it's not as simple as swapping the existing simulated drive for trevor's.

Finally, there have been a few suggestions posted here (namely by Kyle) saying that I may be able to retrieve the differential drive's pose by querying the simulation engine itself. Could someone explain how to do this in more detail? Kyle only briefly touched on it, and I can't quite understand how to fit the brief code snippet he posted into my code. In particular, if this is the way to do it, I'd like to know how to 1) subscribe to the differential drive entity in such as way as to receive state updates (presumably on a timer?) and 2) what fields within this entity or within its received state to look into.

Thanks,
Matt.

[1795 byte] By [MattZukowski] at [2008-1-10]
# 1

It's definitly possible to get the position. I try to describe how I do this.

First I have a class MyBot derived from Microsoft.Robotics.Simulation.Engine.DifferentialDriveEntity similar to the examples of the pioneer or iRobot create. In fact I c&p it from the pioneer3dx and changed mass, dimension etc. to my needs. I put this bot in a simulated world as it is done in simulation tutorial 2 with a little change. I have an instance of this MyBot class as private member of the simulation service class (the one which is there called SimulationTutorial2) and I am able to access this instance from within this "simulation service".

The bad news: there is no subscription port of the simulation engine or differential drive which notifies you every n millisecond about the current position. You have to implement your own timer to request this values periodically. The next question is where to request. My first idea was to get the state of the simulation enginge. As you can see on http://localhost:50000/simulationengine the state contains much information about all (!) serialized (!) entities in the simulation, also the position of your bot entity which is in fact the position of the DifferentialDriveEntity base class. I assume to get it on this way is a bad idea because serialization of all entities in simulation can possible consume much time.

My idea is to save all values I'm interested in in the state of my simulation service and get it from there. Since I have this instance of MyBot it's no problem to expand the get handler:

Code Snippet

[ServiceHandler(ServiceHandlerBehavior.Concurrent)]

public virtual IEnumerator<ITask> GetHandler(pxbotenvsim.Get get)

{

UpdateStateFromSimulation();

get.ResponsePort.Post(m_state);

yield break;

}

As you can see I have a additional method:

Code Snippet

void UpdateStateFromSimulation()

{

m_state.BotPosition = m_powerBot.Position;

}

That's all, hope that helps.

AlexanderDahl at 2007-10-3 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 2

Matt,

Look at the SimulatedDifferentialDrive service source code. It subscribes to the SimulationEngine service with an entity name (or a partner list entry) and it receives a notification which is a reference to the entity. If the service is running on the same node as the simulation engine, this is a reference to the actual entity in the simulation engine. The State.Pose of the entity is updated each frame in the simulation engine so all your service needs to do is look at that field on the entity to determine the position and orientation of the entity at any time.

-Kyle

KyleJ-MSFT at 2007-10-3 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...
# 3

Hi Matt,

Just a quick note about my version of the simulated differential drive.

The generic diffential drive does not have a pose and I did not want to create an incompatible contract.

So what I did was grab the pose (as explained by Kyle) and stuff it into the pose on the wheels every time that there is a frame update in the simulator. Then you can get the state of the diff drive and look in the wheels for the actual pose. Of course, constantly getting the state of the diff drive is an overhead :-(

Strictly speaking this approach is not correct because the wheels are offset from the center of the diff drive (by half of the wheel base), but I could not be bothered figuring out the geometry because I want the center of the drive anyway. If you did have the correct pose of the two wheels, you would have to calculate the centre of the axle between them by averaging the coordinates. The orientation of the two wheels will always be the same anyway.

I don't understand why your service could not find my version of the diff drive. The ExplorerSim uses it.

Trevor

TrevorTaylor at 2007-10-3 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Simulation...

Microsoft Robotics Studio

Site Classified