Now, I wrote a single script that creates suspension, steer and traction
You have to create the chassis, 4 wheels, set this script to each one of the wheels and then paly with the configurable parameters.
Enjoy:
--[[
Autor Juan Ignacio Odriozola (charrua)
Purpose:
A script that facilitates the making of a simple car
all you need is a chassis and 4 wheels
assing this scrip to each wheel and set the object chassis
then adjust some of the configurable parameters
Parent: chassis
entity : wheel
3 joints and 2 auxiliary entities are created the chain is:
Parent Slider Pivot Hinge Pivot Hinge
chassis -suspensionJoint- suspensionPivot -steerJoint- steerPivot -wheelJoint- wheel
suspension uses pin 010 (Y axis)
steer uses pin 010 (Y axis)
wheel pin (must be set depends of wheel orientation)
up/down keys are defaults for forward and backward
left/right keys are defaults for steer left/right
space key is default for brakes
steer velocity and start/end angle must be set
suspension lenght must be set
wheel friction must be set
steerAngle set both limits to +/- steerAngle/2
if no key (left/right) is pressed then, target angle is 0 : straight
suspensionLenght set both limits to +/- suspensionLength/2 and target distance is set to 0
suspension strength defaults to 1000
which is too much strenght for a light weight car (20 of mass) and not to much for a 200 car of mass
each joint is created with a mass of 1, which should be taking into accoung
(so for a 4 wheels car, you have a mass of 8 on the 8 joints).
there are so many other parameters that may be adjusted: Spring, Strength, Stiffness ... not too much documented :)
]]--
Script.currspeed = 0
Script.chassis = nil--Entity "chassis"
Script.pin = Vec3(0,0,1) --Vec3 "wheel Pin"
Script.motorspeed=500--float "max motor speed"
Script.velcontrolled=false--bool "velControl"
Script.suspensionLength=0.2--float "suspension"
Script.steerAngle=90--float "steer angle"
Script.steerSpeed=100--float "steer velocity"
Script.friction=1--float "wheel friction"
Script.steerPivot=nil
Script.suspensionPivot=nil
Script.steerJoint=nil
Script.suspensionJoint=nil
Script.wheelJoint=nil
function Script:Start()
local pos = self.entity:GetPosition(false) --true for global
if self.chassis ~= nil then
self.suspensionPivot = Pivot:Create()
self.suspensionPivot:SetPosition(pos)
self.suspensionPivot:SetMass(1)
self.suspensionPivot:SetCollisionType(Collision.None)
self.steerPivot = Pivot:Create()
self.steerPivot:SetPosition(pos)
self.steerPivot:SetMass(1)
self.steerPivot:SetCollisionType(Collision.None)
--joints creation
self.suspensionJoint = Joint:Slider(pos.x, pos.y, pos.z, 0, 1, 0, self.chassis, self.suspensionPivot)
self.steerJoint = Joint:Hinge(pos.x, pos.y, pos.z, 0, -1, 0, self.suspensionPivot, self.steerPivot)
self.wheelJoint = Joint:Hinge(pos.x, pos.y, pos.z, self.pin.x, self.pin.y, self.pin.z, self.steerPivot, self.entity)
--suspension
self.suspensionJoint:EnableLimits()
self.suspensionJoint:SetLimits(-self.suspensionLength/2,self.suspensionLength/2) --steerAngle=0 means no steer
self.suspensionJoint:SetTargetAngle(0) --at the middle
self.suspensionJoint:SetMotorSpeed(1) -- 1 m/s
self.suspensionJoint:SetStrength(100) --defatul is 1000
self.suspensionJoint:EnableMotor()
--steer
self.steerJoint:EnableLimits()
self.steerJoint:SetLimits(-self.steerAngle/2,self.steerAngle/2) --steerAngle=0 means no steer
self.steerJoint:SetMotorSpeed(self.steerSpeed)
self.steerJoint:EnableMotor()
--wheel
self.entity:SetFriction(self.friction, self.friction)
else
Debug:Error("no chassis assigned")
end
end
function Script:setMotorSpeed(speed)
if self.velcontrolled then
--System:Print("setMotorSpeed: "..speed)
self.currspeed = speed
if speed~=0 then
self.wheelJoint:EnableMotor()
end
self.wheelJoint:SetMotorSpeed(self.currspeed)
end
end
function Script:UpdateWorld()
if self.motorspeed>0 then
self.wheelJoint:SetAngle(self.wheelJoint:GetAngle()+100)
else
self.wheelJoint:SetAngle(self.wheelJoint:GetAngle()-100)
end
if App.window:KeyDown(Key.Space) then
self:setMotorSpeed(0)
end
if self.velcontrolled then
if App.window:KeyDown(Key.Up) then
self.currspeed = self.currspeed + 10
if self.currspeed>self.motorspeed then
self.currspeed=self.motorspeed
end
if self.currspeed == 10 then self.wheelJoint:EnableMotor() end
self.wheelJoint:SetMotorSpeed(self.currspeed)
end
if App.window:KeyDown(Key.Down) then
self.currspeed = self.currspeed - 10
if self.currspeed<-self.motorspeed then
self.currspeed=-self.motorspeed
end
self.wheelJoint:SetMotorSpeed(self.currspeed)
end
end
if self.steerAngle>0 then
local direction=0
if App.window:KeyDown(Key.Left) then
direction=-self.steerAngle/2
end
if App.window:KeyDown(Key.Right) then
direction=self.steerAngle/2
end
self.steerJoint:SetAngle(direction)
else
self.steerJoint:SetAngle(0)
end
end
In the other maps i was using a box as a floor to which I set the desired friction, testing this new script i use a terrain and have to figure it out how to set the friction to the terrain...
Did some searches and ended with:
local n
for n=0,self.world:CountEntities()-1 do
local entity = self.world:GetEntity(n)
if entity:GetClassName()=="Terrain" then
terrain = entity
System:Print("terrain found!")
terrain:SetFriction(10,10)
break
end
end
insert this in the app.lua (after load map) and then you can play with terrain friction, the video shows how the car behaves with the defaul terrain friction and then whit a friction of 10,10
Always learning something new
A word about some parameters:
If you are using a hinge, when you specity speed (SetMotorSpeed) the number means degrees per second. So if you use 3600 as max speed you get 10 revoluions per second.
If your tire has, 64cm then d*pi aprox 2 meters per revolution, 10 revolutions per secon aprox 20 meters per second... and if you are lucky 72Km/h
If you are using a slider, then speed is un meters per second.
Other parameter which is very important is the hinge/slider "pin" which is a vector that tells the direction of movement of the slider or over which plane de hinges open/close
For a common door, we need to use the Y axis, so the pin is 0,1,0
I use this pin for the suspension and for the steer but for this script, you must tell the traction pin, which sould be 1,0,0 or 0,0,1 depending on the orientation of your tires
If your tires are not facing X nor Z axis, then you have to do some math to get the proper x,z component of the pin
In the script I use a Strenght of 100, instead of the 1000 which is default, my car is light weight : 5 + 4*3 = 17 of Mass
chassis has 5, each wheel has 1 and the 2 auxiliary pivots has 1 each one
whith a friction of 10 on each tire and with a friction of 10 on the terrain looks ok for me (better than I spected at first).
Juan
- 3
15 Comments
Recommended Comments