RoboRally/remote_control/control_commander.py

124 lines
5.2 KiB
Python
Raw Normal View History

2020-11-17 20:24:55 +00:00
import numpy as np
import time
from robot import ControlledRobot
from pid_controller import PIDController
from mpc_controller import MPCController
2020-11-17 20:24:55 +00:00
from event_listener import EventListener
class ControlCommander:
2020-11-22 14:57:53 +00:00
valid_controller_types = {'pid': PIDController,
'mpc': MPCController}
2020-11-17 20:24:55 +00:00
2020-11-22 14:57:53 +00:00
def __init__(self, id_ip_dict, controller_type='pid'):
"""
:param id_ip_dict: dictionary containing robot marker id and ip of the robot, e.g. { 12: '10.10.11.91' }
:param controller_type: string 'pid', 'mpc'; or dictionary with robot id and controller type string, e.g. { 12: 'mpc', 13: 'pid'}
"""
self.robots = {}
for id, ip in id_ip_dict.items():
self.robots[id] = ControlledRobot(id, ip)
for id, r in self.robots.items():
2020-11-17 20:24:55 +00:00
r.connect()
2020-11-22 14:57:53 +00:00
if type(controller_type) == dict:
for id, ctype in controller_type.items():
if ctype in ControlCommander.valid_controller_types:
self.robots[id].attach_controller(ControlCommander.valid_controller_types[ctype]())
2020-11-22 14:57:53 +00:00
else:
raise Exception(f"invalid controller type {ctype} specified for robot {id}. "
f"valid controller types are {list(ControlCommander.valid_controller_types.keys())}")
elif controller_type in ControlCommander.valid_controller_types:
2020-11-22 14:57:53 +00:00
for id, r in self.robots.items():
r.attach_controller(ControlCommander.valid_controller_types[controller_type]())
2020-11-22 14:57:53 +00:00
else:
raise Exception(f"invalid controller type {controller_type} specified. valid controller types are "
f"{list(ControlCommander.valid_controller_types.keys())}")
2020-11-17 20:24:55 +00:00
self.event_listener = EventListener(event_server=('127.0.0.1', 42424))
self.current_robot_index = 0
self.controlling = False
self.running = False
def run(self):
2020-11-22 14:57:53 +00:00
unconnected_robots = list(filter(lambda r: not r.connected, self.robots.values()))
2020-11-17 20:24:55 +00:00
if len(unconnected_robots) > 0:
print(f"warning: could not connect to the following robots: {unconnected_robots}")
return
all_detected = False
while not all_detected:
2020-11-22 14:57:53 +00:00
undetected_robots = list(filter(lambda r: None in r.get_measurement(), self.robots.values()))
2020-11-17 20:24:55 +00:00
all_detected = len(undetected_robots) == 0
if not all_detected:
print(f"warning: no measurements available for the following robots: {undetected_robots}")
time.sleep(0.5)
2021-09-09 22:43:02 +00:00
print("all robots detected -> starting control")
2020-11-17 20:24:55 +00:00
self.running = True
while self.running:
while not self.event_listener.event_queue.empty():
event = self.event_listener.event_queue.get()
self.handle_event(event)
def handle_event(self, event):
# handle events from opencv window
print("event: ", event)
if event[0] == 'click': # non-blocking move to target pos
2020-11-17 20:24:55 +00:00
target = event[1]
target_pos = np.array([target['x'], target['y'], target['angle']])
2020-11-22 14:57:53 +00:00
controlled_robot_id = list(self.robots.keys())[self.current_robot_index]
self.robots[controlled_robot_id].move_to_pos(target_pos)
elif event[0] == 'move_blocking': # blocking move to specified target position
target = event[1]
target_pos = np.array([target['x'], target['y'], target['angle']])
controlled_robot_id = list(self.robots.keys())[self.current_robot_index]
# initialize move and wait for the robot to reach the target position
self.robots[controlled_robot_id].move_to_pos(target_pos, blocking=True)
#time.sleep(0.5)
# send confirmation to the server which initiated the command
self.event_listener.send_reply("ack\n".encode())
2020-11-17 20:24:55 +00:00
elif event[0] == 'key':
key = event[1]
if key == 16777235: # arrow up
2020-11-17 20:24:55 +00:00
self.controlling = not self.controlling
if not self.controlling:
print("disable control")
2020-11-22 14:57:53 +00:00
for _, r in self.robots.items():
2020-11-17 20:24:55 +00:00
r.stop_control()
else:
print("enable control")
2020-11-22 14:57:53 +00:00
for _, r in self.robots.items():
2020-11-17 20:24:55 +00:00
r.start_control()
elif key == 16777236: # left
2020-11-17 20:24:55 +00:00
# switch controlled robot
self.current_robot_index = (self.current_robot_index + 1) % len(self.robots)
2020-11-22 14:57:53 +00:00
controlled_robot_id = list(self.robots.keys())[self.current_robot_index]
robot = self.robots[controlled_robot_id]
2020-11-17 20:24:55 +00:00
print(f"controlled robot: {robot.id}")
elif key == 113 or key == 27: # q or ESCAPE
print("quit!")
for r in self.robots:
r.stop_control()
self.running = False
if __name__ == '__main__':
2020-11-22 14:57:53 +00:00
id_ip_dict = {
#11: '10.10.11.88',
2021-09-09 22:43:02 +00:00
#12: '192.168.1.12',
13: '192.168.1.13',
#14: '10.10.11.89',
2020-11-22 14:57:53 +00:00
}
# controller_type = {12: 'mpc', 13: 'pid'}
2021-09-09 22:43:02 +00:00
controller_type = 'mpc'
2020-11-22 14:57:53 +00:00
rc = ControlCommander(id_ip_dict, controller_type=controller_type)
2020-11-17 20:24:55 +00:00
rc.run()