hxbot/HXbot/REflex.py

224 lines
6.2 KiB
Python
Executable File

# -*- 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)