Introduction
Tank Simulator is a software tool to simulate a battle Tank based on its vehicle dynamics. Vehicle dynamics allow simulations to contain parameters that most clearly approximate the dynamic performance of the vehicle. Tank Simulator is still under development and currently simulates only few vehicle parameters like weight, dimension, velocity, suspension and braking effects. The complete version will be one which will have all the vehicle parameters included and exhibits Track-Terrain interaction. The developmental activity uses a computational engine called Open Dynamics Engine (ODE), which is an industrial standard library to simulate articulated bodies. It provides interactive or real-time simulation. 3D Visual environment of the simulator uses a Graphics Library that is packaged with ODE. Functions have been added to this library to suit the application’s need. The complete software is packaged as an integrated environment in Visual C++.
Overall System Architecture
Interface & Graphics Module: These modules are packaged with ODE under the name drawstuff. It is basically a graphics library which provides function to simulate terrain, provide camera view, etc. The library has been customized to draw 3D tank body parts - wheels, idlers, sprocket-wheels, chassis, chain, & turret and other visual requirements of the simulator.
Simulation Module: This module is responsible for executing the simulation code, which involves creation of dynamic world, integration of tank body, parts using joints, collision handling, governing tank behavior, iterating the simulation loop and finally destroying the dynamic world. This module is built using Open Dynamic Engine (ODE).
How It Works
The graphics part of Tank simulator has been developed using OpenGL. However I will just explain only the simulation part of it which uses ODE. There are two things that are quite central to ODE - bodies and joints. Tank is an assembly of parts like chassis, wheels, turret, chain, etc. These parts are first drawn graphically and later provided with rigid body properties which can have mass and show collision properties. These bodies are then joined together using various types of joints available in ODE to form a complete Tank. Tank now just does not remain a 3D figure on the screen, but becomes a vehicle with physical properties. Here’s one part of code that shows it:
static void simLoop (int pause)
{
.
.
.
dSpaceCollide (space,0,&nearCallback); dWorldSetQuickStepNumIterations (world,85);
dWorldQuickStep (world,0.05); dsDrawTankBody(dBodyGetPosition(ChassisBody[0]),dBodyGetRotation(ChassisBody[0]),sides);
dsDrawTurret(dBodyGetPosition(TurretBody[0]),dBodyGetRotation(TurretBody[0]),sides);
.
.
.
}
int main (int argc, char **argv)
{
.
.
.
dMass m; dsFunctions fn;
.
.
fn.step = &simLoop; .
world = dWorldCreate();
space = dHashSpaceCreate (0); contactgroup = dJointGroupCreate (0);
dWorldSetGravity(world, 0,0,GRAVITY); ground = dCreatePlane (space,0,0,1,0); ChassisBody[0] = dBodyCreate (world);
dBodySetPosition (ChassisBody[0],0,0,STARTZ);
dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT);
dMassAdjust (&m,CMASS);
dBodySetMass (ChassisBody[0],&m);
ChassisBox[0] = dCreateBox (0,LENGTH,WIDTH,HEIGHT);
dGeomSetBody (ChassisBox[0],ChassisBody[0]);
.
.
TurretJoint[0] = dJointCreateHinge (world,0); dJointAttach (TurretJoint[0],ChassisBody[0],TurretBody[0]); const dReal *a1 = dBodyGetPosition (TurretBody[0]);
dJointSetHingeAnchor (TurretJoint[0],a1[0],a1[1],a1[2]);
dJointSetHingeAxis (TurretJoint[0],0,0,1);
dJointSetHingeParam (TurretJoint[0],dParamLoStop,0);
dJointSetHingeParam (TurretJoint[0],dParamHiStop,0);
dJointSetHingeParam (TurretJoint[0],dParamSuspensionERP,ERP);
.
.
.
}
The simulation module has been developed based on a Simulation Algorithm given in ODE. Please refer to ODE user guide for this. The algorithm starts with creation of a dynamic world in which simulation takes place then adding bodies into it, giving bodies parameters and then joining these bodies to form the vehicle, later on calling collision handler to determine any collision with other objects in the simulation environment and finally destroying the world. The main function explains exactly this. Using dWorldCreate
, we create a dynamic world then give this world a gravity of 9.81. We create a plain ground on which the tank moves. Using dBodyCreate
, we create bodies, set its position by dBodySetPosition
, mass by dBodySetMass
and then associate this body with the geometrical figure we have created using dGeomSetBody
. There are various types of joints supported by ODE like hinge joint, slider joint etc. dJointCreateHinge
creates a hinge joint. Joints are attached between two bodies by dJointAttach
. Other functions have been used to set various parameters of joint. Once dynamic world and bodies and joints are created to form the vehicle, a simulation loop simLoop
is called. The basic function of this simulation loop is to check for any collision and then advance the simulation given by its stepsize.
References
- Open Dynamics Engine v0.5 User Guide by Russell Smith.
- http://www.sourceforge.net provides CVS repositories for ODE and some ODE examples.
- You can refer to Heavy Vehicle Systems, Vol 9, Nov 2, 2002 by Corina Sandu and Jeffrey S. Freeman to understand Tank Vehicle Dynamics.
I have included a readme file with the source code that contains instructions to setup ODE on your system. Apart from this, I have included three source code folders that show simulator under different development stages. I am currently developing track terrain interaction of tank.