adding the autopilot
parent
d05e656b5e
commit
a262544f03
|
@ -1,7 +1,8 @@
|
|||
--global constants
|
||||
hidroplane.last_time_command = 0
|
||||
hidroplane.vector_up = vector.new(0, 1, 0)
|
||||
hidroplane.ideal_step = 0.02
|
||||
hidroplane.rudder_limit = 30
|
||||
hidroplane.elevator_limit = 40
|
||||
|
||||
dofile(minetest.get_modpath("hidroplane") .. DIR_DELIM .. "hidroplane_utilities.lua")
|
||||
|
||||
|
@ -16,15 +17,41 @@ function hidroplane.check_node_below(obj)
|
|||
return touching_ground, liquid_below
|
||||
end
|
||||
|
||||
function hidroplane.powerAdjust(self,dtime,factor,dir,max_power)
|
||||
local max = max_power or 100
|
||||
local add_factor = factor
|
||||
add_factor = add_factor * (dtime/hidroplane.ideal_step) --adjusting the command speed by dtime
|
||||
local power_index = self._power_lever
|
||||
|
||||
if dir == 1 then
|
||||
if self._power_lever < max then
|
||||
self._power_lever = self._power_lever + add_factor
|
||||
end
|
||||
if self._power_lever > max then
|
||||
self._power_lever = max
|
||||
end
|
||||
end
|
||||
if dir == -1 then
|
||||
if self._power_lever > 0 then
|
||||
self._power_lever = self._power_lever - add_factor
|
||||
if self._power_lever < 0 then self._power_lever = 0 end
|
||||
end
|
||||
if self._power_lever <= 0 then
|
||||
self._power_lever = 0
|
||||
end
|
||||
end
|
||||
if power_index ~= self._power_lever then
|
||||
hidroplane.engineSoundPlay(self)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function hidroplane.control(self, dtime, hull_direction, longit_speed, longit_drag,
|
||||
later_speed, later_drag, accel, player, is_flying)
|
||||
hidroplane.last_time_command = hidroplane.last_time_command + dtime
|
||||
if hidroplane.last_time_command > 1 then hidroplane.last_time_command = 1 end
|
||||
--if self.driver_name == nil then return end
|
||||
local retval_accel = accel
|
||||
|
||||
local rudder_limit = 30
|
||||
local elevator_limit = 40
|
||||
local stop = false
|
||||
|
||||
-- player control
|
||||
|
@ -36,6 +63,7 @@ function hidroplane.control(self, dtime, hull_direction, longit_speed, longit_dr
|
|||
hidroplane.last_time_command = 0
|
||||
if self._engine_running then
|
||||
self._engine_running = false
|
||||
self._autopilot = false
|
||||
-- sound and animation
|
||||
if self.sound_handle then
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
|
@ -46,10 +74,7 @@ function hidroplane.control(self, dtime, hull_direction, longit_speed, longit_dr
|
|||
elseif self._engine_running == false and self._energy > 0 then
|
||||
self._engine_running = true
|
||||
-- sound and animation
|
||||
self.sound_handle = minetest.sound_play({name = "hidroplane_engine"},
|
||||
{object = self.object, gain = 2.0,
|
||||
pitch = 0.5 + ((self._power_lever/100)/2),max_hear_distance = 32,
|
||||
loop = true,})
|
||||
hidroplane.engineSoundPlay(self)
|
||||
self.engine:set_animation_frame_speed(60)
|
||||
end
|
||||
end
|
||||
|
@ -60,32 +85,15 @@ function hidroplane.control(self, dtime, hull_direction, longit_speed, longit_dr
|
|||
local engineacc = (self._power_lever * hidroplane.max_engine_acc) / 100;
|
||||
self.engine:set_animation_frame_speed(60 + self._power_lever)
|
||||
|
||||
local add_factor = 1
|
||||
add_factor = add_factor * (dtime/hidroplane.ideal_step) --adjusting the command speed by dtime
|
||||
local factor = 1
|
||||
|
||||
--increase power lever
|
||||
if ctrl.jump then
|
||||
if self._power_lever < 100 then
|
||||
self._power_lever = self._power_lever + add_factor
|
||||
end
|
||||
if self._power_lever > 100 then
|
||||
self._power_lever = 100
|
||||
engineacc = hidroplane.max_engine_acc
|
||||
else
|
||||
--sound
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = minetest.sound_play({name = "hidroplane_engine"},
|
||||
{object = self.object, gain = 2.0,
|
||||
pitch = 0.5 + ((self._power_lever/100)/2),max_hear_distance = 32,
|
||||
loop = true,})
|
||||
end
|
||||
hidroplane.powerAdjust(self, dtime, factor, 1)
|
||||
end
|
||||
--decrease power lever
|
||||
if ctrl.sneak then
|
||||
if self._power_lever > 0 then
|
||||
self._power_lever = self._power_lever - add_factor
|
||||
if self._power_lever < 0 then self._power_lever = 0 end
|
||||
end
|
||||
hidroplane.powerAdjust(self, dtime, factor, -1)
|
||||
if self._power_lever <= 0 and is_flying == false then
|
||||
--break
|
||||
if longit_speed >= 0.1 then
|
||||
|
@ -97,13 +105,6 @@ function hidroplane.control(self, dtime, hull_direction, longit_speed, longit_dr
|
|||
if abs(longit_speed) < 0.1 then
|
||||
stop = true
|
||||
end
|
||||
else
|
||||
--sound
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = minetest.sound_play({name = "hidroplane_engine"},
|
||||
{object = self.object, gain = 2.0,
|
||||
pitch = 0.5 + ((self._power_lever/100)/2),max_hear_distance = 32,
|
||||
loop = true,})
|
||||
end
|
||||
end
|
||||
--do not exceed
|
||||
|
@ -128,21 +129,14 @@ function hidroplane.control(self, dtime, hull_direction, longit_speed, longit_dr
|
|||
retval_accel=vector.add(retval_accel,hull_acc)
|
||||
|
||||
--pitch
|
||||
local pitch_factor = 10
|
||||
if ctrl.down then
|
||||
self._elevator_angle = math.max(self._elevator_angle-pitch_factor*dtime,-elevator_limit)
|
||||
elseif ctrl.up then
|
||||
if self._angle_of_attack < 0 then pitch_factor = 1 end --lets reduce the command power to avoid accidents
|
||||
self._elevator_angle = math.min(self._elevator_angle+pitch_factor*dtime,elevator_limit)
|
||||
end
|
||||
local pitch_cmd = 0
|
||||
if ctrl.up then pitch_cmd = 1 elseif ctrl.down then pitch_cmd = -1 end
|
||||
hidroplane.set_pitch(self, pitch_cmd, dtime)
|
||||
|
||||
-- yaw
|
||||
local yaw_factor = 30
|
||||
if ctrl.right then
|
||||
self._rudder_angle = math.max(self._rudder_angle-yaw_factor*dtime,-rudder_limit)
|
||||
elseif ctrl.left then
|
||||
self._rudder_angle = math.min(self._rudder_angle+yaw_factor*dtime,rudder_limit)
|
||||
end
|
||||
local yaw_cmd = 0
|
||||
if ctrl.right then yaw_cmd = 1 elseif ctrl.left then yaw_cmd = -1 end
|
||||
hidroplane.set_yaw(self, yaw_cmd, dtime)
|
||||
|
||||
--I'm desperate, center all!
|
||||
if ctrl.right and ctrl.left then
|
||||
|
@ -152,19 +146,109 @@ function hidroplane.control(self, dtime, hull_direction, longit_speed, longit_dr
|
|||
end
|
||||
|
||||
if longit_speed > 0 then
|
||||
local factor = 1
|
||||
if self._rudder_angle > 0 then factor = -1 end
|
||||
local correction = (rudder_limit*(longit_speed/1000)) * factor
|
||||
self._rudder_angle = self._rudder_angle + correction
|
||||
|
||||
factor = 1
|
||||
--if self._elevator_angle > -1.5 then factor = -1 end --here is the "compensator" adjusto to keep it stable
|
||||
if self._elevator_angle > 0 then factor = -1 end
|
||||
correction = (elevator_limit/10) * factor * dtime
|
||||
self._elevator_angle = self._elevator_angle + correction
|
||||
hidroplane.rudder_elevator_auto_correction(self, longit_speed, dtime)
|
||||
end
|
||||
|
||||
return retval_accel, stop
|
||||
end
|
||||
|
||||
function hidroplane.set_pitch(self, dir, dtime)
|
||||
local pitch_factor = 10
|
||||
if dir == -1 then
|
||||
self._elevator_angle = math.max(self._elevator_angle-pitch_factor*dtime,-hidroplane.elevator_limit)
|
||||
elseif dir == 1 then
|
||||
if self._angle_of_attack < 0 then pitch_factor = 1 end --lets reduce the command power to avoid accidents
|
||||
self._elevator_angle = math.min(self._elevator_angle+pitch_factor*dtime,hidroplane.elevator_limit)
|
||||
end
|
||||
end
|
||||
|
||||
function hidroplane.set_yaw(self, dir, dtime)
|
||||
local yaw_factor = 30
|
||||
if dir == 1 then
|
||||
self._rudder_angle = math.max(self._rudder_angle-yaw_factor*dtime,-hidroplane.rudder_limit)
|
||||
elseif dir == -1 then
|
||||
self._rudder_angle = math.min(self._rudder_angle+yaw_factor*dtime,hidroplane.rudder_limit)
|
||||
end
|
||||
end
|
||||
|
||||
function hidroplane.rudder_elevator_auto_correction(self, longit_speed, dtime)
|
||||
local factor = 1
|
||||
if self._rudder_angle > 0 then factor = -1 end
|
||||
local correction = (hidroplane.rudder_limit*(longit_speed/1000)) * factor
|
||||
self._rudder_angle = self._rudder_angle + correction
|
||||
|
||||
factor = 1
|
||||
--if self._elevator_angle > -1.5 then factor = -1 end --here is the "compensator" adjusto to keep it stable
|
||||
if self._elevator_angle > 0 then factor = -1 end
|
||||
correction = (hidroplane.elevator_limit/10) * factor * dtime
|
||||
self._elevator_angle = self._elevator_angle + correction
|
||||
end
|
||||
|
||||
function hidroplane.engineSoundPlay(self)
|
||||
--sound
|
||||
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
|
||||
self.sound_handle = minetest.sound_play({name = "hidroplane_engine"},
|
||||
{object = self.object, gain = 2.0,
|
||||
pitch = 0.5 + ((self._power_lever/100)/2),max_hear_distance = 32,
|
||||
loop = true,})
|
||||
end
|
||||
|
||||
function getAdjustFactor(curr_y, desired_y)
|
||||
local max_difference = 0.1
|
||||
local adjust_factor = 0.5
|
||||
local difference = math.abs(curr_y - desired_y)
|
||||
if difference > max_difference then difference = max_difference end
|
||||
return (difference * adjust_factor) / max_difference
|
||||
end
|
||||
|
||||
function hidroplane.autopilot(self, dtime, hull_direction,
|
||||
longit_speed, longit_drag, later_speed, later_drag, accel, pilot, is_flying, curr_pos)
|
||||
|
||||
local retval_accel = accel
|
||||
|
||||
local max_autopilot_power = 85
|
||||
local max_attack_angle = 1.8
|
||||
|
||||
self._acceleration = 0
|
||||
if self._engine_running then
|
||||
--engine acceleration calc
|
||||
local engineacc = (self._power_lever * hidroplane.max_engine_acc) / 100;
|
||||
self.engine:set_animation_frame_speed(60 + self._power_lever)
|
||||
|
||||
local factor = getAdjustFactor(curr_pos.y, self._auto_pilot_altitude)
|
||||
--increase power lever
|
||||
if self._auto_pilot_altitude < curr_pos.y then
|
||||
hidroplane.powerAdjust(self, dtime, factor, -1)
|
||||
end
|
||||
--decrease power lever
|
||||
if self._auto_pilot_altitude > curr_pos.y then
|
||||
hidroplane.powerAdjust(self, dtime, factor, 1, max_autopilot_power)
|
||||
end
|
||||
--do not exceed
|
||||
local max_speed = 6
|
||||
if longit_speed > max_speed then
|
||||
engineacc = engineacc - (longit_speed-max_speed)
|
||||
if engineacc < 0 then engineacc = 0 end
|
||||
end
|
||||
self._acceleration = engineacc
|
||||
end
|
||||
|
||||
local hull_acc = vector.multiply(hull_direction,self._acceleration)
|
||||
retval_accel=vector.add(retval_accel,hull_acc)
|
||||
|
||||
--pitch
|
||||
if self._angle_of_attack > max_attack_angle then
|
||||
hidroplane.set_pitch(self, 1, dtime)
|
||||
elseif self._angle_of_attack < max_attack_angle then
|
||||
hidroplane.set_pitch(self, -1, dtime)
|
||||
end
|
||||
|
||||
-- yaw
|
||||
hidroplane.set_yaw(self, 0, dtime)
|
||||
|
||||
if longit_speed > 0 then
|
||||
hidroplane.rudder_elevator_auto_correction(self, longit_speed, dtime)
|
||||
end
|
||||
|
||||
return retval_accel
|
||||
end
|
||||
|
|
|
@ -278,6 +278,8 @@ minetest.register_entity("hidroplane:hidro", {
|
|||
_show_hud = false,
|
||||
_instruction_mode = false, --flag to intruction mode
|
||||
_command_is_given = false, --flag to mark the "owner" of the commands now
|
||||
_autopilot = false,
|
||||
_auto_pilot_altitude = 0,
|
||||
|
||||
get_staticdata = function(self) -- unloaded/unloads ... is now saved
|
||||
return minetest.serialize({
|
||||
|
@ -509,6 +511,7 @@ minetest.register_entity("hidroplane:hidro", {
|
|||
else
|
||||
--give the control to the pax
|
||||
if self._passenger then
|
||||
self._autopilot = false
|
||||
hidroplane.transfer_control(self, true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,7 @@ function hidroplane.consumptionCalc(self, accel)
|
|||
end
|
||||
if self._energy <= 0 and self._engine_running and accel ~= nil then
|
||||
self._engine_running = false
|
||||
self._autopilot = false
|
||||
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
|
||||
self.engine:set_animation_frame_speed(0)
|
||||
end
|
||||
|
|
|
@ -12,3 +12,4 @@ HIDROPLANE_GAUGE_POWER_POSITION = {x=2.35,y=1.55,z=10.64}
|
|||
HIDROPLANE_GAUGE_CLIMBER_POSITION = {x=-2.05,y=1.40,z=10.64}
|
||||
HIDROPLANE_GAUGE_SPEED_POSITION = {x=-0.25,y=1.40,z=10.64}
|
||||
|
||||
hidroplane.last_time_command = 0
|
||||
|
|
|
@ -37,8 +37,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
"* Forward: go down flying - nose down \n",
|
||||
"* Left/right: Turn to left/right, work on and out ground. \n",
|
||||
"* Left and Right together: center all commands \n",
|
||||
"* Sneak and Jump together: give/take the controls to/from \n",
|
||||
" pilot student \n",
|
||||
"* Sneak and Jump together (normal): activates de autopilot \n",
|
||||
"* Sneak and Jump together (instruction mode): give/take the \n",
|
||||
" controls to/from pilot student \n",
|
||||
"* Up and Down together: enable/disable HUD"
|
||||
}
|
||||
local shortcut_form = table.concat({
|
||||
|
@ -106,15 +107,16 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
"automatically extend. \n",
|
||||
"When boarding the aircraft, centralize the commands (A \n",
|
||||
"and D keys), press E to start the engine and hold Jump \n",
|
||||
"until the power reaches maximum. When the speed \n",
|
||||
"reaches the green range, lightly pull the stick using the S \n",
|
||||
"key. Always keep the speed within the green range to \n",
|
||||
"avoid stalling. To land, remove all power, but keep the \n",
|
||||
"speed at the limit between the green and white range, \n",
|
||||
"still in the green. When you are about to touch the soil or \n",
|
||||
"water, lightly pull the stick to level and touch it gently. \n",
|
||||
"It's possible to operate with an external camera, \n",
|
||||
"activating the HUD. \n",
|
||||
"until full power. When the speed reaches the green range, \n",
|
||||
"lightly pull the stick using the S key. Always keep the \n",
|
||||
"speed within the green range to avoid stalling. To land, \n",
|
||||
"remove all power, but keep the speed at the limit \n",
|
||||
"between the green and white range. \n",
|
||||
"When you are about to touch the soil or water, lightly pull \n",
|
||||
"the stick to level and touch it gently. It's possible to \n",
|
||||
"operate with an external camera, activating the HUD. \n",
|
||||
"The autopilot (jump and sneak) only keeps the airplane at the \n",
|
||||
"activation level, limited by power and designed ceiling. \n",
|
||||
"It's possible for a passenger to board the aircraft, just \n",
|
||||
"click the right button on the floater. But the passenger \n",
|
||||
"will only be able to enter if the pilot has already boarded."
|
||||
|
@ -124,7 +126,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
"size[16,10]",
|
||||
"background[-0.7,-0.5;17.5,11.5;hidroplane_manual_bg.png]",
|
||||
"image[0.5,1.75;6,6;hidroplane_manual_side_view.png]",
|
||||
"label[9.25,0.5;", table.concat(text, ""), "]",
|
||||
"label[9.25,0.25;", table.concat(text, ""), "]",
|
||||
}, "")
|
||||
minetest.show_formspec(player:get_player_name(), "hidroplane:op", op_form)
|
||||
end
|
||||
|
|
|
@ -356,6 +356,7 @@ function hidroplane.checkattachBug(self)
|
|||
end
|
||||
else
|
||||
if self._passenger ~= nil and self._command_is_given == false then
|
||||
self._autopilot = false
|
||||
hidroplane.transfer_control(self, true)
|
||||
end
|
||||
end
|
||||
|
@ -412,6 +413,14 @@ function hidroplane.transfer_control(self, status)
|
|||
end
|
||||
|
||||
function hidroplane.flightstep(self)
|
||||
local velocity = self.object:get_velocity()
|
||||
--hack to avoid glitches
|
||||
self.object:set_velocity(velocity)
|
||||
local curr_pos = self.object:get_pos()
|
||||
self.object:set_pos(curr_pos)
|
||||
|
||||
|
||||
hidroplane.last_time_command = hidroplane.last_time_command + self.dtime
|
||||
local player = nil
|
||||
if self.driver_name then player = minetest.get_player_by_name(self.driver_name) end
|
||||
local passenger = nil
|
||||
|
@ -419,7 +428,9 @@ function hidroplane.flightstep(self)
|
|||
|
||||
if player then
|
||||
local ctrl = player:get_player_control()
|
||||
---------------------
|
||||
-- change the driver
|
||||
---------------------
|
||||
if passenger and hidroplane.last_time_command >= 1 and self._instruction_mode == true then
|
||||
if self._command_is_given == true then
|
||||
if ctrl.sneak or ctrl.jump or ctrl.up or ctrl.down or ctrl.right or ctrl.left then
|
||||
|
@ -435,7 +446,28 @@ function hidroplane.flightstep(self)
|
|||
end
|
||||
end
|
||||
end
|
||||
-----------
|
||||
--autopilot
|
||||
-----------
|
||||
if self._instruction_mode == false and hidroplane.last_time_command >= 1 then
|
||||
if self._autopilot == true then
|
||||
if ctrl.sneak or ctrl.jump or ctrl.up or ctrl.down or ctrl.right or ctrl.left then
|
||||
hidroplane.last_time_command = 0
|
||||
self._autopilot = false
|
||||
minetest.chat_send_player(self.driver_name," >>> Autopilot deactivated")
|
||||
end
|
||||
else
|
||||
if ctrl.sneak == true and ctrl.jump == true then
|
||||
hidroplane.last_time_command = 0
|
||||
self._autopilot = true
|
||||
self._auto_pilot_altitude = curr_pos.y
|
||||
minetest.chat_send_player(self.driver_name,core.colorize('#00ff00', " >>> Autopilot on"))
|
||||
end
|
||||
end
|
||||
end
|
||||
----------------------------------
|
||||
-- shows the hud for the player
|
||||
----------------------------------
|
||||
if ctrl.up == true and ctrl.down == true and hidroplane.last_time_command >= 1 then
|
||||
hidroplane.last_time_command = 0
|
||||
if self._show_hud == true then
|
||||
|
@ -456,7 +488,6 @@ function hidroplane.flightstep(self)
|
|||
if newroll > 360 then newroll = newroll - 360 end
|
||||
if newroll < -360 then newroll = newroll + 360 end
|
||||
|
||||
local velocity = self.object:get_velocity()
|
||||
local hull_direction = mobkit.rot_to_dir(rotation) --minetest.yaw_to_dir(yaw)
|
||||
local nhdir = {x=hull_direction.z,y=0,z=-hull_direction.x} -- lateral unit vector
|
||||
|
||||
|
@ -471,11 +502,6 @@ function hidroplane.flightstep(self)
|
|||
local accel = vector.add(longit_drag,later_drag)
|
||||
local stop = false
|
||||
|
||||
--hack to avoid glitches
|
||||
self.object:set_velocity(velocity)
|
||||
local curr_pos = self.object:get_pos()
|
||||
self.object:set_pos(curr_pos)
|
||||
|
||||
local node_bellow = mobkit.nodeatpos(mobkit.pos_shift(curr_pos,{y=-3}))
|
||||
local is_flying = true
|
||||
if node_bellow and node_bellow.drawtype ~= 'airlike' then is_flying = false end
|
||||
|
@ -496,6 +522,8 @@ function hidroplane.flightstep(self)
|
|||
self._elevator_angle = self._elevator_angle + 0.1
|
||||
end --limiting the very high climb angle due to strange behavior]]--
|
||||
|
||||
--minetest.chat_send_all(self._angle_of_attack)
|
||||
|
||||
-- pitch
|
||||
local speed_factor = 0
|
||||
if longit_speed > hidroplane.min_speed then speed_factor = (velocity.y * math.rad(2)) end
|
||||
|
@ -558,8 +586,6 @@ function hidroplane.flightstep(self)
|
|||
---------------------------------
|
||||
-- end roll
|
||||
|
||||
--accell calculation
|
||||
--control
|
||||
if not is_attached then
|
||||
-- for some engine error the player can be detached from the machine, so lets set him attached again
|
||||
hidroplane.checkattachBug(self)
|
||||
|
@ -571,9 +597,18 @@ function hidroplane.flightstep(self)
|
|||
else
|
||||
self._command_is_given = false
|
||||
end
|
||||
|
||||
------------------------------------------------------
|
||||
--accell calculation block
|
||||
------------------------------------------------------
|
||||
if is_attached or passenger then
|
||||
accel, stop = hidroplane.control(self, self.dtime, hull_direction,
|
||||
longit_speed, longit_drag, later_speed, later_drag, accel, pilot, is_flying)
|
||||
if self._autopilot ~= true then
|
||||
accel, stop = hidroplane.control(self, self.dtime, hull_direction,
|
||||
longit_speed, longit_drag, later_speed, later_drag, accel, pilot, is_flying)
|
||||
else
|
||||
accel = hidroplane.autopilot(self, self.dtime, hull_direction,
|
||||
longit_speed, longit_drag, later_speed, later_drag, accel, pilot, is_flying, curr_pos)
|
||||
end
|
||||
end
|
||||
|
||||
--end accell
|
||||
|
@ -605,6 +640,9 @@ function hidroplane.flightstep(self)
|
|||
elseif stop == false then
|
||||
self.object:set_velocity({x=0,y=0,z=0})
|
||||
end
|
||||
------------------------------------------------------
|
||||
-- end accell
|
||||
------------------------------------------------------
|
||||
|
||||
--self.object:get_luaentity() --hack way to fix jitter on climb
|
||||
|
||||
|
|
Loading…
Reference in New Issue