Наработки за 5 лет

This commit is contained in:
2019-08-27 14:47:10 +05:00
commit f5582d88c3
56 changed files with 11117 additions and 0 deletions

366
HXbot/HX.py Executable file
View 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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1 @@
# -*- coding: utf-8 -*-

1
HXbot/HXlog.py Executable file
View File

@@ -0,0 +1 @@
# -*- coding: utf-8 -*-

587
HXbot/HXpower.py Executable file
View 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
View 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
View File

@@ -0,0 +1 @@
# -*- coding: utf-8 -*-

224
HXbot/REflex.py Executable file
View 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)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

29
HXbot/hxbot.nja Executable file
View 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"
}