# File by Niklas Silen
# INSTRUCTIONS (how to use the custom FFB system)
#################################################
# Copy this text to a plain text file. Remove the "" symbol that will appear at the begining and the end. Rename the file to ffb_custom.txt and place it in My Documents\Project CARS 2 directory, then select CUSTOM from within the game
#
#General form of code
#(A B ....)
#If A is known function name, then that function is done, with B ... as the arguments. If an argument is itself in (), then that is resolved first.
#If A is not a function name, it is taken as a variable name, and is assigned B, and ... is ignored.
#So
#(output (relative output 1.0 0.5 2.0))
#becomes in effect somthing like in C ish form:
#output = relative(output, 1.0, 0.5, 2.0);
#
# List of commands:
###################
#Variables ...
#Output ...
#* output -- the FFB applied to the wheel
#####
#Time ...
#* dt -- timestep
#* et -- elapsed time
#########
#Steering ...
#* steering_vel
#* steering_pos
################
#Player Controls ...
#* volume
#* tone
#* fx
#########
#Steering ...
#* steering_approx
#* steering_angle_FL
#* steering_angle_FR
#Useful for centering spring type effects.
############
#Rack Forces ...
#(FL, FR, RL, RR)
#* FL_Fx
#* FL_Fy
#* FL_Fz
#* FL_Mx
#* FL_My
#* FL_Mz
#These forces are the components of forces at the tires as felt through the rack. Simply add them all together to get the full rack force.
#Note that Mx and My are near zero, and do not contribute much at all, so adding Fx, Fy, Fz, and Mz is adequate.
#####################
#Full Forces at Tires ...
#(FL, FR, RL, RR)
#* FL_lat
#* FL_long
#* FL_load
#Unlike the above these are the raw full forces at the tires, not mechanically filtering through steering geometry and linkages.
######
#(FL, FR)
#FL_patch_fx
#FL_patch_fy
#FL_patch_fz
#FL_patch_mz
#These are direct forces from the contact patch of the tyre
######
#Grips ...
#(FL, FR)
#* FL_def
#* FL_adh
#* FL_tack
#* FL_stab
#* FL_visc
#* FL_tear
#The ratios of full grip (forces) due to each grip type in the model. They will all sum to 1.0 at any given timestep.
#######
#Rubber ...
#(FL, FR)
#* FL_slide -- 0 to 1 for how much the contact patch is in slide
#* FL_stretch
########
#Relates to Functions ...
#Linkage ...
#* arm_angle -- Linkage uses this value as the spindle arm angle
######
#Split ...
#* split_lo -- split's output: low component
#* split_md -- split's output: medium component
#* split_hi -- split's output: high component
#######
#Smooth ...
#* smooth_lo -- smoothed signal (same as return value)
#* smooth_hi -- the remainder (input - smoothed)
#########
#Histogram ...
#* hist_L -- histogram's L value; F1 widget uses this
#* hist_ML -- histogram's ML value; F1 widget uses this
#* hist_M -- histogram's M value; F1 widget uses this
#* hist_MH -- histogram's MH value; F1 widget uses this
#* hist_H -- histogram's H value; F1 widget uses this
#* hist_clip -- histogram's clip value; F1 widget uses this
###########
#SignalScale ...
#* scale_window_init -- first time time window before adjusting
#* scale_window_nominal -- subsequent windows
#* scale_soft_clear_t -- reference time for fading out learning info
#* scale_blend_t -- reference time for blending in new scale
#* scale_min -- minimum scale
#* scale_max -- maximum scale
##################
#Function Reference ...
#
#Absolute Value ...
#(abs <input>)
#
#Add ...
#(+ <input> ...)
#Add all of the inputs.
#
#AntiDrag ...
#(anti_drag <input> <Cd> <Cf> <refvel>)
#* Cd -- anti drag coeefficent, function of wheel position velocity
#* Cf -- anti drag friction, constant resistence, tapered to zero via:
#* refvel -- wheel velocity below which to taper to zero.
#
#Drag ...
#(drag <input> <Cd> <Cq>)
#* Cd -- drag coeefficent, function of wheel position velocity
#* Cq -- drag coeefficent, function of wheel position velocity squared
#
#Blend ...
#(blend <bias> <input for one> <input for zero>)
#
#Center ...
#(ctr <input>)
#Convert input assumed to be between from 0.0 to 1.0, to -1.0 to 1.0.
#
#Divide ...
#(/ <first input> <input> ...)
#Divide inputs from first input.
#
#Down ...
#(dn <input>)
#Convert input such that:
#* 0 - 0.5 : 0.0
#* 0.5 - 1.0 : 0.0 - 1.0
#
#Hard Clipper ...
#(hard_clip <input> <cap>)
#
#Histogram ...
#(histogram <input>)
#
#If ...
#(if <cond> <true> <false>)
#
#Linkage ...
#(linkage <mode> <angle>)
#
#Maximum ...
#(max <args ...>)
#
#Minimum ...
#(min <args ...>)
#
#Multiply ...
#(* <args ...>)
#
#Power ...
#(power <input> <power>)
#
#RelativeGain ...
#(relative <gain> <bleed> <clamp>)
#
#Safety ...
#(safety <input> <limit>)
#
#Scoop ...
#(scoop <input> <knee> <reduction>)
#
#SignalScale ...
#(signal_scale <input>
#<L weight> <ML weight> <M weight> <MH weight> <H weight>
#<clipping weight>
#<equalize blend> <boost blend>)
#
#Smooth ...
#(smooth <input> <ref time>)
#
#Soft Clipper ...
#(soft_clip <half in> <unity>)
#
#Split ...
#(split <lo scale> <md scale> <hi scale> <lo/md ref time> <md/hi ref time>)
#
#Spring ...
#(spring <force> <stiffness> <damping>)
#
#Subtract ...
#(- <first input> <input> ... )
#Subtract inputs from first input.
#
#Tighten Center ...
#(tighten <input> <range> <falloff>)
#
#Up ...
#(up <input>)
#Convert input such that:
#* 0 - 0.5 : 1.0 - 0.0
#* 0.5 - 1.0 : 0.0
######################################################
# END OF INSTRUCTIONS
######################################################
#
# CUSTOM PRESET Description: 50 / 50 split of Rack and Tire forces
#
(Fx_scale 1.0)
(Fy_scale 1.0)
(Fz_scale 1.0)
(My_scale 1.0)
(Mx_scale 1.0)
(Mz_scale 1.0)
# Low Speed Filter Out -------------------------------
(Fx_scale (* Fx_scale (crossover vel_mag 0.0 1.0)))
(Mz_scale (* Mz_scale (crossover vel_mag 0.0 1.0)))
(arm_angle 0.0)
(left_scale (linkage 1.0 -1.0))
(right_scale (linkage 1.0 1.0))
# TIRES
(def_scale 1.0)
(adh_scale 1.0)
(tack_scale 1.0)
(stab_scale 1.0)
(visc_scale 1.0)
(tear_scale 1.0)
(left_grip (+ (* FL_def def_scale) (* FL_adh adh_scale) (* FL_tack tack_scale) (* FL_stab stab_scale) (* FL_visc visc_scale) (* FL_tear tear_scale)))
(right_grip (+ (* FR_def def_scale) (* FR_adh adh_scale) (* FR_tack tack_scale) (* FR_stab stab_scale) (* FR_visc visc_scale) (* FR_tear tear_scale)))
(left_scale (* left_scale left_grip))
(right_scale (* right_scale right_grip))
# Tires linkage through 0 arm angle
(Fx (+ (* left_scale FL_Fx) (* right_scale FR_Fx)))
(Fy (+ (* left_scale FL_Fy) (* right_scale FR_Fy)))
(Fz (+ (* left_scale FL_Fz) (* right_scale FR_Fz)))
(Mx (+ (* left_scale FL_Mx) (* right_scale FR_Mx)))
(My (+ (* left_scale FL_My) (* right_scale FR_My)))
(Mz (+ (* left_scale FL_Mz) (* right_scale FR_Mz)))
(tire_grips (+ (* Fx_scale Fx) (* Fy_scale Fy) (* Fz_scale Fz) (* Mx_scale Mx) (* My_scale My) (* Mz_scale Mz) ) )
# RACK part starts from here
(Fx_scale 1.0)
(Fy_scale 1.0)
(Fz_scale 1.0)
(My_scale 1.0)
(Mx_scale 1.0)
(Mz_scale 1.0)
# Low Speed Filter Out
(Fx_scale (* Fx_scale (crossover vel_mag 0.0 1.0)))
(Mz_scale (* Mz_scale (crossover vel_mag 0.0 1.0)))
# Spindle Arm
(arm_angle 15.0))
(left_scale (linkage 1.0 -1.0))
(right_scale (linkage 1.0 1.0))
# Rack linkage
(Fx (+ (* left_scale FL_Fx) (* right_scale FR_Fx)))
(Fy (+ (* left_scale FL_Fy) (* right_scale FR_Fy)))
(Fz (+ (* left_scale FL_Fz) (* right_scale FR_Fz)))
(Mx (+ (* left_scale FL_Mx) (* right_scale FR_Mx)))
(My (+ (* left_scale FL_My) (* right_scale FR_My)))
(Mz (+ (* left_scale FL_Mz) (* right_scale FR_Mz)))
(rack (+ (* Fx_scale Fx) (* Fy_scale Fy) (* Fz_scale Fz) (* Mx_scale Mx) (* My_scale My) (* Mz_scale Mz) ) )
# Combining RACK and TIRE forces
(output (+ (* tone 2.0 rack) (* (+ (* tone -1.0) 1.0) 2.0 tire_grips)))
# Jerk Based Road Feel -------------------------------
(FL_road (* FL_load 1.0))
(FL_road (jerk FL_road))
(FL_road (* FL_road (abs FL_angvel)))
(FR_road (* FR_load -1.0))
(FR_road (jerk FR_road))
(FR_road (* FR_road (abs FR_angvel)))
(FL_brk (* FL_long 1.0))
(FL_brk (jerk FL_brk))
(FL_brk (* FL_brk (abs FL_angvel)))
(FR_brk (* FR_long -1.0))
(FR_brk (jerk FR_brk))
(FR_brk (* FR_brk (abs FR_angvel)))
# Bump -----------------------------------------------
(inv_period (/ 1.0 (+ FL_bump_period 0.001)))
(dphase (* FL_vel_x dt inv_period))
(FL_bump (oscillator dphase))
(FL_bump (scoop FL_bump FL_bump_sharpness 0.95))
(FL_bump (* FL_bump FL_load FL_bump_amplitude FL_angvel))
(FL_bump (split FL_bump 0.0 1.0 0.0 0.4 0.02))
(inv_period (/ 1.0 (+ FR_bump_period 0.001)))
(dphase (* FR_vel_x dt inv_period))
(FR_bump (oscillator dphase))
(FR_bump (scoop FR_bump FR_bump_sharpness 0.95))
(FR_bump (* FR_bump FR_load FR_bump_amplitude FR_angvel))
(FR_bump (split FR_bump 0.0 1.0 0.0 0.4 0.02))
# Scrub ----------------------------------------------
(FL_scrub (soft_clip FL_scrub 2.0 0.0))
(FL_scrub (scoop FL_scrub 0.8 0.999))
(FL_scrub (* FL_scrub (oscillator 1.2)))
(FR_scrub (soft_clip FR_scrub 2.0 0.0))
(FR_scrub (scoop FR_scrub 0.8 0.999))
(FR_scrub (* FR_scrub (oscillator 1.2)))
# Texture --------------------------------------------
(road_scale (* 0.0005 1.0))
(brk_scale 0.0)
(bump_scale (* 0.24 1.0))
(scrub_scale (* 14.0 1.0))
(tex_k 20000.0)
(tex_d 1.0)
(FL_tex (+ (* road_scale FL_road) (* brk_scale FL_brk) (* bump_scale FL_bump) (* scrub_scale FL_scrub)))
(FL_tex (split FL_tex 0.0 1.0 1.0 2.0 0.01))
(FL_tex (spring FL_tex tex_k tex_d 1.0))
(FR_tex (+ (* road_scale FR_road) (* brk_scale FR_brk) (* bump_scale FR_bump) (* scrub_scale FR_scrub)))
(FR_tex (split FR_tex 0.0 1.0 1.0 2.0 0.01))
(FR_tex (spring FR_tex tex_k tex_d 1.0))
(tex (+ FL_tex FR_tex))
(tex (soft_clip tex 1.0 0.0))
# Engine ---------------------------------------------
(engine (oscillator (* throttle crankshaft 0.0006)))
(engine (split engine 0.0 1.0 0.0 0.1 0.02))
# Gearbox --------------------------------------------
(gearbox (oscillator (* (- driveshaft_core clutchshaft_core) 1.0)))
(gearbox (* gearbox gearbox_grind clutch 0.05))
(gearbox (spring gearbox 8000.0 0.2 1.0))
(gearbox (* gearbox 1.0))
(feel (+ tex gearbox))
# Scaler as informational only, doesnt affect output -
(scale_window_init 10.0)
(scale_window_nominal 2.0)
(scale_soft_clear_t 10.0)
(scale_min 0.2)
(scale_max 2.0)
(scale_blend_t 2.0)
(signal_scale output
1.0 1.0 1.0 1.0 1.0
0.0
0.0 0.0)
(output (+ (* volume output) (* feel fx)))
(histogram output)
(output (hard_clip (* output gain) 1.0))