OK, I rolled my own wheels and brakes, and they work
splendidly. I can lock up the brakes, do static engine run ups, pivot around one wheel when steering, set parking brakes, etc.. Here's what I have done:
Wheels
I basically apply a counter force to kill any momentum in the vessel x-direction at every time step as I described here:
https://www.orbiter-forum.com/threa...ntures-and-questions.41799/page-3#post-620009
The following function is called in clbk_poststep:
Code:
function set_feature.Set_Rolling_Wheels()
--Following is to mimic realistic rolling tires without side scrub
if vi:get_groundcontact() then
local groundspeed = vi:get_groundspeedvector(REFFRAME.LOCAL)
local side_slip = groundspeed.x
local mass = empty_mass + vi:get_propellantmass(main_fuel_tank)
local simdt = oapi.get_simstep()
side_force_new = mass * side_slip /simdt
if side_force_old == nil then
side_force_old = side_force_new
end
--Need to under-relax the force calculation so vessel doesn't get yeeted to Alpha Quadrant
side_force = side_force_old + 0.5*(side_force_new - side_force_old)
side_force_old = side_force
message = tostring(side_force)
vi:add_force({x=-side_force, y=0, z=0}, {x=0,y=right_wheel_contact.y,z=right_wheel_contact.z})
else
side_force_old = 0
end
end
Brakes
It seems that Orbiter has some anemic default brakes in the background and I don't know if I have shut them down completely, but I have a separate braking implementation using add_force.
I have calls to apply either the left or right brake using the default brake keys in clbk_consumedirectkey:
Code:
function clbk_consumedirectkey(kstate)
if oapi.keydown(kstate, OAPI_KEY.COMMA) then -- set left brake
set_feature.Set_Left_Brake_Force()
end
if oapi.keydown(kstate, OAPI_KEY.PERIOD) then -- set right brake
set_feature.Set_Right_Brake_Force()
end
return false
end
The set_feature.Set_XXXX_Brake_Force() function simply calculates a braking force and applies it to the appropriate wheel contact (only left side function is shown, right is similar):
Code:
function set_feature.Set_Left_Brake_Force()
brake_force = set_feature.Apply_Brake_Force()
vi:add_force({x=0, y=0, z=-brake_force}, left_wheel_contact)
return true
end
The braking force is calculated using the following function. It calculates a braking force based on groundspeed in the z-direction, but limits the total braking acceleration to 1 G (9.81 m/s2). This will also apply braking force in the correct direction, for cases you are rolling backwards.
If groundspeed in the z-direction is zero, then the brake force applied exactly counters the z-component of thrust parallel to the ground.
Code:
function set_feature.Apply_Brake_Force()
if vi:get_groundcontact() then
local groundspeed = vi:get_groundspeedvector(REFFRAME.LOCAL)
local forward_speed = groundspeed.z
local mass = empty_mass + vi:get_propellantmass(main_fuel_tank)
local simdt = oapi.get_simstep()
if forward_speed == 0 then --set brake force to counter thrust parallel to ground
F = vi:get_thrustvector(th_main)
pitch = vi:get_pitch()
brake_force = 0.5*F.z*math.cos(pitch)
else
if math.abs(forward_speed/simdt) > 9.81 then
--determine if velocity is positive or negative
if forward_speed > 0 then
brake_force = 0.5*mass*9.81
else
brake_force = -0.5*mass*9.81
end
else
brake_force = 0.5*mass*forward_speed/simdt
end
end
end
return brake_force
end
It occurs to me that this braking likely will fail if the vessel is not on completely flat terrain as the wheel and braking forces don't currently account for vessel x- and z- components of gravity, so if you decide to go off-roading in a J-3, good luck.