iRobotEducation / irobot-edu-python-sdk

Python SDK for iRobot Edu robots (Root or Create 3)
BSD 3-Clause "New" or "Revised" License
16 stars 6 forks source link

Cliff sensor and touch sensor problems #12

Closed scottcandy34 closed 1 year ago

scottcandy34 commented 1 year ago

I have create3 robot Firmware version (G.3.1) the current cliff sensor does not trigger an event based on the Bluetooth docs here https://github.com/iRobotEducation/root-robot-ble-protocol#command-0---cliff-event although it does trigger on the touch sensor event. Very strange since the documentation does not describe this possibility here https://github.com/iRobotEducation/root-robot-ble-protocol#command-0---touch-sensor-event

Below I have attached my override class code for cliff sensor events. This will trigger only on any of the front cliff sensors and [true, false, false, false] for any combination. Can this be addressed in the create3.py. I'll also leave an issue in the Bluetooth docs. Here https://github.com/iRobotEducation/create3_docs/issues/312

class CliffSensor:
    def __init__(self):
        self.left = False
        self.left_front = False
        self.right = False
        self.right_front = False

class Create3(Create3):
    def __init__(self, backend):
        super().__init__(backend)

        self._events = {
            (0, 4): self._when_stop_button_handler,
            (1, 29): self._when_motor_stalled_handler,
            (12, 0): self._when_bumped_handler,
            (14, 0): self._when_battery_handler,
            (17, 0): self._when_touched_handler and self._when_cliff_sensor_handler,
        }
        self.cliff_sensor = CliffSensor()

    def when_cliff_sensor(self, condition: list[bool, bool, bool, bool], callback: Callable[[bool], Awaitable[None]]):
        """Register when cliff callback of type: async def fn(over_cliff: bool)."""
        self._when_cliff_sensor.append(Event(condition, callback))

    async def _when_cliff_sensor_handler(self, packet):
        self.cliff_sensor.disable_motors = packet.payload[4] != 0
        for event in self._when_cliff_sensor:
            self.cliff_sensor.right = packet.payload[4] & 0x01 != 0
            self.cliff_sensor.right_front = packet.payload[4] & 0x02 != 0
            self.cliff_sensor.left_front = packet.payload[4] & 0x04 != 0
            self.cliff_sensor.left = packet.payload[4] & 0x08 != 0

            # An empty condition list means to trigger the event on every occurrence.
            if not event.condition and (self.cliff_sensor.left or self.cliff_sensor.left_front or self.cliff_sensor.right_front or self.cliff_sensor.right):  # Any.
                await event.run(self)
                continue
            if len(event.condition) > 1 and ((event.condition[0] == self.cliff_sensor.left) and (event.condition[1] == self.cliff_sensor.left_front) and (event.condition[2] == self.cliff_sensor.right_front) and (event.condition[3] == self.cliff_sensor.right)):
                await event.run(self)
shamlian commented 1 year ago

This is two bugs. I'd split them as linked tickets, but one would just get closed invalid.

As discussed in the linked ticket in the create3_docs repository, there is an implementation bug in Create 3 firmware <G.4 where the robot is sending cliff sensor events with device 17 instead of device 20. This will be fixed in the next Create 3 firmware release.

I do not plan to take this requested patch, since there is a bug in the robot and not in the implementation. (The Python code as it is works for Root.) I will close this issue once we've released a fixed firmware for the Create 3 robot.

scottcandy34 commented 1 year ago

Ok Thx

shamlian commented 1 year ago

This should be fixed in G.4.1; please download it and let us know!