Port cycle_to_external_air mode for airlock controllers.

* Adds a flag to controllers that instructs the airlock program to always purge between IN/OUT and also to pump air to "outside" instead of tanks when purging to go OUT.
* Tweak the way the airlock fudges target pressures so it more reliably operates when trying to pump down to vacuum.
* Adds an exterior airlock sensor that reads the air pressure in *front* of it, so it can be mounted on a shuttle but measure air outside the shuttle.
This commit is contained in:
Leshana
2018-02-04 15:05:08 -05:00
parent 9db9681663
commit 4c910f0f2e
4 changed files with 64 additions and 17 deletions

View File

@@ -218,6 +218,13 @@ obj/machinery/airlock_sensor/airlock_interior
obj/machinery/airlock_sensor/airlock_exterior obj/machinery/airlock_sensor/airlock_exterior
command = "cycle_exterior" command = "cycle_exterior"
// Return the air from the turf in "front" of us (Used in shuttles, so it can be in the shuttle area but sense outside it)
obj/machinery/airlock_sensor/airlock_exterior/shuttle/return_air()
var/turf/T = get_step(src, dir)
if(isnull(T))
return ..()
return T.return_air()
obj/machinery/access_button obj/machinery/access_button
icon = 'icons/obj/airlock_machines.dmi' icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_button_standby" icon_state = "access_button_standby"

View File

@@ -11,6 +11,7 @@
var/tag_airlock_mech_sensor var/tag_airlock_mech_sensor
var/tag_shuttle_mech_sensor var/tag_shuttle_mech_sensor
var/tag_secure = 0 var/tag_secure = 0
var/cycle_to_external_air = 0
/obj/machinery/embedded_controller/radio/airlock/initialize() /obj/machinery/embedded_controller/radio/airlock/initialize()
. = ..() . = ..()

View File

@@ -9,6 +9,8 @@
#define TARGET_INOPEN -1 #define TARGET_INOPEN -1
#define TARGET_OUTOPEN -2 #define TARGET_OUTOPEN -2
#define MIN_TARGET_PRESSURE (ONE_ATMOSPHERE * 0.05) // Never try to pump to pure vacuum, its not happening.
#define SKIPCYCLE_MARGIN 1 // Skip cycling airlock (just open the doors) if pressures are within this range.
/datum/computer/file/embedded_program/airlock /datum/computer/file/embedded_program/airlock
var/tag_exterior_door var/tag_exterior_door
@@ -23,6 +25,10 @@
var/state = STATE_IDLE var/state = STATE_IDLE
var/target_state = TARGET_NONE var/target_state = TARGET_NONE
var/cycle_to_external_air = 0
var/tag_pump_out_external
var/tag_pump_out_internal
/datum/computer/file/embedded_program/airlock/New(var/obj/machinery/embedded_controller/M) /datum/computer/file/embedded_program/airlock/New(var/obj/machinery/embedded_controller/M)
..(M) ..(M)
@@ -38,6 +44,10 @@
if (istype(M, /obj/machinery/embedded_controller/radio/airlock)) //if our controller is an airlock controller than we can auto-init our tags if (istype(M, /obj/machinery/embedded_controller/radio/airlock)) //if our controller is an airlock controller than we can auto-init our tags
var/obj/machinery/embedded_controller/radio/airlock/controller = M var/obj/machinery/embedded_controller/radio/airlock/controller = M
cycle_to_external_air = controller.cycle_to_external_air
if(cycle_to_external_air)
tag_pump_out_external = "[id_tag]_pump_out_external"
tag_pump_out_internal = "[id_tag]_pump_out_internal"
tag_exterior_door = controller.tag_exterior_door? controller.tag_exterior_door : "[id_tag]_outer" tag_exterior_door = controller.tag_exterior_door? controller.tag_exterior_door : "[id_tag]_outer"
tag_interior_door = controller.tag_interior_door? controller.tag_interior_door : "[id_tag]_inner" tag_interior_door = controller.tag_interior_door? controller.tag_interior_door : "[id_tag]_inner"
tag_airpump = controller.tag_airpump? controller.tag_airpump : "[id_tag]_pump" tag_airpump = controller.tag_airpump? controller.tag_airpump : "[id_tag]_pump"
@@ -74,7 +84,7 @@
memory["interior_status"]["state"] = signal.data["door_status"] memory["interior_status"]["state"] = signal.data["door_status"]
memory["interior_status"]["lock"] = signal.data["lock_status"] memory["interior_status"]["lock"] = signal.data["lock_status"]
else if(receive_tag==tag_airpump) else if(receive_tag==tag_airpump || receive_tag==tag_pump_out_internal)
if(signal.data["power"]) if(signal.data["power"])
memory["pump_status"] = signal.data["direction"] memory["pump_status"] = signal.data["direction"]
else else
@@ -110,7 +120,7 @@
switch(command) switch(command)
if("cycle_ext") if("cycle_ext")
//If airlock is already cycled in this direction, just toggle the doors. //If airlock is already cycled in this direction, just toggle the doors.
if(!memory["purge"] && IsInRange(memory["external_sensor_pressure"], memory["chamber_sensor_pressure"] * 0.95, memory["chamber_sensor_pressure"] * 1.05)) if(!memory["purge"] && abs(memory["external_sensor_pressure"] - memory["chamber_sensor_pressure"]) <= SKIPCYCLE_MARGIN)
toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "toggle") toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "toggle")
//only respond to these commands if the airlock isn't already doing something //only respond to these commands if the airlock isn't already doing something
//prevents the controller from getting confused and doing strange things //prevents the controller from getting confused and doing strange things
@@ -118,7 +128,7 @@
begin_cycle_out() begin_cycle_out()
if("cycle_int") if("cycle_int")
if(!memory["purge"] && IsInRange(memory["internal_sensor_pressure"], memory["chamber_sensor_pressure"] * 0.95, memory["chamber_sensor_pressure"] * 1.05)) if(!memory["purge"] && abs(memory["internal_sensor_pressure"] - memory["chamber_sensor_pressure"]) <= SKIPCYCLE_MARGIN)
toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "toggle") toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "toggle")
else if(state == target_state) else if(state == target_state)
begin_cycle_in() begin_cycle_in()
@@ -156,6 +166,10 @@
if(shutdown_pump) if(shutdown_pump)
signalPump(tag_airpump, 0) //send a signal to stop pressurizing signalPump(tag_airpump, 0) //send a signal to stop pressurizing
if(cycle_to_external_air)
signalPump(tag_pump_out_internal, 0)
signalPump(tag_pump_out_external, 0)
/datum/computer/file/embedded_program/airlock/process() /datum/computer/file/embedded_program/airlock/process()
@@ -175,6 +189,9 @@
//make sure to return to a sane idle state //make sure to return to a sane idle state
if(memory["pump_status"] != "off") //send a signal to stop pumping if(memory["pump_status"] != "off") //send a signal to stop pumping
signalPump(tag_airpump, 0) signalPump(tag_airpump, 0)
if(cycle_to_external_air)
signalPump(tag_pump_out_internal, 0)
signalPump(tag_pump_out_external, 0)
if ((state == STATE_PRESSURIZE || state == STATE_DEPRESSURIZE) && !check_doors_secured()) if ((state == STATE_PRESSURIZE || state == STATE_DEPRESSURIZE) && !check_doors_secured())
//the airlock will not allow itself to continue to cycle when any of the doors are forced open. //the airlock will not allow itself to continue to cycle when any of the doors are forced open.
@@ -190,24 +207,37 @@
//purge apparently means clearing the airlock chamber to vacuum (then refilling, handled later) //purge apparently means clearing the airlock chamber to vacuum (then refilling, handled later)
target_pressure = 0 target_pressure = 0
state = STATE_DEPRESSURIZE state = STATE_DEPRESSURIZE
signalPump(tag_airpump, 1, 0, 0) //send a signal to start depressurizing if(!cycle_to_external_air || target_state == TARGET_OUTOPEN) // if going outside, pump internal air into air tank
signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing
else
signalPump(tag_pump_out_internal, 1, 0, target_pressure) // if going inside, pump external air out of the airlock
signalPump(tag_pump_out_external, 1, 1, 15000) // make sure the air is actually going outside
else if(chamber_pressure <= target_pressure) else if(chamber_pressure <= target_pressure)
state = STATE_PRESSURIZE state = STATE_PRESSURIZE
signalPump(tag_airpump, 1, 1, target_pressure) //send a signal to start pressurizing if(!cycle_to_external_air || target_state == TARGET_INOPEN) // if going inside, pump air into airlock
signalPump(tag_airpump, 1, 1, target_pressure) //send a signal to start pressurizing
else
signalPump(tag_pump_out_internal, 1, 1, target_pressure) // if going outside, fill airlock with external air
signalPump(tag_pump_out_external, 1, 0, 0)
else if(chamber_pressure > target_pressure) else if(chamber_pressure > target_pressure)
state = STATE_DEPRESSURIZE if(!cycle_to_external_air)
signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing state = STATE_DEPRESSURIZE
signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing
else
memory["purge"] = 1 // should always purge first if using external air, chamber pressure should never be higher than target pressure here
//Make sure the airlock isn't aiming for pure vacuum - an impossibility //Make sure the airlock isn't aiming for pure vacuum - an impossibility
memory["target_pressure"] = max(target_pressure, ONE_ATMOSPHERE * 0.05) memory["target_pressure"] = max(target_pressure, MIN_TARGET_PRESSURE)
if(STATE_PRESSURIZE) if(STATE_PRESSURIZE)
if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95) if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
//not done until the pump has reported that it's off //not done until the pump has reported that it's off
if(memory["pump_status"] != "off") if(memory["pump_status"] != "off")
signalPump(tag_airpump, 0) //send a signal to stop pumping signalPump(tag_airpump, 0) //send a signal to stop pumping
if(cycle_to_external_air)
signalPump(tag_pump_out_internal, 0)
signalPump(tag_pump_out_external, 0)
else else
cycleDoors(target_state) cycleDoors(target_state)
state = STATE_IDLE state = STATE_IDLE
@@ -215,15 +245,17 @@
if(STATE_DEPRESSURIZE) if(STATE_DEPRESSURIZE)
if(memory["chamber_sensor_pressure"] <= memory["target_pressure"] * 1.05) if(memory["chamber_sensor_pressure"] <= max(memory["target_pressure"] * 1.05, MIN_TARGET_PRESSURE))
if(memory["purge"]) if(memory["pump_status"] != "off")
memory["purge"] = 0
memory["target_pressure"] = memory["internal_sensor_pressure"]
state = STATE_PREPARE
target_state = TARGET_NONE
else if(memory["pump_status"] != "off")
signalPump(tag_airpump, 0) signalPump(tag_airpump, 0)
if(cycle_to_external_air)
signalPump(tag_pump_out_internal, 0)
signalPump(tag_pump_out_external, 0)
else if(memory["purge"])
memory["purge"] = 0
memory["target_pressure"] = (target_state == TARGET_INOPEN ? memory["internal_sensor_pressure"] : memory["external_sensor_pressure"])
if (memory["target_pressure"] > SKIPCYCLE_MARGIN)
state = STATE_PREPARE // Skip pressurizing if target pressure is already close enough.
else else
cycleDoors(target_state) cycleDoors(target_state)
state = STATE_IDLE state = STATE_IDLE
@@ -239,10 +271,12 @@
/datum/computer/file/embedded_program/airlock/proc/begin_cycle_in() /datum/computer/file/embedded_program/airlock/proc/begin_cycle_in()
state = STATE_IDLE state = STATE_IDLE
target_state = TARGET_INOPEN target_state = TARGET_INOPEN
memory["purge"] = cycle_to_external_air
/datum/computer/file/embedded_program/airlock/proc/begin_cycle_out() /datum/computer/file/embedded_program/airlock/proc/begin_cycle_out()
state = STATE_IDLE state = STATE_IDLE
target_state = TARGET_OUTOPEN target_state = TARGET_OUTOPEN
memory["purge"] = cycle_to_external_air
/datum/computer/file/embedded_program/airlock/proc/close_doors() /datum/computer/file/embedded_program/airlock/proc/close_doors()
toggleDoor(memory["interior_status"], tag_interior_door, 1, "close") toggleDoor(memory["interior_status"], tag_interior_door, 1, "close")
@@ -368,6 +402,7 @@ send an additional command to open the door again.
if(doorCommand) if(doorCommand)
signalDoor(doorTag, doorCommand) signalDoor(doorTag, doorCommand)
#undef SKIPCYCLE_MARGIN
#undef STATE_IDLE #undef STATE_IDLE
#undef STATE_DEPRESSURIZE #undef STATE_DEPRESSURIZE

View File

@@ -0,0 +1,4 @@
author: Leshana and mustafakalash
delete-after: True
changes:
- rscadd: "A new 'planetary' mode for airlocks which makes them purge the chamber contents to the exterior atmosphere before filling with clean air, and vice versa."