Наработки за 5 лет
This commit is contained in:
366
HXbot/HX.py
Executable file
366
HXbot/HX.py
Executable file
@@ -0,0 +1,366 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot utility module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
# I2C bus
|
||||
I2C_BUS_NUMBER = 2
|
||||
EXT_COM = 0xAA
|
||||
XOR_SEQ = 0xFF
|
||||
|
||||
# VAR
|
||||
REFLEX_ADDRESS = 0x04
|
||||
REFLEX_RESPONSE_DELAY = 0.1 # Delay to get response after send command, sec
|
||||
REFLEX_ERROR_LIMIT = 5
|
||||
REFLEX_MOVE_TIMEOUT = 60
|
||||
|
||||
# COMMANDS
|
||||
# Util
|
||||
COM_PING = 0x01
|
||||
COM_GET_TEMP = 0x02
|
||||
COM_GET_DISTANCE = 0x03
|
||||
|
||||
# Stop
|
||||
STOP = 0x0F
|
||||
# Move
|
||||
MOVE_FLAG = 0x04
|
||||
MOVE_FLOAT = 0x10
|
||||
MOVE_FWD1 = 0x11
|
||||
MOVE_FWD2 = 0x12
|
||||
MOVE_FWD3 = 0x13
|
||||
MOVE_FWD4 = 0x14
|
||||
MOVE_FWD5 = 0x15
|
||||
MOVE_FWD6 = 0x16
|
||||
MOVE_FWD7 = 0x17
|
||||
MOVE_BREAK = 0x18
|
||||
MOVE_REV7 = 0x19
|
||||
MOVE_REV6 = 0x1A
|
||||
MOVE_REV5 = 0x1B
|
||||
MOVE_REV4 = 0x1C
|
||||
MOVE_REV3 = 0x1D
|
||||
MOVE_REV2 = 0x1E
|
||||
MOVE_REV1 = 0x1F
|
||||
|
||||
# Steering
|
||||
STEER_FLAG = 0x05
|
||||
STEER_CENTER = 0x20
|
||||
STEER_LEFT1 = 0x21
|
||||
STEER_LEFT2 = 0x22
|
||||
STEER_LEFT3 = 0x23
|
||||
STEER_LEFT4 = 0x24
|
||||
STEER_LEFT5 = 0x25
|
||||
STEER_LEFT6 = 0x26
|
||||
STEER_LEFT7 = 0x27
|
||||
STEER_FIX_CENTER = 0x28
|
||||
STEER_RIGHT7 = 0x29
|
||||
STEER_RIGHT6 = 0x2A
|
||||
STEER_RIGHT5 = 0x2B
|
||||
STEER_RIGHT4 = 0x2C
|
||||
STEER_RIGHT3 = 0x2D
|
||||
STEER_RIGHT2 = 0x2E
|
||||
STEER_RIGHT1 = 0x2F
|
||||
|
||||
# Head
|
||||
HEAD_H_FLAG = 0x30
|
||||
HEAD_V_FLAG = 0x31
|
||||
HEAD_H_R_RANGE = 83
|
||||
HEAD_H_L_RANGE = 94
|
||||
HEAD_V_UP_RANGE = 90
|
||||
HEAD_V_DOWN_RANGE = 25
|
||||
HEAD_H_CENTER = 83
|
||||
HEAD_V_CENTER = 150
|
||||
|
||||
# CONTROL SOURCE
|
||||
CONTROL_SRC_NONE = 0x00
|
||||
CONTROL_SRC_JOYSTICK = 0x01
|
||||
CONTROL_SRC_IRREMOTE = 0x02
|
||||
CONTROL_SRC_SERVER = 0x03
|
||||
CONTROL_SRC_DB = 0x04
|
||||
CONTROL_SRC_SUB1 = 0x11
|
||||
CONTROL_SRC_SUB2 = 0x12
|
||||
CONTROL_SRC_SUB3 = 0x13
|
||||
CONTROL_SRC_SUB4 = 0x14
|
||||
CONTROL_SRC_SUB5 = 0x15
|
||||
|
||||
CONTROL_SRC_DEFAULT = CONTROL_SRC_JOYSTICK
|
||||
|
||||
# MOVE STATES
|
||||
MOVE_STATE_STOP = 0x00
|
||||
MOVE_STATE_MOVE = 0x01
|
||||
|
||||
# STATUS
|
||||
STATUS_INIT = 0x00
|
||||
STATUS_READY = 0x01
|
||||
STATUS_RUNNING = 0x02
|
||||
STATUS_STOP = 0x03
|
||||
STATUS_EXIT = 0x04
|
||||
|
||||
# STATUS STATES
|
||||
#STATUS_STATE_OK = 0x00
|
||||
#STATUS_STATE_WARNING = 0x01
|
||||
#STATUS_STATE_ERROR = 0x02
|
||||
#STATUS_STATE_LOWBAT1 = 0x03
|
||||
#STATUS_STATE_LOWBAT2 = 0x04
|
||||
|
||||
# JOYSTICK
|
||||
JOYSTICK_PATH = '/dev/input/js0'
|
||||
JOYSTICK_READY_TIMEOUT = 60
|
||||
|
||||
# These constants were borrowed from linux/input.h
|
||||
JOYSTICK_AXIS_NAMES = {
|
||||
0x00: 'x',
|
||||
0x01: 'y',
|
||||
0x02: 'z',
|
||||
0x03: 'rx',
|
||||
0x04: 'ry',
|
||||
0x05: 'rz',
|
||||
0x06: 'trottle',
|
||||
0x07: 'rudder',
|
||||
0x08: 'wheel',
|
||||
0x09: 'gas',
|
||||
0x0a: 'brake',
|
||||
0x10: 'hat0x',
|
||||
0x11: 'hat0y',
|
||||
0x12: 'hat1x',
|
||||
0x13: 'hat1y',
|
||||
0x14: 'hat2x',
|
||||
0x15: 'hat2y',
|
||||
0x16: 'hat3x',
|
||||
0x17: 'hat3y',
|
||||
0x18: 'pressure',
|
||||
0x19: 'distance',
|
||||
0x1a: 'tilt_x',
|
||||
0x1b: 'tilt_y',
|
||||
0x1c: 'tool_width',
|
||||
0x20: 'volume',
|
||||
0x28: 'misc',
|
||||
}
|
||||
|
||||
JOYSTICK_BUTTON_NAMES = {
|
||||
0x120: 'trigger',
|
||||
0x121: 'thumb',
|
||||
0x122: 'thumb2',
|
||||
0x123: 'top',
|
||||
0x124: 'top2',
|
||||
0x125: 'pinkie',
|
||||
0x126: 'base',
|
||||
0x127: 'base2',
|
||||
0x128: 'base3',
|
||||
0x129: 'base4',
|
||||
0x12a: 'base5',
|
||||
0x12b: 'base6',
|
||||
0x12f: 'dead',
|
||||
0x130: 'a',
|
||||
0x131: 'b',
|
||||
0x132: 'c',
|
||||
0x133: 'x',
|
||||
0x134: 'y',
|
||||
0x135: 'z',
|
||||
0x136: 'tl',
|
||||
0x137: 'tr',
|
||||
0x138: 'tl2',
|
||||
0x139: 'tr2',
|
||||
0x13a: 'select',
|
||||
0x13b: 'start',
|
||||
0x13c: 'mode',
|
||||
0x13d: 'thumbl',
|
||||
0x13e: 'thumbr',
|
||||
|
||||
0x220: 'dpad_up',
|
||||
0x221: 'dpad_down',
|
||||
0x222: 'dpad_left',
|
||||
0x223: 'dpad_right',
|
||||
|
||||
# XBox 360 controller uses these codes.
|
||||
0x2c0: 'dpad_left',
|
||||
0x2c1: 'dpad_right',
|
||||
0x2c2: 'dpad_up',
|
||||
0x2c3: 'dpad_down',
|
||||
}
|
||||
|
||||
# JOYSTICK BINDS
|
||||
JOYSTICK_MOVE_AXIS = 'y'
|
||||
JOYSTICK_STEER_AXIS = 'x'
|
||||
JOYSTICK_HEAD_V_AXIS = 'rz'
|
||||
JOYSTICK_HEAD_H_AXIS = 'z'
|
||||
JOYSTICK_START_BTN_1 = 'tl2'
|
||||
JOYSTICK_START_BTN_2 = 'tr2'
|
||||
|
||||
# HXpower
|
||||
POWER_ADDRESS = 0x05
|
||||
POWER_RESPONSE_DELAY = 0.05 # Delay to get response after send command, sec
|
||||
POWER_DELAY = 0.3
|
||||
POWER_ERROR_LIMIT = 3
|
||||
POWER_MV_TIMEOUT = 60
|
||||
|
||||
# Commands
|
||||
# VOLTMETERS
|
||||
COM_GET_VIN = 0x01
|
||||
COM_GET_VDC = 0x02
|
||||
COM_GET_VBT = 0x03
|
||||
COM_GET_VBA = 0x04
|
||||
COM_GET_VPF = 0x05
|
||||
COM_GET_VZU = 0x06
|
||||
COM_GET_VCC = 0x07
|
||||
|
||||
# AMPERMETERS
|
||||
COM_GET_ABT = 0x21
|
||||
COM_GET_ABA = 0x22
|
||||
COM_GET_AIN = 0x23
|
||||
COM_GET_AHX = 0x24
|
||||
|
||||
# STATUS
|
||||
COM_GET_STAT1 = 0x08
|
||||
# 0x01 - vcc_ok
|
||||
# 0x02 - vin_ok
|
||||
# 0x04 - vdc_ok
|
||||
# 0x08 - vbt_ok
|
||||
# 0x10 - vba_ok
|
||||
# 0x20 - bt_enabled
|
||||
# 0x40 - ba_enabled
|
||||
# 0x80 - in_plugged
|
||||
|
||||
COM_GET_STAT2 = 0x09
|
||||
# 0x01 - bt_blocked
|
||||
# 0x02 - ba_blocked
|
||||
# 0x04 - bt_full
|
||||
# 0x08 - ba_full
|
||||
# 0x10 - vpf_ok
|
||||
# 0x20 - vzu_ok
|
||||
# 0x40 - mv_enabled
|
||||
# 0x80 - us_enabled
|
||||
|
||||
COM_GET_STAT3 = 0x20
|
||||
# 0x01 - abt_ok
|
||||
# 0x02 - aba_ok
|
||||
# 0x04 - ain_ok
|
||||
# 0x08 - ahx_ok
|
||||
|
||||
# TEMP
|
||||
COM_GET_POWER_TEMP = 0x10
|
||||
|
||||
VIN_MIN = 10.0
|
||||
VIN_MAX = 14.0
|
||||
VIN_LOW = 11.0
|
||||
VIN_HIGH = 13.0
|
||||
|
||||
VDC_MIN = 5.0
|
||||
VDC_MAX = 5.7
|
||||
VDC_LOW = 5.1
|
||||
VDC_HIGH = 5.5
|
||||
|
||||
VBT_MIN = 3.65
|
||||
VBT_MAX = 4.25
|
||||
VBT_LOW = 3.68
|
||||
VBT_FULL = 4.1
|
||||
|
||||
VBA_MIN = 9.0
|
||||
VBA_MAX = 12.8
|
||||
VBA_LOW = 10.0
|
||||
VBA_FULL = 12.4
|
||||
|
||||
VPF_MIN = 7.2
|
||||
VPF_MAX = 10.0
|
||||
VPF_LOW = 8.0
|
||||
VPF_HIGH = 9.6
|
||||
|
||||
VZU_MIN = 5.0
|
||||
VZU_MAX = 6.3
|
||||
VZU_LOW = 5.2
|
||||
VZU_HIGH = 6.2
|
||||
|
||||
VCC_MIN = 4.5
|
||||
VCC_MAX = 5.3
|
||||
VCC_LOW = 4.7
|
||||
VCC_HIGH = 5.1
|
||||
|
||||
ABT_MIN = 0.3
|
||||
ABT_MAX = 2.0
|
||||
ABT_LOW = 0.4
|
||||
ABT_HIGH = 1.2
|
||||
|
||||
ABA_MIN = 0.05
|
||||
ABA_MAX = 2.0
|
||||
ABA_LOW = 0.5
|
||||
ABA_HIGH = 1.5
|
||||
|
||||
AIN_MIN = 0.05
|
||||
AIN_MAX = 2.0
|
||||
AIN_LOW = 0.1
|
||||
AIN_HIGH = 1.5
|
||||
|
||||
AHX_MIN = 0.05
|
||||
AHX_MAX = 3.0
|
||||
AHX_LOW = 0.1
|
||||
AHX_HIGH = 1.5
|
||||
|
||||
# RELAYS
|
||||
COM_ENABLE_BA = 0x11 # 17
|
||||
COM_ENABLE_MV = 0x12 # 18
|
||||
COM_ENABLE_BT = 0x13 # 19
|
||||
COM_ENABLE_US = 0x14 # 20
|
||||
|
||||
COM_DISABLE_BA = 0x15 # 21
|
||||
COM_DISABLE_MV = 0x16 # 22
|
||||
COM_DISABLE_BT = 0x17 # 23
|
||||
COM_DISABLE_US = 0x18 # 24
|
||||
|
||||
COM_RUN = 0x1B # 27
|
||||
COM_STOP = 0x1C # 28
|
||||
COM_RESET_US = 0x1D # 29
|
||||
|
||||
# HXserver
|
||||
SRV_PORT = 50306
|
||||
SRV_HOST = ''
|
||||
SRV_CMD_GET_ALL = 0x01
|
||||
SRV_TIMEOUT = 1
|
||||
SRV_MAX_ERR_COUNT = 3
|
||||
|
||||
# RETURN CODES
|
||||
# Universal return codes
|
||||
OK_RSP = 0x00
|
||||
NO_RSP = 0xFF
|
||||
ERR_RSP = 0x01
|
||||
BLK_RSP = 0x02
|
||||
CSE_RSP = 0x03
|
||||
IOE_RSP = 0x04
|
||||
TMO_RSP = 0x05
|
||||
|
||||
# HXbot modul flags
|
||||
I2C_BUS_ERR = 0x0001
|
||||
HXPOWER_ERR = 0x0002
|
||||
REFLEX_ERR = 0x0004
|
||||
SERVER_ERR = 0x0008
|
||||
|
||||
JOYSTICK_WRN = 0x0010
|
||||
HXCAMERA_WRN = 0x0020
|
||||
HXLCD_WRN = 0x0040
|
||||
HXDB_WRN = 0x0080
|
||||
HXLIGHT_WRN = 0x0100
|
||||
HXSOUND_WRN = 0x0200
|
||||
HXLOG_WRN = 0x0400
|
||||
|
||||
# HXlcd
|
||||
LCD_ADDRESS = 0x06
|
||||
LCD_ERROR_LIMIT = 5
|
||||
LCD_DELAY = 1
|
||||
LCD_RESPONSE_DELAY = 0.05
|
||||
|
||||
# HXcam
|
||||
CAM_MAX_WRN_COUNT = 3
|
||||
CAM_DELAY = 1.0
|
||||
|
||||
CAM_STATE_STP = 0
|
||||
CAM_STATE_RUN = 1
|
||||
CAM_STATE_WRN = 2
|
||||
CAM_STATE_ERR = 3
|
||||
|
||||
# HXdb
|
||||
DB_DELAY = 10.0
|
||||
|
||||
DB_HOST = 'localhost'
|
||||
DB_NAME = 'hxdb'
|
||||
DB_USER = 'hxdb'
|
||||
DB_PASS = 'hxdbP@S$'
|
||||
711
HXbot/HXbot.py
Executable file
711
HXbot/HXbot.py
Executable file
@@ -0,0 +1,711 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot main program #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import HX
|
||||
import REflex
|
||||
import HXjoystick
|
||||
import HXpower
|
||||
import HXserver
|
||||
import HXcam
|
||||
import HXlcd
|
||||
import HXdb
|
||||
import time
|
||||
import smbus
|
||||
import sys
|
||||
import threading
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
|
||||
# MAIN CLASS
|
||||
class HXbotClass():
|
||||
|
||||
def __init__(self):
|
||||
super(HXbotClass, self).__init__()
|
||||
|
||||
self.i2c_bus = None
|
||||
self.hxpower = None
|
||||
self.reflex = None
|
||||
self.server = None
|
||||
|
||||
self.joystick = None
|
||||
self.hxcam = None
|
||||
self.hxlcd = None
|
||||
self.hxdb = None
|
||||
self.light = None
|
||||
self.sound = None
|
||||
self.log = None
|
||||
|
||||
self.status = HX.STATUS_INIT
|
||||
|
||||
self.hxpower_lock = threading.Lock()
|
||||
self.reflex_lock = threading.Lock()
|
||||
self.hxlcd_lock = threading.Lock()
|
||||
self.hxdb_lock = threading.Lock()
|
||||
|
||||
def get_ready(self):
|
||||
result = HX.OK_RSP
|
||||
|
||||
# Init I2C bus
|
||||
try:
|
||||
self.i2c_bus = smbus.SMBus(HX.I2C_BUS_NUMBER)
|
||||
except IOError:
|
||||
self.stop()
|
||||
return result | HX.I2C_BUS_ERR
|
||||
|
||||
# Init hxpower
|
||||
try:
|
||||
self.hxpower = HXpower.HXpowerClass(self.i2c_bus, self.hxpower_lock)
|
||||
except IOError:
|
||||
self.stop()
|
||||
return result | HX.HXPOWER_ERR
|
||||
|
||||
# Init reflex
|
||||
try:
|
||||
self.reflex = REflex.REflexClass(self)
|
||||
except IOError:
|
||||
self.stop()
|
||||
return result | HX.REFLEX_ERR
|
||||
|
||||
# Init server
|
||||
try:
|
||||
self.server = HXserver.HXserverClass(self)
|
||||
except OSError:
|
||||
self.stop()
|
||||
return result | HX.SERVER_ERR
|
||||
|
||||
# Init joystick
|
||||
try:
|
||||
self.joystick = HXjoystick.HXjoystickClass()
|
||||
except OSError:
|
||||
#self.joystick.stop()
|
||||
#self.joystick = None
|
||||
result |= HX.JOYSTICK_WRN
|
||||
|
||||
# Init hxcam
|
||||
try:
|
||||
self.hxcam = HXcam.HXcamClass()
|
||||
except OSError:
|
||||
self.hxcam.stop()
|
||||
self.hxcam = None
|
||||
result |= HX.HXCAMERA_WRN
|
||||
|
||||
# Init hxlcd
|
||||
try:
|
||||
self.hxlcd = HXlcd.HXlcdClass(self.i2c_bus, self.hxlcd_lock)
|
||||
except OSError:
|
||||
self.hxlcd.stop()
|
||||
self.hxlcd = None
|
||||
result |= HX.HXLCD_WRN
|
||||
|
||||
# Init hxdb
|
||||
try:
|
||||
self.hxdb = HXdb.HXdbClass(self)
|
||||
except Exception:
|
||||
#self.hxdb.stop()
|
||||
self.hxdb = None
|
||||
result |= HX.HXDB_WRN
|
||||
|
||||
# Init GPIO
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
#GPIO.setup(25, GPIO.OUT)
|
||||
|
||||
# Set status
|
||||
self.status = True
|
||||
|
||||
return result
|
||||
|
||||
def start(self):
|
||||
if self.status != HX.STATUS_READY:
|
||||
return HX.BLK_RSP
|
||||
|
||||
# Start hxpower
|
||||
self.hxpower.start()
|
||||
|
||||
# Start reflex
|
||||
self.reflex.start()
|
||||
|
||||
# Start server
|
||||
self.server.start()
|
||||
|
||||
# Start joystick
|
||||
if self.joystick is not None:
|
||||
self.joystick.start()
|
||||
|
||||
# Start camera
|
||||
if self.hxcam is not None:
|
||||
self.hxcam.start()
|
||||
|
||||
# Start lcd
|
||||
if self.hxlcd is not None:
|
||||
self.hxlcd.start()
|
||||
|
||||
# Start db
|
||||
if self.hxdb is not None:
|
||||
self.hxdb.start()
|
||||
|
||||
self.status = HX.STATUS_RUNNING
|
||||
|
||||
return HX.OK_RSP
|
||||
|
||||
def stop(self):
|
||||
# Disable MV
|
||||
self.hxpower.disable_mv()
|
||||
|
||||
# Disable camera
|
||||
if self.hxcam:
|
||||
# Stop process
|
||||
if self.hxcam.is_running:
|
||||
self.hxcam.stop()
|
||||
# Clear property
|
||||
self.hxcam = None
|
||||
|
||||
# Stop reflex
|
||||
if self.reflex:
|
||||
# Stop process
|
||||
if self.reflex.is_running:
|
||||
self.reflex.stop()
|
||||
# Clear property
|
||||
self.reflex = None
|
||||
|
||||
# Stop joystick
|
||||
if self.joystick:
|
||||
# Stop process
|
||||
if self.joystick.is_running:
|
||||
self.joystick.stop()
|
||||
# Clear property
|
||||
self.joystick = None
|
||||
|
||||
# Stop server
|
||||
if self.server:
|
||||
# Stop process
|
||||
if self.server.is_running:
|
||||
self.server.stop()
|
||||
# Clear property
|
||||
self.server = None
|
||||
|
||||
# Stop hxpower
|
||||
if self.hxpower:
|
||||
# Stop process
|
||||
if self.hxpower.is_running:
|
||||
self.hxpower.stop()
|
||||
# Clear property
|
||||
self.hxpower = None
|
||||
|
||||
# Stop hxlcd
|
||||
if self.hxlcd:
|
||||
# Stop process
|
||||
if self.hxlcd.is_running:
|
||||
self.hxlcd.stop()
|
||||
# Clear property
|
||||
self.hxlcd = None
|
||||
|
||||
# Stop hxdb
|
||||
if self.hxdb:
|
||||
# Stop process
|
||||
if self.hxdb.is_running:
|
||||
self.hxdb.stop()
|
||||
# Clear property
|
||||
self.hxdb = None
|
||||
|
||||
# Close I2C bus
|
||||
if self.i2c_bus:
|
||||
self.i2c_bus.close()
|
||||
# Clear property
|
||||
self.i2c_bus = None
|
||||
|
||||
# Set status
|
||||
self.status = HX.STATUS_STOP
|
||||
|
||||
GPIO.cleanup()
|
||||
|
||||
return HX.OK_RSP
|
||||
|
||||
def get_temp(self):
|
||||
try:
|
||||
F = open("/sys/class/thermal/thermal_zone0/temp", "r")
|
||||
T = float(F.read())
|
||||
except IOError:
|
||||
return -999
|
||||
finally:
|
||||
F.close()
|
||||
|
||||
return T / 1000
|
||||
|
||||
|
||||
# MAIN PROGRAM
|
||||
def main():
|
||||
# INIT
|
||||
print("Hi! I'am HXbot. Let's fun!'")
|
||||
print("Type command or \"help\"")
|
||||
|
||||
# Create HXbot instance
|
||||
hxbot = HXbotClass()
|
||||
|
||||
# Run
|
||||
start(hxbot)
|
||||
|
||||
# MAIN LOOP
|
||||
while True:
|
||||
# Set command line view
|
||||
if hxbot.status == HX.STATUS_INIT:
|
||||
command_view = "INIT>"
|
||||
elif hxbot.status == HX.STATUS_READY:
|
||||
command_view = "READY>"
|
||||
elif hxbot.status == HX.STATUS_RUNNING:
|
||||
command_view = "RUNNING>"
|
||||
elif hxbot.status == HX.STATUS_STOP:
|
||||
command_view = "STOP>"
|
||||
elif hxbot.status == HX.STATUS_EXIT:
|
||||
command_view = "EXIT>"
|
||||
|
||||
command = input(command_view)
|
||||
|
||||
# COMMANDS
|
||||
# Help
|
||||
if command.lower() == "help":
|
||||
print_help()
|
||||
|
||||
# Exit / Quit
|
||||
elif command.lower() == "exit" or \
|
||||
command.lower() == "quit":
|
||||
stop(hxbot)
|
||||
hxbot.status = HX.STATUS_EXIT
|
||||
print("Exit...")
|
||||
sys.exit()
|
||||
|
||||
# Status
|
||||
elif command.lower() == "status":
|
||||
print_status(hxbot)
|
||||
# REflex control
|
||||
elif command.lower() == "reflex":
|
||||
reflex_control(hxbot)
|
||||
# HXpower control
|
||||
elif command.lower() == "hxpower":
|
||||
hxpower_control(hxbot)
|
||||
# HXcam control
|
||||
elif command.lower() == "hxcam":
|
||||
hxcam_control(hxbot)
|
||||
|
||||
# Get ready
|
||||
elif command.lower() == "ready":
|
||||
ready(hxbot)
|
||||
# Start
|
||||
elif command.lower() == "start":
|
||||
start(hxbot)
|
||||
# Stop
|
||||
elif command.lower() == "stop":
|
||||
stop(hxbot)
|
||||
# Restart
|
||||
elif command.lower() == "restart":
|
||||
restart(hxbot)
|
||||
|
||||
# Test
|
||||
elif command.lower() == "t":
|
||||
t1 = time.clock()
|
||||
print("t1:", t1)
|
||||
time.sleep(5)
|
||||
t2 = time.clock()
|
||||
print("t2:", t2)
|
||||
dt = t2 - t1
|
||||
print("dt:", dt)
|
||||
|
||||
# WAT?
|
||||
else:
|
||||
print("WRONG COMMAND")
|
||||
print("Try again or type \"help\"")
|
||||
|
||||
# EXIT
|
||||
sys.exit()
|
||||
|
||||
|
||||
# FUNCTIONS
|
||||
def ready(hxbot):
|
||||
if hxbot.status != HX.STATUS_READY:
|
||||
print("Get ready...")
|
||||
result = hxbot.get_ready()
|
||||
print_result(result)
|
||||
else:
|
||||
print("HXbot already ready")
|
||||
|
||||
|
||||
def start(hxbot):
|
||||
if hxbot.status != HX.STATUS_RUNNING:
|
||||
if hxbot.status != HX.STATUS_READY:
|
||||
ready(hxbot)
|
||||
|
||||
print("Start...")
|
||||
result = hxbot.start()
|
||||
print_result(result)
|
||||
else:
|
||||
print("HXbot already running")
|
||||
|
||||
|
||||
def stop(hxbot):
|
||||
if hxbot.status != HX.STATUS_STOP:
|
||||
print("Stop...")
|
||||
result = hxbot.stop()
|
||||
print_result(result)
|
||||
else:
|
||||
print("HXbot already stopped")
|
||||
|
||||
|
||||
def restart(hxbot):
|
||||
stop(hxbot)
|
||||
ready(hxbot)
|
||||
start(hxbot)
|
||||
|
||||
|
||||
def print_help():
|
||||
print("This is HXbot main program. You can type this commands:")
|
||||
print("help - this help")
|
||||
print("exit |")
|
||||
print("quit - stop HXbot and exit")
|
||||
print("status - get status")
|
||||
print("start - start HXbot")
|
||||
print("stop - stop HXbot")
|
||||
print("restart - stop HXbot")
|
||||
print("reflex - control REflex")
|
||||
print("hxpower - control HXpower")
|
||||
|
||||
|
||||
def hxpower_help():
|
||||
print("This is HXpower control program. You can type this commands:")
|
||||
print("help - this help")
|
||||
print("exit - main menu")
|
||||
print("bt - switch BT")
|
||||
print("ba - switch BA")
|
||||
print("mv - enable/disable moving")
|
||||
print("us - enable/disable USB")
|
||||
print("0-255 - send raw command")
|
||||
|
||||
|
||||
def hxcam_help():
|
||||
print("This is HXcam control program. You can type this commands:")
|
||||
print("help - this help")
|
||||
print("exit - main menu")
|
||||
print("start - start HXcam")
|
||||
print("stop - stop HXcam")
|
||||
print("restart - restart HXcam")
|
||||
|
||||
|
||||
def reflex_help():
|
||||
print("This is REflex control program. You can type this commands:")
|
||||
print("help - this help")
|
||||
print("exit - main menu")
|
||||
print("0-255 - send raw command")
|
||||
|
||||
|
||||
def print_result(result):
|
||||
# Universal return codes
|
||||
if result == HX.OK_RSP:
|
||||
print("OK")
|
||||
elif result == HX.NO_RSP:
|
||||
print("WARNING: No response")
|
||||
elif result == HX.ERR_RSP:
|
||||
print("ERROR")
|
||||
elif result == HX.BLK_RSP:
|
||||
print("ERROR: Blocked")
|
||||
elif result == HX.CSE_RSP:
|
||||
print("ERROR: Wrong control sum")
|
||||
elif result == HX.BLK_RSP:
|
||||
print("ERROR: ")
|
||||
elif result == HX.IOE_RSP:
|
||||
print("ERROR: Input/output error")
|
||||
elif result == HX.TMO_RSP:
|
||||
print("ERROR: Timeout")
|
||||
|
||||
# HXbot extended return codes
|
||||
elif result == HX.I2C_BUS_ERR:
|
||||
print("ERROR: I2C bus not ready")
|
||||
elif result == HX.HXPOWER_ERR:
|
||||
print("ERROR: HXpower not ready")
|
||||
elif result == HX.JOYSTICK_WRN:
|
||||
print("WARNING: Joystick not found")
|
||||
elif result == HX.REFLEX_ERR:
|
||||
print("ERROR: REflex not ready")
|
||||
elif result == HX.SERVER_ERR:
|
||||
print("ERROR: Server not ready")
|
||||
elif result == HX.HXCAMERA_WRN:
|
||||
print("WARNING: Camera not ready")
|
||||
elif result == HX.HXLCD_WRN:
|
||||
print("WARNING: LCD module not ready")
|
||||
elif result == HX.HXDB_WRN:
|
||||
print("WARNING: DB module not ready")
|
||||
|
||||
# Unknown return code
|
||||
else:
|
||||
print("WARNING: Unknown return code received")
|
||||
|
||||
|
||||
def print_status(hxbot):
|
||||
if (hxbot.status != HX.STATUS_READY and
|
||||
hxbot.status != HX.STATUS_RUNNING):
|
||||
print("HXbot is not in ready or running state!")
|
||||
return
|
||||
|
||||
# Print voltages
|
||||
print("Vcc =", hxbot.hxpower.vcc)
|
||||
print("Vin =", hxbot.hxpower.vin)
|
||||
print("Vdc =", hxbot.hxpower.vdc)
|
||||
print("Vbt =", hxbot.hxpower.vbt)
|
||||
print("Vba =", hxbot.hxpower.vba)
|
||||
print("Vpf =", hxbot.hxpower.vpf)
|
||||
print("Vzu =", hxbot.hxpower.vzu)
|
||||
|
||||
# Print currents
|
||||
print("Abt =", hxbot.hxpower.abt)
|
||||
print("Aba =", hxbot.hxpower.aba)
|
||||
print("Ain =", hxbot.hxpower.ain)
|
||||
print("Ahx =", hxbot.hxpower.ahx)
|
||||
|
||||
# Print temperature
|
||||
print("CPU Temp:", hxbot.get_temp())
|
||||
print("REflex Temp:", hxbot.reflex.get_temp())
|
||||
#print("HXPower Temp:", )
|
||||
|
||||
# Print status
|
||||
if hxbot.hxpower.vcc_ok:
|
||||
print("Vcc - OK")
|
||||
else:
|
||||
print("Vcc - FAIL")
|
||||
if hxbot.hxpower.vin_ok:
|
||||
print("Vin - OK")
|
||||
else:
|
||||
print("Vin - FAIL")
|
||||
if hxbot.hxpower.vdc_ok:
|
||||
print("Vdc - OK")
|
||||
else:
|
||||
print("Vdc - FAIL")
|
||||
if hxbot.hxpower.vbt_ok:
|
||||
print("Vbt - OK")
|
||||
else:
|
||||
print("Vbt - FAIL")
|
||||
if hxbot.hxpower.vba_ok:
|
||||
print("Vba - OK")
|
||||
else:
|
||||
print("Vba - FAIL")
|
||||
if hxbot.hxpower.vpf_ok:
|
||||
print("Vpf - OK")
|
||||
else:
|
||||
print("Vpf - FAIL")
|
||||
if hxbot.hxpower.vzu_ok:
|
||||
print("Vzu - OK")
|
||||
else:
|
||||
print("Vzu - FAIL")
|
||||
|
||||
if hxbot.hxpower.abt_ok:
|
||||
print("Abt - OK")
|
||||
else:
|
||||
print("Abt - FAIL")
|
||||
if hxbot.hxpower.aba_ok:
|
||||
print("Aba - OK")
|
||||
else:
|
||||
print("Aba - FAIL")
|
||||
if hxbot.hxpower.ain_ok:
|
||||
print("Ain - OK")
|
||||
else:
|
||||
print("Ain - FAIL")
|
||||
if hxbot.hxpower.ahx_ok:
|
||||
print("Ahx - OK")
|
||||
else:
|
||||
print("Ahx - FAIL")
|
||||
|
||||
if hxbot.hxpower.bt_enabled:
|
||||
print("BT enabled")
|
||||
else:
|
||||
print("BT disabled")
|
||||
if hxbot.hxpower.ba_enabled:
|
||||
print("BA enabled")
|
||||
else:
|
||||
print("BA disabled")
|
||||
if hxbot.hxpower.mv_enabled:
|
||||
print("mv enabled")
|
||||
else:
|
||||
print("PF disabled")
|
||||
if hxbot.hxpower.us_enabled:
|
||||
print("USB power enabled")
|
||||
else:
|
||||
print("USB power disabled")
|
||||
if hxbot.hxpower.bt_blocked:
|
||||
print("BT blocked")
|
||||
else:
|
||||
print("BT unblocked")
|
||||
if hxbot.hxpower.ba_blocked:
|
||||
print("BA blocked")
|
||||
else:
|
||||
print("BA unblocked")
|
||||
|
||||
if hxbot.hxpower.in_plugged:
|
||||
print("IN plugged")
|
||||
else:
|
||||
print("IN unplugged")
|
||||
|
||||
if hxbot.hxpower.bt_full:
|
||||
print("BT charge complete")
|
||||
if hxbot.hxpower.ba_full:
|
||||
print("BA charge complete")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def reflex_control(hxbot):
|
||||
if (hxbot.status != HX.STATUS_READY and
|
||||
hxbot.status != HX.STATUS_RUNNING):
|
||||
print("HXbot is not in ready or running state!")
|
||||
return
|
||||
|
||||
rawCommand = 0x00
|
||||
rawResponse = 0x00
|
||||
|
||||
print("Reflex control program. Type command or \"help\"")
|
||||
print("Type \"exit\" to previous menu")
|
||||
command_view = "REflex control>"
|
||||
|
||||
while True:
|
||||
command = input(command_view)
|
||||
if command.lower() == "exit":
|
||||
break
|
||||
elif command.lower() == "help":
|
||||
reflex_help()
|
||||
else:
|
||||
# Try to send RAW command to REflex
|
||||
try:
|
||||
rawCommand = int(command)
|
||||
except:
|
||||
rawCommand = 0x00
|
||||
|
||||
if not rawCommand:
|
||||
continue
|
||||
|
||||
with hxbot.reflex_lock:
|
||||
hxbot.i2c_bus.write_byte(HX.REFLEX_ADDRESS, rawCommand)
|
||||
print("Sent: ", rawCommand)
|
||||
time.sleep(HX.REFLEX_RESPONSE_DELAY)
|
||||
rawResponse = hxbot.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
|
||||
print("Received: ", rawResponse)
|
||||
|
||||
|
||||
def hxpower_control(hxbot):
|
||||
if (hxbot.status != HX.STATUS_READY and
|
||||
hxbot.status != HX.STATUS_RUNNING):
|
||||
print("HXbot is not in ready or running state!")
|
||||
return
|
||||
|
||||
rawCommand = 0x00
|
||||
rawResponse = 0x00
|
||||
|
||||
print("HXpower control program. Type command or \"help\"")
|
||||
print("Type \"exit\" to previous menu")
|
||||
command_view = "HXpower control>"
|
||||
|
||||
while True:
|
||||
command = input(command_view)
|
||||
if command.lower() == "exit":
|
||||
break
|
||||
elif command.lower() == "help":
|
||||
hxpower_help()
|
||||
elif command.lower() == "bt":
|
||||
if hxbot.hxpower.bt_enabled:
|
||||
print("Disable BT...")
|
||||
result = hxbot.hxpower.disable_bt()
|
||||
else:
|
||||
print("Enable BT...")
|
||||
result = hxbot.hxpower.enable_bt()
|
||||
print_result(result)
|
||||
elif command.lower() == "ba":
|
||||
if hxbot.hxpower.ba_enabled:
|
||||
print("Disable BA...")
|
||||
result = hxbot.hxpower.disable_ba()
|
||||
else:
|
||||
print("Enable BA...")
|
||||
result = hxbot.hxpower.enable_ba()
|
||||
print_result(result)
|
||||
elif command.lower() == "mv":
|
||||
if hxbot.hxpower.mv_enabled:
|
||||
print("Disable MV...")
|
||||
result = hxbot.hxpower.disable_mv()
|
||||
else:
|
||||
print("Enable MV...")
|
||||
result = hxbot.hxpower.enable_mv()
|
||||
print_result(result)
|
||||
elif command.lower() == "us":
|
||||
if hxbot.hxpower.us_enabled:
|
||||
print("Disable USB power...")
|
||||
result = hxbot.hxpower.disable_us()
|
||||
else:
|
||||
print("Enable USB power...")
|
||||
result = hxbot.hxpower.enable_us()
|
||||
print_result(result)
|
||||
elif command.lower() == "reset":
|
||||
GPIO.output(25, 0)
|
||||
time.sleep(5)
|
||||
GPIO.output(25, 1)
|
||||
else:
|
||||
# Try to send RAW command to HXpower
|
||||
try:
|
||||
rawCommand = int(command)
|
||||
except:
|
||||
rawCommand = 0x00
|
||||
print("Wrong command!")
|
||||
|
||||
if not rawCommand:
|
||||
continue
|
||||
|
||||
rawCommand = (rawCommand << 8) | (rawCommand ^ HX.XOR_SEQ)
|
||||
try:
|
||||
with hxbot.hxpower_lock:
|
||||
hxbot.i2c_bus.write_word_data(HX.POWER_ADDRESS,
|
||||
HX.EXT_COM, rawCommand)
|
||||
print("Sent:", rawCommand, "(", rawCommand, ")")
|
||||
time.sleep(HX.POWER_RESPONSE_DELAY)
|
||||
rawResponse = hxbot.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
print("Received:", rawResponse)
|
||||
except IOError as E:
|
||||
print(E)
|
||||
|
||||
|
||||
def hxcam_control(hxbot):
|
||||
if (hxbot.status != HX.STATUS_READY and
|
||||
hxbot.status != HX.STATUS_RUNNING):
|
||||
print("HXbot is not in ready or running state!")
|
||||
return
|
||||
|
||||
print("HXcam control program. Type command or \"help\"")
|
||||
print("Type \"exit\" to previous menu")
|
||||
command_view = "HXcam control>"
|
||||
|
||||
while True:
|
||||
command = input(command_view)
|
||||
if command.lower() == "exit":
|
||||
break
|
||||
elif command.lower() == "help":
|
||||
hxcam_help()
|
||||
elif command.lower() == "start":
|
||||
print("Start HXcam")
|
||||
if hxbot.hxcam.is_running:
|
||||
print("Allready running")
|
||||
else:
|
||||
hxbot.hxcam.start()
|
||||
elif command.lower() == "stop":
|
||||
print("Stop HXcam")
|
||||
if not hxbot.hxcam.is_running:
|
||||
print("Not running")
|
||||
else:
|
||||
hxbot.hxcam.stop()
|
||||
elif command.lower() == "restart":
|
||||
print("Restart HXcam")
|
||||
if hxbot.hxcam.is_running:
|
||||
print("Stop...")
|
||||
hxbot.hxcam.stop()
|
||||
if not hxbot.hxcam.is_running:
|
||||
print("Start...")
|
||||
hxbot.hxcam.start()
|
||||
|
||||
# MAIN PROGRAM
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
257
HXbot/HXcam.py
Executable file
257
HXbot/HXcam.py
Executable file
@@ -0,0 +1,257 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot camera control module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import subprocess
|
||||
import threading
|
||||
#import select
|
||||
import time
|
||||
import sys
|
||||
import os.path as path
|
||||
import HX
|
||||
|
||||
|
||||
class HXcamClass():
|
||||
|
||||
def __init__(self):
|
||||
super(HXcamClass, self).__init__()
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
self.mcam = None
|
||||
self.rcam = None
|
||||
self.mmic = None
|
||||
self.rvid = None
|
||||
|
||||
self.is_running = False
|
||||
|
||||
# Subprocess states
|
||||
# 0 - Not running
|
||||
# 1 - Running
|
||||
# 2 - Error
|
||||
# 3 - Device not found
|
||||
self.mcam_state = HX.CAM_STATE_STP
|
||||
self.rvid_state = HX.CAM_STATE_STP
|
||||
self.rcam_state = HX.CAM_STATE_STP
|
||||
self.mmic_state = HX.CAM_STATE_STP
|
||||
|
||||
self.mcam_wrn_count = 0
|
||||
self.rcam_wrn_count = 0
|
||||
self.mmic_wrn_count = 0
|
||||
|
||||
def start(self):
|
||||
self.__e = threading.Event()
|
||||
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
|
||||
|
||||
self.mcam_start()
|
||||
#self.rcam_start()
|
||||
self.mmic_start()
|
||||
|
||||
self.__t.start()
|
||||
|
||||
self.is_running = True
|
||||
|
||||
def stop(self):
|
||||
self.__e.set()
|
||||
self.__t.join()
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
self.mcam_stop()
|
||||
#self.rcam_stop()
|
||||
self.mmic_stop()
|
||||
|
||||
self.is_running = False
|
||||
|
||||
def restart(self):
|
||||
if self.is_running:
|
||||
self.__stop()
|
||||
self.__start()
|
||||
|
||||
def test(self):
|
||||
#import time
|
||||
#import sys
|
||||
#import shlex
|
||||
#string = ""
|
||||
#args = shlex.split(string)
|
||||
#print(args)
|
||||
#sys.exit()
|
||||
pass
|
||||
|
||||
def mcam_start(self):
|
||||
# cvlc 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15'
|
||||
# --sout '#rtp{sdp=rtsp://:8554/video}' -v --live-caching 50
|
||||
if path.exists('/dev/video0'):
|
||||
arg = 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15'
|
||||
elif path.exists('/dev/video1'):
|
||||
arg = 'v4l2:///dev/video1:chroma=H264:width=1280:height=720:fps=15'
|
||||
else:
|
||||
self.mcam_state = HX.CAM_STATE_ERR
|
||||
return
|
||||
|
||||
self.mcam = subprocess.Popen(
|
||||
args=['/usr/bin/cvlc',
|
||||
arg,
|
||||
'--sout', '#rtp{sdp=rtsp://:8554/video}',
|
||||
'--live-caching', '50', 'vlc://quit'],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL)
|
||||
|
||||
self.mcam_state = HX.CAM_STATE_RUN
|
||||
|
||||
def mcam_stop(self):
|
||||
if self.mcam_state != HX.CAM_STATE_ERR:
|
||||
self.mcam.terminate()
|
||||
self.mcam_state = HX.CAM_STATE_STP
|
||||
|
||||
def rcam_start(self):
|
||||
# raspivid -t 0 -n -w 1280 -h 720 -fps 15 -o - |
|
||||
# cvlc -v stream:///dev/stdin
|
||||
# --sout '#rtp{sdp=rtsp://:8555/video}' :demux=h264
|
||||
self.rvid = subprocess.Popen(
|
||||
args=['raspivid', '-t', '0', '-n', '-w', '1280', '-h', '720',
|
||||
'-fps', '15', '-o', '-'],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL)
|
||||
|
||||
self.rcam = subprocess.Popen(
|
||||
args=['cvlc', 'stream:///dev/stdin', '--sout',
|
||||
'#rtp{sdp=rtsp://:8555/video}', ':demux=h264',
|
||||
'--live-caching', '50', 'vlc://quit'],
|
||||
stdin=self.rvid.stdout,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL)
|
||||
|
||||
self.rcam_state = HX.CAM_STATE_RUN
|
||||
|
||||
def rcam_stop(self):
|
||||
if self.rcam_state != HX.CAM_STATE_ERR:
|
||||
self.rvid.terminate()
|
||||
self.rcam.terminate()
|
||||
self.rcam_state = HX.CAM_STATE_STP
|
||||
|
||||
def mmic_start(self):
|
||||
# cvlc -v 'alsa://hw:1,0'
|
||||
# --sout '#transcode{acodec=mpga,ab=128,channels=2,samplerate=44100}
|
||||
# :rtp{sdp=rtsp://:8556/audio}'
|
||||
self.mmic = subprocess.Popen(
|
||||
args=['cvlc', 'alsa://hw:0,0', '--sout',
|
||||
'#transcode{acodec=mpga,ab=128,channels=2,samplerate=44100}' +
|
||||
':rtp{sdp=rtsp://:8556/audio}',
|
||||
'--live-caching', '500', 'vlc://quit'],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL)
|
||||
|
||||
self.mmic_state = HX.CAM_STATE_RUN
|
||||
|
||||
def mmic_stop(self):
|
||||
if self.mmic_state != HX.CAM_STATE_ERR:
|
||||
self.mmic.terminate()
|
||||
self.mmic_state = HX.CAM_STATE_STP
|
||||
|
||||
def __process(self, stopRequest):
|
||||
# Process loop
|
||||
while not stopRequest.is_set():
|
||||
# Main Camera
|
||||
if self.mcam_state != HX.CAM_STATE_ERR:
|
||||
if self.mcam.poll() is not None:
|
||||
self.mcam_start()
|
||||
|
||||
if self.mcam_state != HX.CAM_STATE_WRN:
|
||||
self.mcam_wrn_count += 1
|
||||
|
||||
if self.mcam_wrn_count >= HX.CAM_MAX_WRN_COUNT:
|
||||
self.mcam_state = HX.CAM_STATE_WRN
|
||||
|
||||
# Rear Camera
|
||||
#if self.rcam_state != HX.CAM_STATE_ERR:
|
||||
#if self.rcam.poll() is not None:
|
||||
#self.rcam_start()
|
||||
|
||||
#if self.rcam_state != HX.CAM_STATE_WRN:
|
||||
#self.rcam_wrn_count += 1
|
||||
|
||||
#if self.rcam_wrn_count >= HX.CAM_MAX_WRN_COUNT:
|
||||
#self.rcam_state = HX.CAM_STATE_WRN
|
||||
|
||||
# Main Microphone
|
||||
if self.mmic_state != HX.CAM_STATE_ERR:
|
||||
if self.mmic.poll() is not None:
|
||||
self.mmic_start()
|
||||
|
||||
if self.mmic_state != HX.CAM_STATE_WRN:
|
||||
self.mmic_wrn_count += 1
|
||||
|
||||
if self.mmic_wrn_count >= HX.CAM_MAX_WRN_COUNT:
|
||||
self.mmic_state = HX.CAM_STATE_WRN
|
||||
|
||||
time.sleep(HX.CAM_DELAY)
|
||||
|
||||
#if self.mcam_state == 1:
|
||||
## VLC-1
|
||||
#r, w, e = select.select([self.mcam.stderr], [], [], 0.5)
|
||||
#if self.mcam.stderr in r:
|
||||
#print("VLC-1 ERROR:")
|
||||
#print(self.mcam.stderr.readline())
|
||||
|
||||
#r, w, e = select.select([self.mcam.stdout], [], [], 0.5)
|
||||
#if self.mcam.stdout in r:
|
||||
#print("VLC-1 OUT:")
|
||||
#print(self.mcam.stdout.readline())
|
||||
|
||||
#if self.rvid_state == 1:
|
||||
## VLC-2
|
||||
#r, w, e = select.select([self.rvid.stderr], [], [], 0.5)
|
||||
#if self.rvid.stderr in r:
|
||||
#print("RVID ERROR:")
|
||||
#print(self.rvid.stderr.readline())
|
||||
|
||||
#r, w, e = select.select([self.rcam.stderr], [], [], 0.5)
|
||||
#if self.rcam.stderr in r:
|
||||
#print("VLC-2 ERROR:")
|
||||
#print(self.rcam.stderr.readline())
|
||||
|
||||
#r, w, e = select.select([self.rcam.stdout], [], [], 0.5)
|
||||
#if self.rcam.stdout in r:
|
||||
#print("VLC-2 OUT:")
|
||||
#print(self.rcam.stdout.readline())
|
||||
|
||||
#if self.mmic_state == 1:
|
||||
## VLC-3
|
||||
#r, w, e = select.select([self.mmic.stderr], [], [], 0)
|
||||
#if self.mmic.stderr in r:
|
||||
#print("MMIC ERROR:")
|
||||
#print(self.mmic.stderr.readline())
|
||||
|
||||
#r, w, e = select.select([self.mmic.stdout], [], [], 0.5)
|
||||
#if self.mmic.stdout in r:
|
||||
#print("MMIC OUT:")
|
||||
#print(self.mmic.stdout.readline())
|
||||
|
||||
|
||||
def main():
|
||||
HXcam = HXcamClass()
|
||||
HXcam.start()
|
||||
|
||||
print("Execution started")
|
||||
|
||||
command_view = '"Return" or CTRL+C to exit>'
|
||||
try:
|
||||
while True:
|
||||
command = input(command_view)
|
||||
|
||||
if command == "":
|
||||
HXcam.stop()
|
||||
sys.exit()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Terminate...")
|
||||
HXcam.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
132
HXbot/HXdb.py
Executable file
132
HXbot/HXdb.py
Executable file
@@ -0,0 +1,132 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot database module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import HX
|
||||
import threading
|
||||
import time
|
||||
import mysql.connector
|
||||
from mysql.connector import errorcode
|
||||
|
||||
|
||||
class HXdbClass():
|
||||
|
||||
def __init__(self, hxbot):
|
||||
super(HXdbClass, self).__init__()
|
||||
|
||||
self.hxbot = hxbot
|
||||
|
||||
self.hxpower = None
|
||||
self.reflex = None
|
||||
self.joystick = None
|
||||
self.hxlcd = None
|
||||
self.hxcam = None
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
self.is_running = False
|
||||
|
||||
try:
|
||||
self.cnx = mysql.connector.connect(user=HX.DB_USER,
|
||||
password=HX.DB_PASS,
|
||||
host=HX.DB_HOST,
|
||||
database=HX.DB_NAME)
|
||||
except mysql.connector.Error as err:
|
||||
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
|
||||
print("Something is wrong with your user name or password")
|
||||
elif err.errno == errorcode.ER_BAD_DB_ERROR:
|
||||
print("Database does not exist")
|
||||
else:
|
||||
print(err)
|
||||
self.cnx = None
|
||||
|
||||
raise
|
||||
|
||||
def start(self):
|
||||
self.hxpower = self.hxbot.hxpower
|
||||
self.reflex = self.hxbot.reflex
|
||||
self.joystick = self.hxbot.joystick
|
||||
self.hxlcd = self.hxbot.hxlcd
|
||||
self.hxcam = self.hxbot.hxcam
|
||||
|
||||
self.__e = threading.Event()
|
||||
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
|
||||
|
||||
self.__t.start()
|
||||
self.is_running = True
|
||||
|
||||
def stop(self):
|
||||
self.__e.set()
|
||||
self.__t.join()
|
||||
self.is_running = False
|
||||
|
||||
if self.cnx is not None:
|
||||
self.cnx.close()
|
||||
|
||||
self.hxpower = None
|
||||
self.reflex = None
|
||||
self.joystick = None
|
||||
self.hxlcd = None
|
||||
self.hxcam = None
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
def __process(self, stopRequest):
|
||||
cursor = self.cnx.cursor()
|
||||
pw = self.hxpower
|
||||
|
||||
insert_state = ("INSERT INTO states "
|
||||
"(vcc, vin, vdc, vbt, vba, vis, vzu, "
|
||||
"ahx, aba, ain, adc, "
|
||||
"vcc_ok, vin_ok, vdc_ok, vbt_ok, vba_ok, "
|
||||
"vis_ok, vzu_ok, "
|
||||
"ahx_ok, aba_ok, ain_ok, adc_ok, "
|
||||
"lr_enabled, ba_enabled, ba_blocked, "
|
||||
"vcc_low, vcc_high, vin_low, vin_high, "
|
||||
"vdc_low, vdc_high, vbt_low, vbt_full, "
|
||||
"vba_low, vba_full, vis_low, vis_high, "
|
||||
"vzu_low, vzu_high, "
|
||||
"ahx_low, ahx_high, aba_low, aba_high, "
|
||||
"ain_low, ain_high, adc_low, adc_high, "
|
||||
"pf_enabled, bl_enabled, bl_powered, "
|
||||
"bl_error, ba_full, ba_charge) "
|
||||
"VALUES ("
|
||||
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
|
||||
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
|
||||
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
|
||||
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
|
||||
"%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
|
||||
"%s, %s, %s)")
|
||||
|
||||
while not stopRequest.is_set():
|
||||
# Get Data
|
||||
state = (pw.vcc, pw.vin, pw.vdc, pw.vbt, pw.vba, pw.vis,
|
||||
pw.vzu, pw.ahx, pw.aba, pw.ain, pw.adc, pw.vcc_ok,
|
||||
pw.vin_ok, pw.vdc_ok, pw.vbt_ok, pw.vba_ok,
|
||||
pw.vis_ok, pw.vzu_ok,
|
||||
pw.ahx_ok, pw.aba_ok, pw.ain_ok, pw.adc_ok,
|
||||
pw.lr_enabled, pw.ba_enabled, pw.ba_blocked,
|
||||
pw.vcc_low, pw.vcc_high, pw.vin_low, pw.vin_high,
|
||||
pw.vdc_low, pw.vdc_high, pw.vbt_low, pw.vbt_full,
|
||||
pw.vba_low, pw.vba_full, pw.vis_low, pw.vis_high,
|
||||
pw.vzu_low, pw.vzu_high, pw.ahx_low, pw.ahx_high,
|
||||
pw.aba_low, pw.aba_high, pw.ain_low, pw.ain_high,
|
||||
pw.adc_low, pw.adc_high,
|
||||
pw.pf_enabled, pw.bl_enabled,
|
||||
pw.bl_powered, pw.bl_error,
|
||||
pw.ba_full, pw.ba_charge)
|
||||
|
||||
# Insert Data
|
||||
if pw.online:
|
||||
cursor.execute(insert_state, state)
|
||||
self.cnx.commit()
|
||||
|
||||
# Delay
|
||||
time.sleep(HX.DB_DELAY)
|
||||
|
||||
cursor.close()
|
||||
234
HXbot/HXjoystick.py
Executable file
234
HXbot/HXjoystick.py
Executable file
@@ -0,0 +1,234 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot controller module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import HX
|
||||
import threading
|
||||
import array
|
||||
import struct
|
||||
import select
|
||||
import time
|
||||
from fcntl import ioctl
|
||||
|
||||
|
||||
class HXjoystickClass():
|
||||
|
||||
def __init__(self):
|
||||
super(HXjoystickClass, self).__init__()
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
self.ready = False
|
||||
|
||||
self.device = open(HX.JOYSTICK_PATH, 'rb')
|
||||
|
||||
self.name = ""
|
||||
self.axis_states = {}
|
||||
self.button_states = {}
|
||||
self.axis_map = []
|
||||
self.button_map = []
|
||||
self.axis_names = HX.JOYSTICK_AXIS_NAMES
|
||||
self.button_names = HX.JOYSTICK_BUTTON_NAMES
|
||||
|
||||
self.online = False
|
||||
self.is_running = False
|
||||
self.last_command_time = 0.0
|
||||
|
||||
# Get the device name.
|
||||
buf = array.array('B', [0] * 64)
|
||||
# JSIOCGNAME(len)
|
||||
ioctl(self.device, 0x80006a13 + (0x10000 * len(buf)), buf)
|
||||
self.name = buf.tostring()
|
||||
#print('Device name: %s' % js_name)
|
||||
|
||||
# Get number of axes and buttons.
|
||||
buf = array.array('B', [0])
|
||||
ioctl(self.device, 0x80016a11, buf) # JSIOCGAXES
|
||||
num_axes = buf[0]
|
||||
|
||||
buf = array.array('B', [0])
|
||||
ioctl(self.device, 0x80016a12, buf) # JSIOCGBUTTONS
|
||||
num_buttons = buf[0]
|
||||
|
||||
# Get the axis map.
|
||||
buf = array.array('B', [0] * 0x40)
|
||||
ioctl(self.device, 0x80406a32, buf) # JSIOCGAXMAP
|
||||
|
||||
for axis in buf[:num_axes]:
|
||||
axis_name = self.axis_names.get(axis, 'unknown(0x%02x)' % axis)
|
||||
self.axis_map.append(axis_name)
|
||||
self.axis_states[axis_name] = 0.0
|
||||
|
||||
# Get the button map.
|
||||
buf = array.array('H', [0] * 200)
|
||||
ioctl(self.device, 0x80406a34, buf) # JSIOCGBTNMAP
|
||||
|
||||
for btn in buf[:num_buttons]:
|
||||
btn_name = self.button_names.get(btn, 'unknown(0x%03x)' % btn)
|
||||
self.button_map.append(btn_name)
|
||||
self.button_states[btn_name] = 0
|
||||
|
||||
#print('%d axes found: %s' % (num_axes, ', '.join(self.axis_map)))
|
||||
#print('%d btns found: %s' % (num_buttons, ', '.join(self.button_map)))
|
||||
|
||||
def start(self):
|
||||
self.__e = threading.Event()
|
||||
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
|
||||
|
||||
self.__t.start()
|
||||
self.is_running = True
|
||||
|
||||
def stop(self):
|
||||
self.__e.set()
|
||||
self.__t.join()
|
||||
self.is_running = False
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
def __process(self, stopRequest):
|
||||
while not stopRequest.is_set():
|
||||
r, w, e = select.select([self.device], [], [], 0.8)
|
||||
if self.device in r:
|
||||
try:
|
||||
evbuf = self.device.read(8)
|
||||
self.online = True
|
||||
except OSError:
|
||||
self.online = False
|
||||
self.ready = False
|
||||
continue
|
||||
|
||||
if evbuf:
|
||||
time_, value, type, number = struct.unpack('IhBB', evbuf)
|
||||
|
||||
# Save last command time
|
||||
self.last_command_time = time.clock()
|
||||
|
||||
#if type & 0x80:
|
||||
#print("(initial)")
|
||||
|
||||
if type & 0x01:
|
||||
button = self.button_map[number]
|
||||
if button:
|
||||
self.button_states[button] = value
|
||||
#if value:
|
||||
#print("%s pressed" % (button))
|
||||
#else:
|
||||
#print("%s released" % (button))
|
||||
|
||||
if type & 0x02:
|
||||
axis = self.axis_map[number]
|
||||
if axis:
|
||||
fvalue = value / 32767.0
|
||||
self.axis_states[axis] = fvalue
|
||||
#print("%s: %.3f" % (axis, fvalue))
|
||||
|
||||
# Switch ready property
|
||||
if (self.button_states[HX.JOYSTICK_START_BTN_1] and
|
||||
self.button_states[HX.JOYSTICK_START_BTN_2]):
|
||||
if self.ready:
|
||||
self.ready = False
|
||||
else:
|
||||
self.ready = True
|
||||
|
||||
# Timeout? Relax...
|
||||
elif time.clock() - self.last_command_time >= \
|
||||
HX.JOYSTICK_READY_TIMEOUT / 100:
|
||||
self.ready = False
|
||||
|
||||
def get_m(self):
|
||||
axis_move = self.axis_states[HX.JOYSTICK_MOVE_AXIS]
|
||||
axis_steer = self.axis_states[HX.JOYSTICK_STEER_AXIS]
|
||||
|
||||
axis_head_v = self.axis_states[HX.JOYSTICK_HEAD_V_AXIS]
|
||||
axis_head_h = self.axis_states[HX.JOYSTICK_HEAD_H_AXIS]
|
||||
|
||||
# STOP (FLOAT)
|
||||
if (axis_move >= -1 / 8) and (axis_move <= 1 / 8):
|
||||
move = HX.MOVE_FLOAT
|
||||
|
||||
# MOVE FORWARD
|
||||
elif (axis_move >= -2 / 8) and (axis_move < -1 / 8):
|
||||
move = HX.MOVE_FWD1
|
||||
elif (axis_move >= -3 / 8) and (axis_move < -2 / 8):
|
||||
move = HX.MOVE_FWD2
|
||||
elif (axis_move >= -4 / 8) and (axis_move < -3 / 8):
|
||||
move = HX.MOVE_FWD3
|
||||
elif (axis_move >= -5 / 8) and (axis_move < -4 / 8):
|
||||
move = HX.MOVE_FWD4
|
||||
elif (axis_move >= -6 / 8) and (axis_move < -5 / 8):
|
||||
move = HX.MOVE_FWD5
|
||||
elif (axis_move >= -7 / 8) and (axis_move < -6 / 8):
|
||||
move = HX.MOVE_FWD6
|
||||
elif (axis_move >= -1) and (axis_move < -7 / 8):
|
||||
move = HX.MOVE_FWD7
|
||||
|
||||
# MOVE BACKWARD
|
||||
elif (axis_move > 1 / 8) and (axis_move <= 2 / 8):
|
||||
move = HX.MOVE_REV1
|
||||
elif (axis_move > 2 / 8) and (axis_move <= 3 / 8):
|
||||
move = HX.MOVE_REV2
|
||||
elif (axis_move > 3 / 8) and (axis_move <= 4 / 8):
|
||||
move = HX.MOVE_REV3
|
||||
elif (axis_move > 4 / 8) and (axis_move <= 5 / 8):
|
||||
move = HX.MOVE_REV4
|
||||
elif (axis_move > 5 / 8) and (axis_move <= 6 / 8):
|
||||
move = HX.MOVE_REV5
|
||||
elif (axis_move > 6 / 8) and (axis_move <= 7 / 8):
|
||||
move = HX.MOVE_REV6
|
||||
elif (axis_move > 7 / 8) and (axis_move <= 1):
|
||||
move = HX.MOVE_REV7
|
||||
|
||||
# CENTER (FLOAT)
|
||||
if (axis_steer >= -1 / 8) and (axis_steer <= 1 / 8):
|
||||
steer = HX.STEER_CENTER
|
||||
|
||||
# STEER LEFT
|
||||
elif (axis_steer >= -2 / 8) and (axis_steer < -1 / 8):
|
||||
steer = HX.STEER_LEFT1
|
||||
elif (axis_steer >= -3 / 8) and (axis_steer < -2 / 8):
|
||||
steer = HX.STEER_LEFT2
|
||||
elif (axis_steer >= -4 / 8) and (axis_steer < -3 / 8):
|
||||
steer = HX.STEER_LEFT3
|
||||
elif (axis_steer >= -5 / 8) and (axis_steer < -4 / 8):
|
||||
steer = HX.STEER_LEFT4
|
||||
elif (axis_steer >= -6 / 8) and (axis_steer < -5 / 8):
|
||||
steer = HX.STEER_LEFT5
|
||||
elif (axis_steer >= -7 / 8) and (axis_steer < -6 / 8):
|
||||
steer = HX.STEER_LEFT6
|
||||
elif (axis_steer >= -1) and (axis_steer < -7 / 8):
|
||||
steer = HX.STEER_LEFT7
|
||||
|
||||
# STEER RIGHT
|
||||
elif (axis_steer > 1 / 8) and (axis_steer <= 2 / 8):
|
||||
steer = HX.STEER_RIGHT1
|
||||
elif (axis_steer > 2 / 8) and (axis_steer <= 3 / 8):
|
||||
steer = HX.STEER_RIGHT2
|
||||
elif (axis_steer > 3 / 8) and (axis_steer <= 4 / 8):
|
||||
steer = HX.STEER_RIGHT3
|
||||
elif (axis_steer > 4 / 8) and (axis_steer <= 5 / 8):
|
||||
steer = HX.STEER_RIGHT4
|
||||
elif (axis_steer > 5 / 8) and (axis_steer <= 6 / 8):
|
||||
steer = HX.STEER_RIGHT5
|
||||
elif (axis_steer > 6 / 8) and (axis_steer <= 7 / 8):
|
||||
steer = HX.STEER_RIGHT6
|
||||
elif (axis_steer > 7 / 8) and (axis_steer <= 1):
|
||||
steer = HX.STEER_RIGHT7
|
||||
|
||||
# Head V
|
||||
if axis_head_v > 0:
|
||||
head_v = int(HX.HEAD_V_CENTER - HX.HEAD_V_UP_RANGE * axis_head_v)
|
||||
else:
|
||||
head_v = int(HX.HEAD_V_CENTER - HX.HEAD_V_DOWN_RANGE * axis_head_v)
|
||||
|
||||
# Head H
|
||||
if axis_head_h > 0:
|
||||
head_h = int(HX.HEAD_H_CENTER - HX.HEAD_H_R_RANGE * axis_head_h)
|
||||
else:
|
||||
head_h = int(HX.HEAD_H_CENTER - HX.HEAD_H_L_RANGE * axis_head_h)
|
||||
|
||||
# Return
|
||||
return (True, move, steer, head_v, head_h)
|
||||
149
HXbot/HXlcd.py
Executable file
149
HXbot/HXlcd.py
Executable file
@@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot LCD module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import HX
|
||||
import threading
|
||||
import time
|
||||
import array
|
||||
import struct
|
||||
|
||||
|
||||
class HXlcdClass():
|
||||
|
||||
def __init__(self, i2c_bus, lock):
|
||||
super(HXlcdClass, self).__init__()
|
||||
|
||||
self.i2c_bus = i2c_bus
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
self.lock = lock
|
||||
self.online = False
|
||||
self.is_running = False
|
||||
self.error_count = 0
|
||||
|
||||
def start(self):
|
||||
self.__e = threading.Event()
|
||||
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
|
||||
|
||||
self.__t.start()
|
||||
self.is_running = True
|
||||
|
||||
def stop(self):
|
||||
self.__e.set()
|
||||
self.__t.join()
|
||||
self.is_running = False
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
def __process(self, stopRequest):
|
||||
while not stopRequest.is_set():
|
||||
try:
|
||||
self.__send_command(HX.COM_PING)
|
||||
|
||||
self.online = True
|
||||
|
||||
except IOError:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
|
||||
# Too many errors
|
||||
if self.error_count >= HX.LCD_ERROR_LIMIT:
|
||||
self.online = False
|
||||
|
||||
# Delay
|
||||
time.sleep(HX.LCD_DELAY)
|
||||
|
||||
def __sum_check(self, val, sum_):
|
||||
tmp = 0x00
|
||||
for b in val:
|
||||
tmp ^= b
|
||||
tmp ^= HX.XOR_SEQ
|
||||
if tmp == sum_:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __read_float(self, cmd):
|
||||
# Byte array
|
||||
data = array.array('B', [0, 0, 0, 0])
|
||||
with self.lock:
|
||||
# Send command
|
||||
self.__write_byte(cmd)
|
||||
time.sleep(HX.LCD_RESPONSE_DELAY)
|
||||
|
||||
# Get bytes
|
||||
data[0] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
data[1] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
data[2] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
data[3] = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
|
||||
# Get check sum
|
||||
sum_ = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
|
||||
# Check and return value
|
||||
if self.__sum_check(data, sum_):
|
||||
return struct.unpack('f', data)[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def __read_byte(self, cmd):
|
||||
with self.lock:
|
||||
# Send command
|
||||
self.__write_byte(cmd)
|
||||
time.sleep(HX.LCD_RESPONSE_DELAY)
|
||||
|
||||
# Get byte
|
||||
data = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
|
||||
# Get check sum
|
||||
sum_ = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
|
||||
# Check and return value
|
||||
if data ^ HX.XOR_SEQ == sum_:
|
||||
return data
|
||||
else:
|
||||
return None
|
||||
|
||||
def __write_byte(self, cmd):
|
||||
cmd = (cmd << 8) | (cmd ^ HX.XOR_SEQ)
|
||||
self.i2c_bus.write_word_data(HX.LCD_ADDRESS, HX.EXT_COM, cmd)
|
||||
|
||||
def send_cmd(self, cmd):
|
||||
try:
|
||||
with self.lock:
|
||||
# Send command
|
||||
self.__write_byte(cmd)
|
||||
time.sleep(HX.LCD_RESPONSE_DELAY)
|
||||
|
||||
# Get response
|
||||
response = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
|
||||
# Return
|
||||
return response
|
||||
except IOError:
|
||||
return HX.IOE_RSP
|
||||
|
||||
def __send_command(self, command):
|
||||
try:
|
||||
with self.lock:
|
||||
self.i2c_bus.write_word_data(HX.LCD_ADDRESS, command, 0)
|
||||
time.sleep(HX.LCD_RESPONSE_DELAY)
|
||||
response = self.i2c_bus.read_byte(HX.LCD_ADDRESS)
|
||||
except IOError:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
if self.error_count >= HX.LCD_ERROR_LIMIT:
|
||||
self.online = False
|
||||
return HX.IOE_RSP
|
||||
else:
|
||||
self.error_count = 0
|
||||
self.online = True
|
||||
return response
|
||||
|
||||
return HX.NO_RSP
|
||||
1
HXbot/HXlight.py
Executable file
1
HXbot/HXlight.py
Executable file
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
1
HXbot/HXlog.py
Executable file
1
HXbot/HXlog.py
Executable file
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
587
HXbot/HXpower.py
Executable file
587
HXbot/HXpower.py
Executable file
@@ -0,0 +1,587 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot power control module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import HX
|
||||
import threading
|
||||
import time
|
||||
import array
|
||||
import struct
|
||||
|
||||
|
||||
class HXpowerClass():
|
||||
|
||||
def __init__(self, i2c_bus, lock):
|
||||
super(HXpowerClass, self).__init__()
|
||||
|
||||
self.i2c_bus = i2c_bus
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
self.lock = lock
|
||||
|
||||
# MV
|
||||
self.__mv_enable_time = 0.0
|
||||
self.mv_blocked = True
|
||||
|
||||
# HXpower data
|
||||
self.online = False
|
||||
self.is_running = False
|
||||
self.error_count = 0
|
||||
|
||||
self.status = 0x000000
|
||||
self.vcc = 0.0
|
||||
self.vin = 0.0
|
||||
self.vdc = 0.0
|
||||
self.vbt = 0.0
|
||||
self.vba = 0.0
|
||||
self.vpf = 0.0
|
||||
self.vzu = 0.0
|
||||
self.abt = 0.0
|
||||
self.aba = 0.0
|
||||
self.ain = 0.0
|
||||
self.ahx = 0.0
|
||||
self.vcc_ok = False
|
||||
self.vin_ok = False
|
||||
self.vdc_ok = False
|
||||
self.vbt_ok = False
|
||||
self.vba_ok = False
|
||||
self.vpf_ok = False
|
||||
self.vzu_ok = False
|
||||
self.abt_ok = False
|
||||
self.aba_ok = False
|
||||
self.ain_ok = False
|
||||
self.ahx_ok = False
|
||||
self.bt_enabled = False
|
||||
self.ba_enabled = False
|
||||
self.bt_blocked = False
|
||||
self.ba_blocked = False
|
||||
self.vcc_low = False
|
||||
self.vcc_high = False
|
||||
self.vin_low = False
|
||||
self.vin_high = False
|
||||
self.vdc_low = False
|
||||
self.vdc_high = False
|
||||
self.vbt_low = False
|
||||
self.vbt_full = False
|
||||
self.vba_low = False
|
||||
self.vba_full = False
|
||||
self.vpf_low = False
|
||||
self.vpf_high = False
|
||||
self.vzu_low = False
|
||||
self.vzu_high = False
|
||||
self.abt_low = False
|
||||
self.abt_high = False
|
||||
self.aba_low = False
|
||||
self.aba_high = False
|
||||
self.ain_low = False
|
||||
self.ain_high = False
|
||||
self.ahx_low = False
|
||||
self.ahx_high = False
|
||||
|
||||
self.mv_enabled = False
|
||||
self.us_enabled = False
|
||||
|
||||
self.in_plugged = False
|
||||
self.ba_full = False
|
||||
self.bt_full = False
|
||||
|
||||
def start(self):
|
||||
self.__e = threading.Event()
|
||||
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
|
||||
|
||||
self.__t.start()
|
||||
self.is_running = True
|
||||
|
||||
def stop(self):
|
||||
self.__e.set()
|
||||
self.__t.join()
|
||||
self.is_running = False
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
def __process(self, stopRequest):
|
||||
stat1 = 0x00
|
||||
stat2 = 0x00
|
||||
stat3 = 0x00
|
||||
|
||||
# Process loop
|
||||
while not stopRequest.is_set():
|
||||
try:
|
||||
self.status = 0x0000
|
||||
|
||||
# Get status 1
|
||||
tmp = self.__read_byte(HX.COM_GET_STAT1)
|
||||
if tmp is not None:
|
||||
stat1 = tmp << 8
|
||||
else:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
|
||||
# Get status 2
|
||||
tmp = self.__read_byte(HX.COM_GET_STAT2)
|
||||
if tmp is not None:
|
||||
stat2 = tmp
|
||||
else:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
|
||||
# Get status 3
|
||||
tmp = self.__read_byte(HX.COM_GET_STAT3)
|
||||
if tmp is not None:
|
||||
stat3 = tmp << 16
|
||||
else:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
|
||||
self.status |= stat1
|
||||
self.status |= stat2
|
||||
self.status |= stat3
|
||||
|
||||
# Get Voltages
|
||||
tmp = self.__read_float(HX.COM_GET_VCC)
|
||||
if tmp is not None:
|
||||
self.vcc = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_VIN)
|
||||
if tmp is not None:
|
||||
self.vin = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_VDC)
|
||||
if tmp is not None:
|
||||
self.vdc = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_VBT)
|
||||
if tmp is not None:
|
||||
self.vbt = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_VBA)
|
||||
if tmp is not None:
|
||||
self.vba = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_VPF)
|
||||
if tmp is not None:
|
||||
self.vpf = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_VZU)
|
||||
if tmp is not None:
|
||||
self.vzu = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_ABT)
|
||||
if tmp is not None:
|
||||
self.abt = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_ABA)
|
||||
if tmp is not None:
|
||||
self.aba = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_AIN)
|
||||
if tmp is not None:
|
||||
self.ain = tmp
|
||||
|
||||
tmp = self.__read_float(HX.COM_GET_AHX)
|
||||
if tmp is not None:
|
||||
self.ahx = tmp
|
||||
|
||||
self.online = True
|
||||
self.error_count = 0
|
||||
except IOError:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
|
||||
# Decode Status
|
||||
if self.status & 0x0100:
|
||||
self.vcc_ok = True
|
||||
else:
|
||||
self.vcc_ok = False
|
||||
|
||||
if self.status & 0x0200:
|
||||
self.vin_ok = True
|
||||
else:
|
||||
self.vin_ok = False
|
||||
|
||||
if self.status & 0x0400:
|
||||
self.vdc_ok = True
|
||||
else:
|
||||
self.vdc_ok = False
|
||||
|
||||
if self.status & 0x0800:
|
||||
self.vbt_ok = True
|
||||
else:
|
||||
self.vbt_ok = False
|
||||
|
||||
if self.status & 0x1000:
|
||||
self.vba_ok = True
|
||||
else:
|
||||
self.vba_ok = False
|
||||
|
||||
if self.status & 0x0010:
|
||||
self.vpf_ok = True
|
||||
else:
|
||||
self.vpf_ok = False
|
||||
|
||||
if self.status & 0x0020:
|
||||
self.vzu_ok = True
|
||||
else:
|
||||
self.vzu_ok = False
|
||||
|
||||
if self.status & 0x2000:
|
||||
self.bt_enabled = True
|
||||
else:
|
||||
self.bt_enabled = False
|
||||
|
||||
if self.status & 0x4000:
|
||||
self.ba_enabled = True
|
||||
else:
|
||||
self.ba_enabled = False
|
||||
|
||||
if self.status & 0x0040:
|
||||
self.mv_enabled = True
|
||||
else:
|
||||
self.mv_enabled = False
|
||||
|
||||
if self.status & 0x0080:
|
||||
self.us_enabled = True
|
||||
else:
|
||||
self.us_enabled = False
|
||||
|
||||
if self.status & 0x8000:
|
||||
self.in_plugged = True
|
||||
else:
|
||||
self.in_plugged = False
|
||||
|
||||
if self.status & 0x0001:
|
||||
self.bt_blocked = True
|
||||
else:
|
||||
self.bt_blocked = False
|
||||
|
||||
if self.status & 0x0002:
|
||||
self.ba_blocked = True
|
||||
else:
|
||||
self.ba_blocked = False
|
||||
|
||||
if self.status & 0x0004:
|
||||
self.bt_full = True
|
||||
else:
|
||||
self.bt_full = False
|
||||
|
||||
if self.status & 0x0008:
|
||||
self.ba_full = True
|
||||
else:
|
||||
self.ba_full = False
|
||||
|
||||
if self.status & 0x010000:
|
||||
self.abt_ok = True
|
||||
else:
|
||||
self.abt_ok = False
|
||||
|
||||
if self.status & 0x020000:
|
||||
self.aba_ok = True
|
||||
else:
|
||||
self.aba_ok = False
|
||||
|
||||
if self.status & 0x040000:
|
||||
self.ain_ok = True
|
||||
else:
|
||||
self.ain_ok = False
|
||||
|
||||
if self.status & 0x080000:
|
||||
self.ahx_ok = True
|
||||
else:
|
||||
self.ahx_ok = False
|
||||
|
||||
# LOW | HIGH
|
||||
if self.vcc < HX.VCC_LOW:
|
||||
self.vcc_low = True
|
||||
else:
|
||||
self.vcc_low = False
|
||||
|
||||
if self.vcc > HX.VCC_HIGH:
|
||||
self.vcc_high = True
|
||||
else:
|
||||
self.vcc_high = False
|
||||
|
||||
if self.vin < HX.VIN_LOW:
|
||||
self.vin_low = True
|
||||
else:
|
||||
self.vin_low = False
|
||||
|
||||
if self.vin > HX.VIN_HIGH:
|
||||
self.vin_high = True
|
||||
else:
|
||||
self.vin_high = False
|
||||
|
||||
if self.vdc < HX.VDC_LOW:
|
||||
self.vdc_low = True
|
||||
else:
|
||||
self.vdc_low = False
|
||||
|
||||
if self.vdc > HX.VDC_HIGH:
|
||||
self.vdc_high = True
|
||||
else:
|
||||
self.vdc_high = False
|
||||
|
||||
if self.vbt < HX.VBT_LOW:
|
||||
self.vbt_low = True
|
||||
else:
|
||||
self.vbt_low = False
|
||||
|
||||
if self.vbt > HX.VBT_FULL:
|
||||
self.vbt_full = True
|
||||
else:
|
||||
self.vbt_full = False
|
||||
|
||||
if self.vba < HX.VBA_LOW:
|
||||
self.vba_low = True
|
||||
else:
|
||||
self.vba_low = False
|
||||
|
||||
if self.vba > HX.VBA_FULL:
|
||||
self.vba_full = True
|
||||
else:
|
||||
self.vba_full = False
|
||||
|
||||
if self.vpf < HX.VPF_LOW:
|
||||
self.vpf_low = True
|
||||
else:
|
||||
self.vpf_low = False
|
||||
|
||||
if self.vpf > HX.VPF_HIGH:
|
||||
self.vpf_high = True
|
||||
else:
|
||||
self.vpf_high = False
|
||||
|
||||
if self.vzu < HX.VZU_LOW:
|
||||
self.vzu_low = True
|
||||
else:
|
||||
self.vzu_low = False
|
||||
|
||||
if self.vzu > HX.VZU_HIGH:
|
||||
self.vzu_high = True
|
||||
else:
|
||||
self.vzu_high = False
|
||||
|
||||
if self.abt < HX.ABT_LOW:
|
||||
self.abt_low = True
|
||||
else:
|
||||
self.abt_low = False
|
||||
|
||||
if self.abt > HX.ABT_HIGH:
|
||||
self.abt_high = True
|
||||
else:
|
||||
self.abt_high = False
|
||||
|
||||
if self.aba < HX.ABA_LOW:
|
||||
self.aba_low = True
|
||||
else:
|
||||
self.aba_low = False
|
||||
|
||||
if self.aba > HX.ABA_HIGH:
|
||||
self.aba_high = True
|
||||
else:
|
||||
self.aba_high = False
|
||||
|
||||
if self.ain < HX.AIN_LOW:
|
||||
self.ain_low = True
|
||||
else:
|
||||
self.ain_low = False
|
||||
|
||||
if self.ain > HX.AIN_HIGH:
|
||||
self.ain_high = True
|
||||
else:
|
||||
self.ain_high = False
|
||||
|
||||
if self.ahx < HX.AHX_LOW:
|
||||
self.ahx_low = True
|
||||
else:
|
||||
self.ahx_low = False
|
||||
|
||||
if self.ahx > HX.AHX_HIGH:
|
||||
self.ahx_high = True
|
||||
else:
|
||||
self.ahx_high = False
|
||||
|
||||
# Too many errors
|
||||
if self.error_count >= HX.POWER_ERROR_LIMIT:
|
||||
self.online = False
|
||||
|
||||
# Unblock PF
|
||||
if (self.mv_enabled and time.clock() - self.__mv_enable_time >=
|
||||
HX.POWER_MV_TIMEOUT / 100):
|
||||
self.mv_blocked = False
|
||||
|
||||
# Delay
|
||||
time.sleep(HX.POWER_DELAY)
|
||||
|
||||
def __sum_check(self, val, sum_):
|
||||
tmp = 0x00
|
||||
for b in val:
|
||||
tmp ^= b
|
||||
tmp ^= HX.XOR_SEQ
|
||||
if tmp == sum_:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __read_float(self, cmd):
|
||||
# Byte array
|
||||
data = array.array('B', [0, 0, 0, 0])
|
||||
with self.lock:
|
||||
# Send command
|
||||
self.__write_byte(cmd)
|
||||
time.sleep(HX.POWER_RESPONSE_DELAY)
|
||||
|
||||
# Get bytes
|
||||
data[0] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
data[1] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
data[2] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
data[3] = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
|
||||
# Get check sum
|
||||
sum_ = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
|
||||
# Check and return value
|
||||
if self.__sum_check(data, sum_):
|
||||
return struct.unpack('f', data)[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def __read_byte(self, cmd):
|
||||
with self.lock:
|
||||
# Send command
|
||||
self.__write_byte(cmd)
|
||||
time.sleep(HX.POWER_RESPONSE_DELAY)
|
||||
|
||||
# Get byte
|
||||
data = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
|
||||
# Get check sum
|
||||
sum_ = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
|
||||
# Check and return value
|
||||
if data ^ HX.XOR_SEQ == sum_:
|
||||
return data
|
||||
else:
|
||||
return None
|
||||
|
||||
def __write_byte(self, cmd):
|
||||
cmd = (cmd << 8) | (cmd ^ HX.XOR_SEQ)
|
||||
self.i2c_bus.write_word_data(HX.POWER_ADDRESS, HX.EXT_COM, cmd)
|
||||
|
||||
def send_cmd(self, cmd):
|
||||
try:
|
||||
with self.lock:
|
||||
# Send command
|
||||
self.__write_byte(cmd)
|
||||
time.sleep(HX.POWER_RESPONSE_DELAY)
|
||||
|
||||
# Get response
|
||||
response = self.i2c_bus.read_byte(HX.POWER_ADDRESS)
|
||||
|
||||
# Return
|
||||
return response
|
||||
except IOError:
|
||||
return HX.IOE_RSP
|
||||
|
||||
def enable_bt(self):
|
||||
# Enable power from BT
|
||||
if not self.bt_enabled:
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_ENABLE_BT)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already enabled? OK!
|
||||
return HX.OK_RSP
|
||||
|
||||
def disable_bt(self):
|
||||
# Disable power from BT
|
||||
if self.bt_enabled:
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_DISABLE_BT)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already disabled? OK!
|
||||
return HX.OK_RSP
|
||||
|
||||
def enable_us(self):
|
||||
# Enable USB power
|
||||
if not self.us_enabled:
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_ENABLE_US)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already enabled? OK!
|
||||
return HX.OK_RSP
|
||||
|
||||
def disable_us(self):
|
||||
# Disable USB power
|
||||
if self.us_enabled:
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_DISABLE_US)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already disabled? OK!
|
||||
return HX.OK_RSP
|
||||
|
||||
def enable_mv(self):
|
||||
# Enable PowerFunctions and servos
|
||||
if not self.mv_enabled:
|
||||
# Save MV enable time
|
||||
self.__mv_enable_time = time.clock()
|
||||
self.mv_blocked = True
|
||||
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_ENABLE_MV)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already enabled? OK!
|
||||
return HX.OK_RSP
|
||||
|
||||
def disable_mv(self):
|
||||
# Disable PowerFunctions and servos
|
||||
if self.mv_enabled:
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_DISABLE_MV)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already disabled? OK!
|
||||
return HX.OK_RSP
|
||||
|
||||
def enable_ba(self):
|
||||
# Enable BA
|
||||
if not self.ba_enabled:
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_ENABLE_BA)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already enabled? OK!
|
||||
return HX.OK_RSP
|
||||
|
||||
def disable_ba(self):
|
||||
# Disable BA
|
||||
if self.ba_enabled:
|
||||
# Run command
|
||||
result = self.send_cmd(HX.COM_DISABLE_BA)
|
||||
|
||||
# Return
|
||||
return result
|
||||
else:
|
||||
# Already disabled? OK!
|
||||
return HX.OK_RSP
|
||||
171
HXbot/HXserver.py
Executable file
171
HXbot/HXserver.py
Executable file
@@ -0,0 +1,171 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# HXbot server module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import HX
|
||||
import threading
|
||||
import socket
|
||||
import sys
|
||||
import struct
|
||||
|
||||
|
||||
class HXserverClass():
|
||||
|
||||
def __init__(self, hxbot):
|
||||
super(HXserverClass, self).__init__()
|
||||
|
||||
try:
|
||||
self.s = socket.socket(family=socket.AF_INET,
|
||||
type=socket.SOCK_DGRAM)
|
||||
self.s.bind((HX.SRV_HOST, HX.SRV_PORT))
|
||||
self.s.settimeout(HX.SRV_TIMEOUT)
|
||||
except OSError as E:
|
||||
print(E)
|
||||
sys.exit()
|
||||
|
||||
self.hxbot = hxbot
|
||||
|
||||
self.hxpower = None
|
||||
self.reflex = None
|
||||
self.joystick = None
|
||||
self.hxlcd = None
|
||||
self.hxcam = None
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
self.is_running = False
|
||||
|
||||
def start(self):
|
||||
self.hxpower = self.hxbot.hxpower
|
||||
self.reflex = self.hxbot.reflex
|
||||
self.joystick = self.hxbot.joystick
|
||||
self.hxlcd = self.hxbot.hxlcd
|
||||
self.hxcam = self.hxbot.hxcam
|
||||
|
||||
self.__e = threading.Event()
|
||||
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
|
||||
|
||||
self.__t.start()
|
||||
self.is_running = True
|
||||
|
||||
def stop(self):
|
||||
self.__e.set()
|
||||
self.__t.join()
|
||||
self.is_running = False
|
||||
|
||||
self.hxpower = None
|
||||
self.reflex = None
|
||||
self.joystick = None
|
||||
self.hxlcd = None
|
||||
self.hxcam = None
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
def __process(self, stopRequest):
|
||||
while not stopRequest.is_set():
|
||||
try:
|
||||
data = self.s.recvfrom(1024)
|
||||
except socket.timeout:
|
||||
continue
|
||||
|
||||
cmd = data[0][0]
|
||||
client = data[1]
|
||||
|
||||
if cmd == HX.SRV_CMD_GET_ALL:
|
||||
self.s.sendto(self.__pack_all(), client)
|
||||
else:
|
||||
pass
|
||||
|
||||
self.s.close()
|
||||
|
||||
def __pack_all(self):
|
||||
# INIT
|
||||
pw = self.hxpower
|
||||
rf = self.reflex
|
||||
lc = self.hxlcd
|
||||
|
||||
ca = self.hxcam
|
||||
if ca is not None:
|
||||
ca_mcam_state = ca.mcam_state
|
||||
ca_rcam_state = ca.rcam_state
|
||||
ca_mmic_state = ca.mmic_state
|
||||
else:
|
||||
ca_mcam_state = 2
|
||||
ca_rcam_state = 2
|
||||
ca_mmic_state = 2
|
||||
|
||||
js = self.joystick
|
||||
if js is not None:
|
||||
js_online = js.online
|
||||
else:
|
||||
js_online = False
|
||||
|
||||
result = struct.pack(
|
||||
'fffffffffff??????????????????????????????????????????????BBB',
|
||||
pw.vcc,
|
||||
pw.vin,
|
||||
pw.vdc,
|
||||
pw.vbt,
|
||||
pw.vba,
|
||||
pw.vpf,
|
||||
pw.vzu,
|
||||
pw.abt,
|
||||
pw.aba,
|
||||
pw.ain,
|
||||
pw.ahx,
|
||||
pw.online,
|
||||
pw.vcc_ok,
|
||||
pw.vin_ok,
|
||||
pw.vdc_ok,
|
||||
pw.vbt_ok,
|
||||
pw.vba_ok,
|
||||
pw.vpf_ok,
|
||||
pw.vzu_ok,
|
||||
pw.abt_ok,
|
||||
pw.aba_ok,
|
||||
pw.ain_ok,
|
||||
pw.ahx_ok,
|
||||
pw.bt_enabled,
|
||||
pw.ba_enabled,
|
||||
pw.bt_blocked,
|
||||
pw.ba_blocked,
|
||||
pw.vcc_low,
|
||||
pw.vcc_high,
|
||||
pw.vin_low,
|
||||
pw.vin_high,
|
||||
pw.vdc_low,
|
||||
pw.vdc_high,
|
||||
pw.vbt_low,
|
||||
pw.vbt_full,
|
||||
pw.vba_low,
|
||||
pw.vba_full,
|
||||
pw.vpf_low,
|
||||
pw.vpf_high,
|
||||
pw.vzu_low,
|
||||
pw.vzu_high,
|
||||
pw.abt_low,
|
||||
pw.abt_high,
|
||||
pw.aba_low,
|
||||
pw.aba_high,
|
||||
pw.ain_low,
|
||||
pw.ain_high,
|
||||
pw.ahx_low,
|
||||
pw.ahx_high,
|
||||
pw.mv_enabled,
|
||||
pw.us_enabled,
|
||||
pw.in_plugged,
|
||||
pw.ba_full,
|
||||
pw.bt_full,
|
||||
rf.online,
|
||||
js_online,
|
||||
lc.online,
|
||||
ca_mcam_state,
|
||||
ca_rcam_state,
|
||||
ca_mmic_state)
|
||||
|
||||
return result
|
||||
1
HXbot/HXsound.py
Executable file
1
HXbot/HXsound.py
Executable file
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
224
HXbot/REflex.py
Executable file
224
HXbot/REflex.py
Executable file
@@ -0,0 +1,224 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
########################################
|
||||
# REflex communication module #
|
||||
# EoF 2016 EoF@itphx.ru #
|
||||
########################################
|
||||
|
||||
import threading
|
||||
import time
|
||||
import HX
|
||||
|
||||
|
||||
class REflexClass():
|
||||
|
||||
def __init__(self, hxbot):
|
||||
self.i2c_bus = hxbot.i2c_bus
|
||||
self.hxbot = hxbot
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
self.lock = hxbot.reflex_lock
|
||||
|
||||
self.joystick = None
|
||||
self.hxpower = None
|
||||
self.control = HX.CONTROL_SRC_DEFAULT
|
||||
|
||||
self.error_count = 0
|
||||
self.online = False
|
||||
self.is_running = False
|
||||
|
||||
self.ready_to_move = False
|
||||
self.last_command_time = 0.0
|
||||
|
||||
self.__move_float = 0
|
||||
self.__steer_center = 0
|
||||
|
||||
# Tuple of commands for execute
|
||||
self.m = (
|
||||
False, # Check
|
||||
HX.MOVE_FLOAT, # Move
|
||||
HX.STEER_CENTER, # Steer
|
||||
HX.HEAD_V_CENTER, # Head vertical orientation
|
||||
HX.HEAD_H_CENTER # Head horizontal orientation
|
||||
)
|
||||
|
||||
# Tuple with results of executions
|
||||
self.s = (
|
||||
HX.NO_RSP,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
)
|
||||
|
||||
def start(self):
|
||||
self.joystick = self.hxbot.joystick
|
||||
self.hxpower = self.hxbot.hxpower
|
||||
|
||||
self.__e = threading.Event()
|
||||
self.__t = threading.Thread(target=self.__process, args=(self.__e, ))
|
||||
|
||||
self.__t.start()
|
||||
self.is_running = True
|
||||
|
||||
def stop(self):
|
||||
self.__e.set()
|
||||
self.__t.join()
|
||||
self.is_running = False
|
||||
|
||||
self.__e = None
|
||||
self.__t = None
|
||||
|
||||
self.joystick = None
|
||||
self.hxpower = None
|
||||
|
||||
def start_move(self):
|
||||
result = HX.OK_RSP
|
||||
|
||||
# Enable moving
|
||||
if not self.hxpower.mv_enabled:
|
||||
result = self.hxpower.enable_mv()
|
||||
|
||||
if result != HX.OK_RSP:
|
||||
return
|
||||
|
||||
self.ready_to_move = True
|
||||
|
||||
def stop_move(self, non_block=False):
|
||||
result = HX.OK_RSP
|
||||
|
||||
# Disable moving
|
||||
if self.hxpower.mv_blocked and not non_block:
|
||||
return
|
||||
|
||||
if self.hxpower.mv_enabled:
|
||||
result = self.hxpower.disable_mv()
|
||||
|
||||
if result != HX.OK_RSP:
|
||||
return
|
||||
|
||||
self.ready_to_move = False
|
||||
|
||||
def get_temp(self):
|
||||
return self.__send_command(HX.COM_GET_TEMP)
|
||||
|
||||
def __send_command(self, command):
|
||||
try:
|
||||
with self.lock:
|
||||
self.i2c_bus.write_word_data(HX.REFLEX_ADDRESS, command, 0)
|
||||
time.sleep(HX.REFLEX_RESPONSE_DELAY)
|
||||
response = self.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
|
||||
except IOError:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
if self.error_count >= HX.REFLEX_ERROR_LIMIT:
|
||||
self.online = False
|
||||
return HX.IOE_RSP
|
||||
else:
|
||||
self.error_count = 0
|
||||
self.online = True
|
||||
return response
|
||||
|
||||
return HX.NO_RSP
|
||||
|
||||
def __send_ex_command(self, flag, command):
|
||||
try:
|
||||
with self.lock:
|
||||
self.i2c_bus.write_word_data(HX.REFLEX_ADDRESS, HX.EXT_COM,
|
||||
flag << 8 | command)
|
||||
time.sleep(HX.REFLEX_RESPONSE_DELAY)
|
||||
response = self.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
|
||||
except IOError:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
if self.error_count >= HX.REFLEX_ERROR_LIMIT:
|
||||
self.online = False
|
||||
return HX.IOE_RSP
|
||||
else:
|
||||
self.error_count = 0
|
||||
self.online = True
|
||||
return response
|
||||
|
||||
return HX.NO_RSP
|
||||
|
||||
def __get_byte(self):
|
||||
try:
|
||||
with self.lock:
|
||||
response = self.i2c_bus.read_byte(HX.REFLEX_ADDRESS)
|
||||
except IOError:
|
||||
if self.online:
|
||||
self.error_count += 1
|
||||
if self.error_count >= HX.REFLEX_ERROR_LIMIT:
|
||||
self.online = False
|
||||
return HX.IOE_RSP
|
||||
else:
|
||||
self.error_count = 0
|
||||
self.online = True
|
||||
return response
|
||||
|
||||
def __process(self, stopRequest):
|
||||
# Process loop
|
||||
while not stopRequest.is_set():
|
||||
# Init cycle
|
||||
have_commands = False
|
||||
|
||||
# Ping REflex
|
||||
self.__send_command(HX.COM_PING)
|
||||
|
||||
# Joystick
|
||||
if self.control == HX.CONTROL_SRC_JOYSTICK and self.joystick:
|
||||
if self.joystick.ready:
|
||||
# Joystick ready! Let's go!
|
||||
if not self.ready_to_move:
|
||||
self.start_move()
|
||||
|
||||
# Get m
|
||||
self.m = self.joystick.get_m()
|
||||
have_commands = self.m[0]
|
||||
else:
|
||||
if self.ready_to_move:
|
||||
self.stop_move(True)
|
||||
time.sleep(0.5)
|
||||
|
||||
# Execute received commands
|
||||
if have_commands:
|
||||
self.s = self.execute(self.m)
|
||||
|
||||
# No commands? Stop move...
|
||||
elif (time.clock() - self.last_command_time >=
|
||||
HX.REFLEX_MOVE_TIMEOUT / 100):
|
||||
self.stop_move()
|
||||
|
||||
def execute(self, m):
|
||||
# Move
|
||||
if m[1] != HX.MOVE_FLOAT:
|
||||
move_rsp = self.__send_ex_command(HX.MOVE_FLAG, m[1])
|
||||
self.__move_float = 0
|
||||
elif self.__move_float < 3:
|
||||
move_rsp = self.__send_ex_command(HX.MOVE_FLAG, m[1])
|
||||
self.__move_float += 1
|
||||
else:
|
||||
move_rsp = HX.OK_RSP
|
||||
|
||||
# Steer
|
||||
if m[2] != HX.STEER_CENTER:
|
||||
steer_rsp = self.__send_ex_command(HX.STEER_FLAG, m[2])
|
||||
self.__steer_center = 0
|
||||
elif self.__steer_center < 3:
|
||||
steer_rsp = self.__send_ex_command(HX.STEER_FLAG, m[2])
|
||||
self.__steer_center += 1
|
||||
else:
|
||||
steer_rsp = HX.OK_RSP
|
||||
|
||||
# Head vertiacal orientation
|
||||
head_v_rsp = self.__send_ex_command(HX.HEAD_V_FLAG, m[3])
|
||||
|
||||
# Head horizontal orientation
|
||||
head_h_rsp = self.__send_ex_command(HX.HEAD_H_FLAG, m[4])
|
||||
|
||||
# Set last command time
|
||||
self.last_command_time = time.clock()
|
||||
|
||||
# Return execution status
|
||||
return (HX.OK_RSP, move_rsp, steer_rsp, head_v_rsp, head_h_rsp)
|
||||
BIN
HXbot/__pycache__/HX.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/HX.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/HX.cpython-35.pyc
Normal file
BIN
HXbot/__pycache__/HX.cpython-35.pyc
Normal file
Binary file not shown.
BIN
HXbot/__pycache__/HXcam.cpython-35.pyc
Normal file
BIN
HXbot/__pycache__/HXcam.cpython-35.pyc
Normal file
Binary file not shown.
BIN
HXbot/__pycache__/HXcontrol.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/HXcontrol.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/HXdb.cpython-35.pyc
Normal file
BIN
HXbot/__pycache__/HXdb.cpython-35.pyc
Normal file
Binary file not shown.
BIN
HXbot/__pycache__/HXjoystick.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/HXjoystick.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/HXjoystick.cpython-35.pyc
Executable file
BIN
HXbot/__pycache__/HXjoystick.cpython-35.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/HXlcd.cpython-35.pyc
Normal file
BIN
HXbot/__pycache__/HXlcd.cpython-35.pyc
Normal file
Binary file not shown.
BIN
HXbot/__pycache__/HXpower.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/HXpower.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/HXpower.cpython-35.pyc
Normal file
BIN
HXbot/__pycache__/HXpower.cpython-35.pyc
Normal file
Binary file not shown.
BIN
HXbot/__pycache__/HXserver.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/HXserver.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/HXserver.cpython-35.pyc
Normal file
BIN
HXbot/__pycache__/HXserver.cpython-35.pyc
Normal file
Binary file not shown.
BIN
HXbot/__pycache__/HXu.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/HXu.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/HXwatchdog.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/HXwatchdog.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/REflex.cpython-34.pyc
Executable file
BIN
HXbot/__pycache__/REflex.cpython-34.pyc
Executable file
Binary file not shown.
BIN
HXbot/__pycache__/REflex.cpython-35.pyc
Normal file
BIN
HXbot/__pycache__/REflex.cpython-35.pyc
Normal file
Binary file not shown.
29
HXbot/hxbot.nja
Executable file
29
HXbot/hxbot.nja
Executable file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"mainFile": "HXbot.py",
|
||||
"use-tabs": false,
|
||||
"venv": "",
|
||||
"relatedProjects": [],
|
||||
"name": "HXbot",
|
||||
"license": "GNU General Public License v3",
|
||||
"url": "",
|
||||
"pythonPath": "/usr/bin/python3",
|
||||
"preExecScript": "",
|
||||
"additional_builtins": [],
|
||||
"programParams": "",
|
||||
"indentation": 4,
|
||||
"PYTHONPATH": "",
|
||||
"supported-extensions": [
|
||||
".py",
|
||||
".html",
|
||||
".jpg",
|
||||
".png",
|
||||
".ui",
|
||||
".css",
|
||||
".json",
|
||||
".js",
|
||||
".ini"
|
||||
],
|
||||
"project-type": "Import from sources",
|
||||
"postExecScript": "",
|
||||
"description": "Main program of HXbot"
|
||||
}
|
||||
Reference in New Issue
Block a user