Simple Vehicle Class

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Simple Vehicle Class

Postby pHySiQuE » Sat Sep 13, 2014 8:13 pm

I'm trying to make sense of Julio's awesome but confusing vehicle code, and simplify the usage. This has not been tested, but it compiles and runs without crashing.

Usage
Code: Select all
   NewtonBody* newtonbody = ???

   NewtonVehicle* vehicle = new Vehicle(newtonbody);

   vehicle->AddTire(-2, 0, 2, 1, 1, 1, true);
   vehicle->AddTire(2, 0, 2, 1, 1, 1, true);
   vehicle->AddTire(-2, 0, -2, 1, 1, 1, false);
   vehicle->AddTire(2, 0, -2, 1, 1, 1, false);

   vehicle->AddAxle(0, 1);
   vehicle->AddAxle(2, 3);

   vehicle->Build()


NewtonVehicle.h
Code: Select all
#include "Leadwerks.h"

class NewtonVehicle
{
   CustomVehicleControllerManager* manager;
   CustomVehicleController* vehicle;
   std::vector<CustomVehicleControllerBodyStateTire*> tire;
   CustomVehicleControllerComponentSteering* steering;
   CustomVehicleControllerComponentBrake* brakes;
   CustomVehicleControllerComponentEngine::dGearBox* gearbox;
   CustomVehicleControllerComponentEngine* engine;
   std::vector<float> forwardGearRatio;
   float reverseGearRatio;
   CustomVehicleControllerComponentEngine::dMultiAxelDifferential* differencial;
   std::vector<int> axle;
   std::vector<CustomVehicleControllerComponentEngine::dSingleAxelDifferential*> newtonaxles;
   float topSpeedKPH, idleTorquePoundPerFoot, idleRPM, peakTorquePoundPerFoot, peakTorqueRPM, peakHorsePower, peakHorsePowerRPM, redLineTorquePoundPerFoot, redLineRPM;
   
   //Destructor
   ~NewtonVehicle();

public:

   //Constructor
   NewtonVehicle(NewtonBody* newtonbody);

   //Tires
   int AddTire(float x, float y, float z, float mass, float radius, float width, bool steering, float suspensionDamper = 200.0, float suspensionSpring = 2000.0, float suspensionLength = 1.2, float lateralStiffness = 20.0, float longitudinalStiffness = 100000.0, float aligningMOmentTrail = 1.5);
   void AddAxle(int lefttire, int righttire);

   //Optional settings
   void SetGearRatio(std::vector<float> forwardGearRatio, float reverseGearRatio);
   void SetTorqueCurve(float topSpeedKPH, float idleTorquePoundPerFoot, float idleRPM, float peakTorquePoundPerFoot, float peakTorqueRPM, float peakHorsePower, float peakHorsePowerRPM, float redLineTorquePoundPerFoot, float redLineRPM);

   //Build
   bool Build();
   NewtonBody* GetBody();

   //Control
   void SetAcceleration(float engineGasPedal);
   void SetSteering(float steering);
   void SetBrakes(float brakes);
   void SetHandBrakes(float brakes);
   void SetGear(int gear);
   void SetTransmissionMode(bool automatic);

   //Information
   void GetTireMatrix(int tireindex, float* matrix);
   int GetGear();
   float GetRPM();
   float GetSpeed();
};


NewtonVehicle.cpp
Code: Select all
#include "NewtonVehicle.h"

NewtonVehicle::NewtonVehicle(NewtonBody* newtonbody) : manager(NULL), vehicle(NULL)
{
   const float maxsteerangle = 25.0f;
   const float braketorque = 10000.0f;

   CustomVehicleControllerManager* manager = new CustomVehicleControllerManager(NewtonBodyGetWorld(newtonbody));
   float gravity[3] = { 0.0, -1.0, 0.0 };
   float mass = 10;
   float mat[16] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };

   vehicle = manager->CreateVehicle(newtonbody, mat, gravity);
   
   //Create steering
   steering = new CustomVehicleControllerComponentSteering(vehicle, maxsteerangle * 3.141592f / 180.0f);

   //Create brakes
   brakes = new CustomVehicleControllerComponentBrake(vehicle, braketorque);

   //Setup default gear ratio
   reverseGearRatio = 2.9;
   forwardGearRatio.push_back(2.5);
   forwardGearRatio.push_back(2.0);
   forwardGearRatio.push_back(1.5);

   //Default torque values
   topSpeedKPH = 72.0;
   idleTorquePoundPerFoot = 1300.0;
   idleRPM = 500.0;
   peakTorquePoundPerFoot = 2000.0;
   peakTorqueRPM = 3000.0;
   peakHorsePower = 1200;
   peakHorsePowerRPM = 4000.0;
   redLineTorquePoundPerFoot = 300.0;
   redLineRPM = 4500;
}

NewtonVehicle::~NewtonVehicle()
{
   if (vehicle)
   {
      manager->DestroyController(vehicle);
      vehicle = NULL;
   }
   delete manager;
}

NewtonBody* NewtonVehicle::GetBody()
{
   return vehicle->GetBody();
}

void NewtonVehicle::GetTireMatrix(int tireindex, float* matrix)
{
   const dMatrix& tireMatrix = tire[tireindex]->GetLocalMatrix();
   memcpy(matrix, &tireMatrix, sizeof(float)* 16);
}

void NewtonVehicle::SetAcceleration(float engineGasPedal)
{
   engine->SetParam(engineGasPedal);
}

void NewtonVehicle::SetSteering(float steeringVal)
{
   steering->SetParam(steeringVal);
}

void NewtonVehicle::SetBrakes(float brakePedal)
{
   brakes->SetParam(brakePedal);
}

void NewtonVehicle::SetHandBrakes(float brakePedal)
{
   CustomVehicleControllerComponentBrake* const handBrakes = vehicle->GetHandBrakes();
   handBrakes->SetParam(brakePedal);
}

int NewtonVehicle::AddTire(float x, float y, float z, float mass, float radius, float width, bool usesteering, float suspensionDamper, float suspensionSpring, float suspensionLength, float lateralStiffness, float longitudinalStiffness, float aligningMOmentTrail)
{
   CustomVehicleControllerBodyStateTire::TireCreationInfo tireInfo;
   tireInfo.m_location[0] = x;
   tireInfo.m_location[1] = y;
   tireInfo.m_location[2] = z;
   tireInfo.m_mass = mass;
   tireInfo.m_radio = radius;
   tireInfo.m_width = width;
   tireInfo.m_dampingRatio = suspensionDamper;
   tireInfo.m_springStrength = suspensionSpring;
   tireInfo.m_suspesionlenght = suspensionLength;
   tireInfo.m_lateralStiffness = lateralStiffness;
   tireInfo.m_longitudialStiffness = longitudinalStiffness;
   tireInfo.m_aligningMomentTrail = aligningMOmentTrail;

   CustomVehicleControllerBodyStateTire* newtontire = vehicle->AddTire(tireInfo);
   if (newtontire == NULL) return -1;
   tire.push_back(newtontire);
   
   //Add steering if desired
   if (steering) steering->AddSteeringTire(tire[tire.size() - 1], -1.0f);
   
   //Always add brakes
   brakes->AddBrakeTire(tire[tire.size()-1]);
   
   return tire.size() - 1;
}

void NewtonVehicle::SetGearRatio(std::vector<float> forwardGearRatio,float reverseGearRatio)
{
   this->forwardGearRatio = forwardGearRatio;
   this->reverseGearRatio = reverseGearRatio;
}

void NewtonVehicle::AddAxle(int lefttire, int righttire)
{
   axle.push_back(lefttire);
   axle.push_back(righttire);
}

void NewtonVehicle::SetTorqueCurve(float topSpeedKPH, float idleTorquePoundPerFoot, float idleRPM, float peakTorquePoundPerFoot, float peakTorqueRPM, float peakHorsePower, float peakHorsePowerRPM, float redLineTorquePoundPerFoot, float redLineRPM)
{
   this->topSpeedKPH = topSpeedKPH;
   this->idleTorquePoundPerFoot = idleTorquePoundPerFoot;
   this->idleRPM = idleRPM;
   this->peakTorquePoundPerFoot = peakTorquePoundPerFoot;
   this->peakTorqueRPM = peakTorqueRPM;
   this->peakHorsePower = peakHorsePower;
   this->peakHorsePowerRPM = peakHorsePowerRPM;
   this->redLineTorquePoundPerFoot = redLineTorquePoundPerFoot;
   this->redLineRPM = redLineRPM;
}

bool NewtonVehicle::Build()
{
   if (tire.size() < 2) return false;
   if (axle.size() == 0) return false;

   vehicle->SetSteering(steering);
   vehicle->SetBrakes(brakes);
   
   //Build axles / differential
   for (int i = 0; i < axle.size()/2; i++)
   {
      newtonaxles.push_back(new CustomVehicleControllerComponentEngine::dSingleAxelDifferential(vehicle, tire[axle[i*2+0]], tire[axle[i*2+1]]));
   }
   differencial = new CustomVehicleControllerComponentEngine::dMultiAxelDifferential(vehicle, newtonaxles.size(), &newtonaxles[0]);

   //Build gearbox
   gearbox = new CustomVehicleControllerComponentEngine::dGearBox(vehicle, reverseGearRatio, forwardGearRatio.size(), &forwardGearRatio[0]);
   
   //Build engine
   engine = new CustomVehicleControllerComponentEngine(vehicle, gearbox, differencial);
   engine->SetTransmissionMode(true);
   vehicle->SetEngine(engine);
   
   //Build Torque Curve
   engine->InitEngineTorqueCurve(topSpeedKPH, idleTorquePoundPerFoot, idleRPM, peakTorquePoundPerFoot, peakTorqueRPM, peakHorsePower, peakHorsePowerRPM, redLineTorquePoundPerFoot, redLineRPM);
   
   //Finalize vehicle
   vehicle->Finalize();
   
   return true;
}

int NewtonVehicle::GetGear()
{
   int gearid = engine->GetGear();
   if (gearid == CustomVehicleControllerComponentEngine::dGearBox::m_reverseGear) return -1;
   if (gearid == CustomVehicleControllerComponentEngine::dGearBox::m_newtralGear) return 0;
   return gearid - CustomVehicleControllerComponentEngine::dGearBox::m_firstGear + 1;
}

void NewtonVehicle::SetGear(int gearid)
{
   switch (gearid)
   {
   case -1:
      engine->SetGear(CustomVehicleControllerComponentEngine::dGearBox::m_reverseGear);
      break;
   case 0:
      engine->SetGear(CustomVehicleControllerComponentEngine::dGearBox::m_newtralGear);
      break;
   default:
      engine->SetGear(CustomVehicleControllerComponentEngine::dGearBox::m_firstGear + gearid - 1);
      break;
   }
}

float NewtonVehicle::GetRPM()
{
   return engine->GetRPM();
}

float NewtonVehicle::GetSpeed()
{
   return engine->GetSpeed();
}

void NewtonVehicle::SetTransmissionMode(bool automatic)
{
   engine->SetTransmissionMode(automatic);
}
Last edited by pHySiQuE on Wed Sep 17, 2014 6:55 pm, edited 2 times in total.
pHySiQuE
 
Posts: 608
Joined: Fri Sep 02, 2011 9:54 pm

Re: Simple Vehicle Class

Postby pHySiQuE » Sat Sep 13, 2014 8:54 pm

Is it really necessary for the vehicle manager to accept a collision instead of just working on an arbitrary body? The integration in my engine will be pretty difficult with that design.
pHySiQuE
 
Posts: 608
Joined: Fri Sep 02, 2011 9:54 pm

Re: Simple Vehicle Class

Postby Julio Jerez » Sat Sep 13, 2014 10:05 pm

another CreateVehicle that takes a body already made can be added,
I just though it will be simpler to pass the collision shape and have the controller adding the vehicle

but yes is not really necessary that the controller create the vehicle body,
I will add another function that passes the body tomorrow.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simple Vehicle Class

Postby pHySiQuE » Sun Sep 14, 2014 10:32 am

Okay, my wrapper class is done and I will post it as soon as that is ready.
pHySiQuE
 
Posts: 608
Joined: Fri Sep 02, 2011 9:54 pm

Re: Simple Vehicle Class

Postby Julio Jerez » Sun Sep 14, 2014 10:14 pm

Yes that's the idea, you use the classes as base classes to make your own implementation.

just to gives an idea how thread vehicles are going to look like, sync and play the demo.

It is not fully completed yet, tomorrow I will add the part the move the thread up and down,
but the thread motion is very compelling, I think.

I have not added the function to initialize the vehicle from a body already made yet, I will do tat tomorrow.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simple Vehicle Class

Postby pHySiQuE » Mon Sep 15, 2014 11:18 am

You do realize when people have to "make their own implementation" that your participation rate will drop by 95%, right?
pHySiQuE
 
Posts: 608
Joined: Fri Sep 02, 2011 9:54 pm

Re: Simple Vehicle Class

Postby Julio Jerez » Mon Sep 15, 2014 11:51 am

I do not think this is true, there are ton of libraries that provide base classes for end customer build on top of them.
plus it does not really matter to me if I have not participation, I believe I have participated too much already.
over the years if has become a very big disappointment to me that the primary reason people turn to use Newton is because they feel is simpler but inferior to other solutions, in most cases they use as a learning step to try to go to another physic library later.
People adding functionality is what I would like to happens but so far very few people has done it.

anyway if you sync again, the tracks of threaded vehicle is now completed, and I believe it Is very cool, if I may say so.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simple Vehicle Class

Postby pHySiQuE » Mon Sep 15, 2014 2:03 pm

Convenience always wins. Usually the simpler easier to use technology overtakes the more complex technology.

The treaded vehicle is quite cool. I've never seen anything like that.
pHySiQuE
 
Posts: 608
Joined: Fri Sep 02, 2011 9:54 pm

Re: Simple Vehicle Class

Postby Julio Jerez » Mon Sep 15, 2014 2:09 pm

pHySiQuE wrote:The treaded vehicle is quite cool. I've never seen anything like that.

At least not on a real time general purpose physics demo,
there are very good specialized vehicle simulations out there but there are specialized vehicle solvers that uses reduced coordinate system to solve the equations. for a general purpose physics solve I think this is pretty good. considering there the thread are still fake, But isn't that cool?

Next I will make the super car demo drive on a test court where the car will be drive following a spline path that define the driving court.
I Think should show some interesting emerging drifting.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simple Vehicle Class

Postby Julio Jerez » Wed Sep 17, 2014 9:10 am

pHySiQuE wrote:Is it really necessary for the vehicle manager to accept a collision instead of just working on an arbitrary body? The integration in my engine will be pretty difficult with that design.

this is now implemented
Code: Select all
CustomVehicleController* CreateVehicle (NewtonBody* const body, const dMatrix& vehicleFrame, const dVector& gravityVector);

CustomVehicleController* CreateVehicle (NewtonCollision* const chassisShape, const dMatrix& vehicleFrame, dFloat mass, const dVector& gravityVector);
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simple Vehicle Class

Postby pHySiQuE » Wed Sep 17, 2014 6:55 pm

THanks. My code above is updated.
pHySiQuE
 
Posts: 608
Joined: Fri Sep 02, 2011 9:54 pm

Re: Simple Vehicle Class

Postby collerblade2 » Sun Oct 05, 2014 10:48 am

Hi
1. hm.. handBrakes are none existing. U need to insert vehicle->SetHandBrakes(....); somewhere into Build().
2. engine->SetKey() is not editable trough your warp.
3. in build u use steering instead of usesteering.

TY
collerblade2
 
Posts: 9
Joined: Wed Aug 27, 2014 4:27 pm

Re: Simple Vehicle Class

Postby pHySiQuE » Wed Oct 08, 2014 1:50 am

Thank you for those corrections. I have now built this vehicle class into my engine and will not be updating it. I hope this is useful for you.
pHySiQuE
 
Posts: 608
Joined: Fri Sep 02, 2011 9:54 pm

Re: Simple Vehicle Class

Postby Julio Jerez » Wed Oct 08, 2014 5:15 pm

@collerblade2
did you get anything going?

@pHySiQuE
did you get the Threaded vehicles?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simple Vehicle Class

Postby collerblade2 » Thu Oct 09, 2014 2:13 am

hi,
y its working mostly :-). Thx. But it is still in wip (work in progress).
collerblade
collerblade2
 
Posts: 9
Joined: Wed Aug 27, 2014 4:27 pm

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest