followme_e-tron/Nasal/steering.nas

214 lines
7.6 KiB
Plaintext
Raw Permalink Normal View History

#//Followme EV steering system by Sidi Liang
#//Contact: sidi.liang@gmail.com
2020-01-17 15:33:43 +08:00
var cache = {
new: func return { parents:[cache] };
};
var memoize = { callback:nil };
memoize.new = func(code) {
return { parents:[memoize], callback:code, cache:cache.new() };
}
memoize._save = func(value) me.cache[value] = me.callback(value);
memoize.lookup = func(value) {
var found = me.cache[value];
if (found) {
#//print("cached:",found,"\n");
return found;
}
#//print("Calculated:", value);
return me._save(value);
}
var Steering = {
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
new: func() {
print("Steering system initialized!");
2020-04-22 19:39:11 +08:00
var steering = { parents:[Steering] };
props.getNode("/controls/steering_wheel/steering_limit-deg", 1).setValue(steering.steeringLimit * R2D);
return steering;
2020-01-17 15:33:43 +08:00
},
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
mode: 0, #//0: direct; 1: advanced
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
debugMode: 0,
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
input: 0, #//-1: left, 1:right, 0: none
command: 0, #//Steering command, range from -1 to 1
2020-05-16 18:13:53 +08:00
commandNode: props.getNode("/controls/flight/rudder", 1),
2020-01-17 15:33:43 +08:00
steeringAngle: 0, #//in rad
2020-04-22 19:39:11 +08:00
#steeringAngleDeg: 0, #//in degrees
#//steeringLimit: 7.8539815, #// 2.5 * 3.1415926 = 7.8539815 5 * 3.1415926 = 15.707963 3.1415926 / 4 = 0.78359815
steeringLimit: 15.707963,
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
powPointThree: memoize.new( func(value){
return math.pow(value, 0.3);
}),
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
powPointOne: memoize.new( func(value){
return math.pow(value, 0.1);
}),
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
steeringStep:func(rad){
return 0.1 * me.powPointOne.lookup(sprintf("%.1f", math.abs(rad))) + 0.04;
},
neutralStep: func(rad){
var speed = props.getNode("/", 1).getValue("sim/multiplay/generic/float[15]");
2020-04-22 19:39:11 +08:00
return 0.03 * me.powPointThree.lookup(sprintf("%.1f", math.abs(speed))) * math.abs(rad);
2020-01-17 15:33:43 +08:00
},
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
mainLoop: func(){
if(me.input == 0)
{
if(math.abs(me.steeringAngle) <=0.2)
2020-01-17 20:30:27 +08:00
{
2020-01-17 15:33:43 +08:00
me.steeringAngle = 0;
2020-05-16 18:13:53 +08:00
me.command = me.steeringAngle / me.steeringLimit; #//The steering wheel could rotate for two circles and a half
me.commandNode.setValue(me.command);
2020-04-22 19:39:11 +08:00
#me.steeringAngleDeg = me.steeringAngle * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
2020-01-17 20:30:27 +08:00
}
2020-01-17 15:33:43 +08:00
if(me.steeringAngle == 0)
{
me.stopTimer();
return 0;
}
2020-01-17 20:29:25 +08:00
else if(me.steeringAngle >= 0.05)
2020-01-17 15:33:43 +08:00
me.steeringAngle -= me.neutralStep(me.steeringAngle);
2020-01-17 20:33:32 +08:00
else if(me.steeringAngle <= -0.05)
2020-01-17 15:33:43 +08:00
me.steeringAngle += me.neutralStep(me.steeringAngle);
}
else if(me.input == 1 and me.steeringAngle < me.steeringLimit)
{
if(me.steeringAngle < 0)
{
me.steeringAngle += me.neutralStep(me.steeringAngle);
me.steeringAngle += 0.35 * me.input;
}
else
me.steeringAngle += me.steeringStep(me.steeringAngle);
}
else if(me.input == -1 and me.steeringAngle > (-me.steeringLimit))
{
if(me.steeringAngle > 0)
{
me.steeringAngle -= me.neutralStep(me.steeringAngle);
me.steeringAngle -= 0.35;
}
else
me.steeringAngle -= me.steeringStep(me.steeringAngle);
}
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
me.command = me.steeringAngle / me.steeringLimit; #//The steering wheel could rotate for two circles and a half
2020-04-22 19:39:11 +08:00
#me.steeringAngleDeg = me.steeringAngle * R2D;
2020-05-16 18:13:53 +08:00
me.commandNode.setValue(me.command);
2020-04-22 19:39:11 +08:00
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
2020-01-17 15:33:43 +08:00
if(me.debugMode)
{
print("Steering system command:" ~ me.command);
print("Steering system angle rad:" ~ me.steeringAngle);
print("Steering system angle degrees:" ~ me.steeringAngleDeg);
}
},
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
inputLeft: func(){
me.input = -1;
if(!me.mode){
2020-04-22 19:39:11 +08:00
me.command = -0.5;
2020-01-17 15:33:43 +08:00
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
2020-04-22 19:39:11 +08:00
#me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
2020-01-17 15:33:43 +08:00
}else if(me.mode and !me.timerStarted){
me.startTimer();
}
},
inputRight: func(){
me.input = 1;
if(!me.mode){
me.command = 0.5;
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
2020-04-22 19:39:11 +08:00
#me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
2020-01-17 15:33:43 +08:00
}else if(me.mode and !me.timerStarted){
me.startTimer();
}
},
neutral: func(){
me.input = 0;
if(!me.mode){
me.command = 0;
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
2020-04-22 19:39:11 +08:00
#me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
2020-01-17 15:33:43 +08:00
}else if(me.mode and !me.timerStarted){
me.startTimer();
}
},
2020-04-22 19:39:11 +08:00
2020-01-17 15:33:43 +08:00
steeringTimer: nil,
timerCreated: 0,
timerStarted: 0,
startTimer: func(){
if(!me.timerCreated){
me.steeringTimer = maketimer(0.01, func me.mainLoop());
me.timerCreated = 1;
me.steeringTimer.simulatedTime = 1;
if(me.debugMode) print("Steering system timer created!");
}
me.steeringTimer.start();
me.timerStarted = 1;
if(me.debugMode) print("Steering system timer started!");
},
stopTimer: func(){
me.steeringTimer.stop();
me.timerStarted = 0;
if(me.debugMode) print("Steering system timer stopped!");
},
};
#//Force calculation for front wheel drive(and four wheel drive)
var flForce = props.getNode("/fdm/jsbsim/external_reactions/FL");
var frForce = props.getNode("/fdm/jsbsim/external_reactions/FR");
var calculateFWForce = func(input){
var rad = input * 45 * D2R;
var x = math.cos(rad);
var y = math.sin(rad);
flForce.setValue("x", x);
flForce.setValue("y", y);
frForce.setValue("x", x);
frForce.setValue("y", y);
}
2020-01-17 15:33:43 +08:00
var steeringAssistance = Steering.new();
var frontWheelListener = setlistener("/controls/flight/rudder", func(n){ # create listener
calculateFWForce(n.getValue());
});
2020-01-17 15:33:43 +08:00
addcommand("enableAdvancedSteering", func() {
steeringAssistance.mode = 1;
print("Advanced Steering Enabled");
});
addcommand("disableAdvancedSteering", func() {
steeringAssistance.mode = 0;
print("Advanced Steering Disabled");
2020-04-22 19:39:11 +08:00
});
addcommand("setSteeringTravelToMin", func() {
steeringAssistance.steeringLimit = 0.78359815;
props.getNode("/controls/steering_wheel/steering_limit-deg", 1).setValue(steeringAssistance.steeringLimit * R2D);
print("Steering Travel Set To 1 : 1");
});
addcommand("setSteeringTravelToNormal", func() {
steeringAssistance.steeringLimit = 7.8539815;
props.getNode("/controls/steering_wheel/steering_limit-deg", 1).setValue(steeringAssistance.steeringLimit * R2D);
print("Steering Travel Set To Normal");
});
addcommand("setSteeringTravelToMax", func() {
steeringAssistance.steeringLimit = 15.707963;
props.getNode("/controls/steering_wheel/steering_limit-deg", 1).setValue(steeringAssistance.steeringLimit * R2D);
print("Steering Travel Set To Max");
});