Наработки за 5 лет
This commit is contained in:
Executable
+366
@@ -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$'
|
||||
Executable
+711
@@ -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()
|
||||
Executable
+257
@@ -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()
|
||||
Executable
+132
@@ -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()
|
||||
Executable
+234
@@ -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)
|
||||
Executable
+149
@@ -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
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
Executable
+587
@@ -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
|
||||
Executable
+171
@@ -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
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
Executable
+224
@@ -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)
|
||||
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
+29
@@ -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