wiki:vehicle

Vehicle

Vehicle interface is used to define physics parameters and behavior for ground vehicles.

When the vehicle is created for the first time, the engine invokes the init_chassis event in the script. This is expected to define the vehicle construction, adding wheels and returning vehicle parameters. The init_vehicle event is invoked for each new instance of the vehicle (including the first one), and it can be used to define per-instance parameters. Fps camera position should be defined here.

For each frame, update_frame event is called. Inputs and model animation is supposed to be handled here. In current version engine provides three input values - gas pedal state, brake pedal state, and steering value. These values are provided in normalized ranges, and the script is expected to produce the physical values for engine force, braking force and steering angle for each wheel.

Vehicle interface (vehicle)

The vehicle interface defines the following methods and events:

type name parameters description
event init_chassis string params - extra parameters from objdef file
returns vehicle_params structure
invoked once to define the vehicle chassis for all instances
used to define wheels and other chassis parameters
note: optional parameters come from objdef's "parameters" field, wrapped in extra {}
event init_vehicle invoked when a new instance of the vehicle is created
event engine bool start - true for engine starting, false when stopping invoked when the engine is started or stopped
event update_frame dt - delta time from previous frame
engine - engine power (-1 .. 1), gas pedal state
brake - brake pedal (0..1)
steering - steering state (-1..1)
invoked each frame to handle the internal state of the object
event switch_seat int seat - seat id to switch to handle seat and camera switching
should return false if given seat/camera id is not present
method get_geomob id - id of geometry object (default 0) returns a geometry object that can be used to animate the model joints according to the current state
method sound returns the corresponding sound interface object
method set_fps_camera_pos float3 pos - position of the camera
uint joint_id - optional joint id to attach to
set the position of the first person camera in model space
method get_camera_mode returns current camera mode: -1 not bound, 0 FPS, 1 TPS, 2 TPS follow
method log text - text for console window print text message to outerra console
recognizes error: and warning: prefixes
method add_wheel string wheel_pivot - name of the wheel model joint to bind to
wheel - wheel structure defining parameters of wheel, tire and suspension
returns wheel id (incremental from 0)
adds wheel with suspension moving along the z-axis (up/down)
note: can be called only from init_chassis
method add_wheel_swing string axle_pivot - name of the fixed axle model joint to bind to
string wheel_pivot - name of the wheel model joint to bind to
wheel - wheel structure defining parameters of wheel, tire and suspension
returns wheel id (incremental from 0)
adds wheel on half-axle suspension moving around the y-axis (i.e Tatra suspension)
note: can be called only from init_chassis
method load_sound string filename - audio file name (relative to package dir) preload sound sample
note: can be called only from init_chassis
method add_sound_emitter string joint - joint (bone) name in model create sound emitter that will be used by the vehicle
note: can be called only from init_chassis
method add_spot_light float3 offset - model-space offset relative to the bone or model pivot
float3 dir - ligth direction
light_params - light parameters
string joint joint name to attach the light to
Define circular spotlight source
note should be called in init_chassis()
method add_point_light float3 offset - model-space offset relative to the bone or model pivot
light_params - light parameters
string joint joint name to attach the light to
Define point light source
note: should be called in init_chassis()
method light uint id
bool on
Turn light on/off
method light_mask uint mask
bool on
uint base=0 - base light id to offset the mask from
Turn multiple lights identified by the bit mask on or off
method light_toggle uint id Toggle light
method light_toggle_mask uint mask
uint base=0 - base light id to offset the mask from
Toggle multiple lights identified by the bit mask
method light_color uint id
float3 color
Set light color/intensity
method lights_off All lights off
method steer int wheel_id - 0..n wheel to act on, -2 to act on the first two wheels (0,1)
float angle - angle in radians to steer the wheel(s)
steer wheel by setting angle
method wheel_force int wheel_id - 0..n wheel to act on, -1 to act on all wheels
float engine - force to exert on the wheel hub in fwd/bkw direction (in Newtons)
apply a propelling force on wheel(s)
method wheel_brake int wheel_id - 0..n wheel to act on, -1 to act on all wheels
float brake - braking force to exert on the wheel hub (in Newtons)
apply a braking force on wheel(s)
method wheel int wheel_id - 0..n wheel id
returns wheel_data structure with wheel info
get run-time wheel data
method speed get vehicle speed [m/s]
method velocity bool model_space - model or world space coordinate system returns speeds in ECEF space:
float3 linear - linear speed vector
float3 angular - angular speed vector
method max_tire_speed tire speed of the fastest revolving wheel [m/s]
method max_rpm rpm of the fastest revolving wheel
method animate_wheels articulate wheel joints according to the current state
Note: this method simplifies the animation of wheels for basic cases, without needing to animate the model via the geomob interface. However, this assumes that the wheel pivot uses a standard coordinate system, otherwise the wheels can behave oddly when animated
method extra_force float3 pos - model-space position where the force acts
float3 force - force vector in model-space coordinates (in Newtons)
apply extra force impulse anywhere on the object
method fire float3 pos - model-space position
float3 dir - model-space direction of firing
float speed - firing speed
float caliber - trace diameter
float3 color - tracer color
fire a colored plasma tracer
method mass float m - mass in kg set new object mass (usable for submarines and loads
method solar_time returns {time, sun_coef} object
time - solar time at vehicle location, in miliseconds
sun_coef - sun position relative to horizon: 0 sun at horizon, 1 sun at zenith, -1 sun at anti-zenith

See also the geometry object interface, for things to do with the underlying geometry object.

Example

var axle2coef=1.0;

//invoked only the first time the model is loaded, or upon reload
function init_chassis(param)
{
  //optional: get extra parameters from the objdef file
  var par = eval(param);

  var wheelparam = {
    radius: 0.7,
    width: 0.45,
    suspension_max: 0.2,
    suspension_min: -0.35,
    suspension_stiffness: 5.0,
    damping_compression: 0.2,
    damping_relaxation: 0.12,
    slip: 0.8,
    roll_influence: 0.1
  };
  this.add_wheel_swing('halfaxle_l0', 'tire_l0', wheelparam);
  this.add_wheel_swing('halfaxle_r0', 'tire_r0', wheelparam);
  this.add_wheel_swing('halfaxle_l1', 'tire_l1', wheelparam);
  this.add_wheel_swing('halfaxle_r1', 'tire_r1', wheelparam);
  this.add_wheel_swing('halfaxle_l2', 'tire_l2', wheelparam);
  this.add_wheel_swing('halfaxle_r2', 'tire_r2', wheelparam);
  this.add_wheel_swing('halfaxle_l3', 'tire_l3', wheelparam);
  this.add_wheel_swing('halfaxle_r3', 'tire_r3', wheelparam);
  
  //compute steering coefficient for the second axle
  var body = this.get_geomob(0);
  var a0 = body.get_joint_local_pos(body.get_joint('tire_l0')).y;
  var a1 = body.get_joint_local_pos(body.get_joint('tire_l1')).y;
  var a2 = body.get_joint_local_pos(body.get_joint('tire_l2')).y;
  var a3 = body.get_joint_local_pos(body.get_joint('tire_l3')).y;
  var m = 0.5*(a2+a3);
  axle2coef = (a1-m)/(a0-m);
  
  //sounds
  this.load_sound("diesel-engine-start.ogg");
  this.load_sound("diesel-engine-idle.ogg");
  this.add_sound_emitter("halfaxle_l0");
  
  return {mass:14000};
}

//invoked for each new instance of the vehicle
function init_vehicle()
{
  this.snd = this.sound();
  this.snd.set_ref_distance(0, 9.0);

  this.started = 0;
}

function engine(start)
{
  if(start) {
    this.started=1;
    this.snd.play(0, 0, false, false);
  }
}


const EF = 27000.0;
const BF = 28000.0;
const maxkmh = 100;
const forceloss = EF / (0.2*maxkmh + 1);


//invoked each frame to handle inputs and animate the model
function update_frame(dt, engine, brake, steering)
{
  var kmh = this.speed()*3.6;
  
  //reduce engine force with speed (hack)
  var redux = engine>=0 ? 0.2 : 0.6;
  var esign = engine<0 ? -1 : 1;
  engine = EF*Math.abs(engine);
  var force = (esign>0) == (kmh>=0)
        ? engine/(redux*Math.abs(kmh) + 1)
        : engine;
  force -= forceloss;
  force = Math.max(0.0, Math.min(force, engine));
  engine = esign*force;


  steering *= 0.6;
  this.steer(0, steering);
  this.steer(1, steering);
  this.steer(2, steering*axle2coef);
  this.steer(3, steering*axle2coef);
  
  if(this.started>1)
    this.wheel_force(-1, engine);
  
  brake *= BF;
  this.wheel_brake(-1, brake);
  
  this.animate_wheels();
  
  if(this.started==1 && !this.snd.is_playing(0)) {
    this.started=2;
    this.snd.play(0, 1, true, false);
  }
  else if(this.started==2) {
    var pitch = Math.abs(kmh)/20.0;
    var g = kmh>0 ? Math.floor(pitch) : 0;
    var f = pitch - g;
    f += 0.5*g;
    this.snd.set_pitch(0, 0.5*f + 1.0);
  }
}

See vehicle_params for getting further information about vehicle parameters.

Last modified 2 years ago Last modified on Sep 20, 2015, 6:21:58 PM