class Controller(object): """Controller model""" def __init__(self): self.server = Server(CONTROLLER_PORT, 'controller') self.sensor = Client(SENSOR_PORT, 'sensor', 1) self.rate = Rate(1) # Hz def dispatch(self): """Runs a single cycle of the controller process""" sensor_msg = self.sensor.recv() if not sensor_msg: return None logger.info("Received sensor position: %s", sensor_msg) reported_y = sensor_msg['y'] # The y axis is deliberately driven to zero, # so any reported y axis position is the error. error = reported_y self.publish({ 'delta_x': X_DELTA, 'delta_y': -1 * error }) # Sleep to achieve a 1Hz command rate self.rate.sleep() def publish(self, move_cmd): """Publish the move command""" self.server.publish(move_cmd)
def do_server(): server = Server(10020, "example_server") rate = Rate(1) while True: server.publish({"msg": "Hello World!"}) rate.sleep()
class Welder(object): """Welder model""" def __init__(self): self.server = Server(WELDER_PORT, 'welder') self.controller = Client(CONTROLLER_PORT, 'controller', 1) self.x = 0 self.y = 0 def dispatch(self): """Runs a single cycle of the welder process""" # Grab the latest move command move_cmd = self.controller.recv() if not move_cmd: move_cmd = { 'delta_x': 0, 'delta_y': 0 } # Apply it self.drive(move_cmd) # Publish state self.publish() def drive(self, move_cmd): """Takes a drive command and applies it""" logger.info("Received dx dy commands: %s, %s", move_cmd['delta_x'], move_cmd['delta_y'] ) delta_x = move_cmd['delta_x'] delta_y = move_cmd['delta_y'] + (random.random() * MAX_Y_ERROR) self.x += delta_x self.y += delta_y @property def state(self): """Returns the current state in a serializable format""" return { 'x': self.x, 'y': self.y, } def publish(self): """Publish a welder state update""" self.server.publish(self.state)
class Sensor(object): """Sensor model""" def __init__(self): self.server = Server(SENSOR_PORT, 'sensor') self.welder = Client(WELDER_PORT, 'welder', 1) def dispatch(self): """Execute a single cycle of the sensor process""" # Of course the sensor does not have direct knowledge # of the end effector's position. But to model the sensor's # behavior, it needs to be based on the truth of the # welder's actual position. welder_msg = self.welder.recv() if not welder_msg: return None self.publish({'x': welder_msg['x'], 'y': welder_msg['y']}) def publish(self, data): """Publish a sensor output message""" self.server.publish(data)
def __init__(self): self.quit_event = trio.Event() self.codec = NativeCodec() self.server = Server(PacketTransport, self._handle_request, self._handle_notification, self._handle_error)
class FileWriterServer: def __init__(self): self.quit_event = trio.Event() self.codec = NativeCodec() self.server = Server(PacketTransport, self._handle_request, self._handle_notification, self._handle_error) async def serve(self, address: bytes, *, task_status=trio.TASK_STATUS_IGNORED): async with trio.open_nursery() as n: async def wait_quit(): await self.quit_event.wait() await trio.sleep(1) self.server.close() n.start_soon(wait_quit) await n.start(self.server.serve, address) print(f'Server starts: {self.server._socket}') task_status.started() def quit(self): self.quit_event.set() async def call(self, conn: Connection, method: str, *args: Any) -> Any: data, fds = self.codec.encode([method, *args]) data, fds = await conn.send(data, fds) return self.codec.decode(data, fds) async def _handle_request(self, conn: Connection, data: Bytes, fds: List[Fd]) -> Tuple[Bytes, List[Fd]]: method, *args = self.codec.decode(data, fds) if method == "quit": print('Quit?') if await self.call(conn, 'quit?'): print('Quit!') self.quit() else: print('Nope!') result = True, elif method == "write": fd, content = args print(f'Writing to fd {fd.get()}.') try: with open(fd.take(), 'at') as fh: written = fh.write(pformat(content) + '\n') result = True, written except Exception as e: result = False, str(e) else: result = False, 'unknown method', method return self.codec.encode(result) async def _handle_notification(self, conn: Connection, data: Bytes, fds: List[Fd]) -> None: raise NotImplementedError async def _handle_error(self, conn: Connection, err: Exception): print('Error:', conn, err) self.quit() raise err
def __init__(self): self.server = Server(CONTROLLER_PORT, 'controller') self.sensor = Client(SENSOR_PORT, 'sensor', 1) self.rate = Rate(1) # Hz
def __init__(self): self.server = Server(SENSOR_PORT, 'sensor') self.welder = Client(WELDER_PORT, 'welder', 1)
def __init__(self): self.server = Server(WELDER_PORT, 'welder') self.controller = Client(CONTROLLER_PORT, 'controller', 1) self.x = 0 self.y = 0