我使用名为KRPC的插件来传输来自游戏ksp的数据,这里的python脚本是krpc的文档:https://krpc.github.io/krpc/ 从来没有使用我的程序显示的数据和游戏结束的数据之间的延迟,直到我多线程我的程序现在我得到了第二次延迟。多线程我的python程序很重要,因为它似乎阻止了脚本挂起或崩溃。我无法弄清楚造成延误的原因。我的python脚本在树莓派上运行,所以我试图保持低CPU使用率
from threading import Thread
import time
import Adafruit_Nokia_LCD as LCD
import Adafruit_GPIO.SPI as SPI
import krpc
import RPi.GPIO as GPIO
from pad4pi import rpi_gpio
from UUGear import *
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
GPIO.setwarnings(False)
try:
device = UUGearDevice('UUGear-Arduino-5343-9628')
if not device.isValid():
exit()
KEYPAD = [
[1,2,3],
[4,5,6],
[7,8,9],
["*",0,"#"]
]
ROW_PINS = [4,5,12,16] # BCM numbering
COL_PINS = [26,6,13] # BCM numbering
global pressedkey
pressedkey = '0'
factory = rpi_gpio.KeypadFactory()
# Try factory.create_4_by_3_keypad
# and factory.create_4_by_4_keypad for reasonable defaults
keypad = factory.create_keypad(keypad=KEYPAD, row_pins=ROW_PINS, col_pins=COL_PINS)
def procKey(key):
print(key)
global pressedkey
pressedkey = str(key)
# printKey will be called each time a keypad button is pressed
keypad.registerKeyPressHandler(procKey)
# Raspberry Pi hardware SPI config:
DC = 23
RST = 24
SPI_PORT = 0
SPI_DEVICE = 0
# Hardware SPI usage:
disp = LCD.PCD8544(DC, RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=4000000))
# Software SPI usage (defaults to bit-bang SPI interface):
#disp = LCD.PCD8544(DC, RST, SCLK, DIN, CS)
# Initialize library.
disp.begin(contrast=60)
disp.clear()
disp.display()
image = Image.new('1', (LCD.LCDWIDTH, LCD.LCDHEIGHT))
draw = ImageDraw.Draw(image)
# Load default font.
font = ImageFont.load_default()
draw.rectangle((0,0,83,47), outline=255, fill=255)
draw.text((15,0), 'Loading...', font=font)
disp.image(image)
disp.display()
conn = krpc.connect(name='rpi', address='192.168.0.10', rpc_port=50000, stream_port=50001)
vessel = conn.space_center.active_vessel
draw.rectangle((0,0,83,47), outline=255, fill=255)
draw.text((0,0), '--FLIGHT SYS--', font=font)
draw.text((3,10), '1 - Surface', font=font)
draw.text((3,20), '2 - Orbit', font=font)
disp.image(image)
disp.display()
device.setPinModeAsInput(9)
device.setPinModeAsInput(2)
device.setPinModeAsInput(3)
device.setPinModeAsInput(4)
device.setPinModeAsOutput(12)
vessel.control.sas = False
prev_input_stage = 0
prev_input_parachute = 0
input_stage = '0'
input_parachute = '0'
def screen():
global apoapsis
global periapsis
global altitude
global pressedkey
global draw
global font
global disp
global conn
global vessel
ut = conn.add_stream(getattr, conn.space_center, 'ut')
altitude = conn.add_stream(getattr, vessel.flight(), 'mean_altitude')
apoapsis = conn.add_stream(getattr, vessel.orbit, 'apoapsis_altitude')
periapsis = conn.add_stream(getattr, vessel.orbit, 'periapsis_altitude')
while True:
print 'AP:', apoapsis()
print 'Pe:', periapsis()
print 'Alt:', altitude()
#for parachute in vessel.parts.parachutes:
# print parachute.state
if pressedkey == '2':
draw.rectangle((0,0,83,47), outline=255, fill=255)
if abs(apoapsis()) < 1000:
draw.text((0,0), 'Ap:' + str(round(apoapsis(), 2)) + 'M', font=font)
else:
draw.text((0,0), 'Ap:' + str(round(apoapsis()/1000, 2)) + 'KM', font=font)
if abs(periapsis()) < 1000:
draw.text((0,10), 'Pe:' + str(round(periapsis(), 2)) + 'M', font=font)
else:
draw.text((0,10), 'Pe:' + str(round(periapsis()/1000, 2)) + 'KM', font=font)
if pressedkey == '1':
draw.rectangle((0,0,83,47), outline=255, fill=255)
if abs(altitude()) < 1000:
draw.text((0,0), 'Alt:' + str(round(altitude(), 2)) + 'M', font=font)
else:
draw.text((0,0), 'Alt:' + str(round(altitude()/1000, 2)) + 'KM', font=font)
if pressedkey == '#':
draw.rectangle((0,0,83,47), outline=255, fill=255)
draw.text((0,0), '--FLIGHT SYS--', font=font)
draw.text((3,10), '1 - Surface', font=font)
draw.text((3,20), '2 - Orbit', font=font)
disp.image(image)
disp.display()
def hardware():
global input_stage
global prev_input_stage
global vessel
global device
global input_parachute
global prev_input_parachute
while True:
input_stage = not device.getPinStatus(9)
if ((not prev_input_stage) and input_stage):
vessel.control.activate_next_stage()
print("stage")
print 'Pin 9 status=', device.getPinStatus(9)
prev_input_stage = input_stage
input_parachute = not device.getPinStatus(2)
if ((not prev_input_parachute) and input_parachute):
for parachute in vessel.parts.parachutes:
parachute.deploy()
print("Parachute")
print 'Pin 2 status=', device.getPinStatus(2)
#print(device.analogRead(3))
prev_input_parachute = input_parachute
vessel.control.sas = not device.getPinStatus(4)
if vessel.control.sas == True:
device.setPinHigh(12)
else:
device.setPinLow(12)
for engines in vessel.parts.engines:
if engines.gimballed == True:
engines.gimbal_locked = bool(device.getPinStatus(3))
time.sleep(0.2)
t1 = Thread(target = screen)
t2 = Thread(target = hardware)
t1.start()
t2.start()
t1.join()
t2.join()
except:
print 'Interrupted'
print 'Cleaning up'
GPIO.cleanup()
device.detach()
device.stopDaemon()
keypad.cleanup()