Skip to content

Negative TachoMotor position sensor bugfix #7

@tuhe

Description

@tuhe

Hi!

I think this is a super cool project and I am really happy to see you are working on the new Control Plus hub :-). I noticed a small bug in the sensor readings. If I attach a CPlusMotor using

@attach(CPlusLargeMotor, name='stearing', port=2, capabilities=['sense_pos'])

and then steer it towards negative positions, sense_pos will return very large numbers. It seems negative numbers are encoded in the format max_value-abs(value), and the following (really dumb) fix to peripheral.py seems to solve the issue:

  async def update_value(self, msg_bytes):
       msg = bytearray(msg_bytes)
       if len(self.capabilities)==0:
           self.value = msg
       if len(self.capabilities)==1:
           capability = self.capabilities[0]
           datasets, bytes_per_dataset = self.datasets[capability][0:2]
           for i in range(datasets):
               msg_ptr = i*bytes_per_dataset
               val = self._convert_bytes(msg[msg_ptr: msg_ptr+bytes_per_dataset], bytes_per_dataset)

               # my fix
               if msg_bytes[-1] == 255:
                   b2 = [255 - b for b in msg_bytes]
                   msg2 = bytearray(b2)
                   val2 = self._convert_bytes(msg2[msg_ptr: msg_ptr + bytes_per_dataset], bytes_per_dataset)
                   val = -val2

               if datasets==1:
                   self.value[capability] = val
               else:
                   self.value[capability][i] = val

               if val > 10000:
                   raise Exception("bad position")

       if len(self.capabilities) > 1:
           await self._parse_combined_sensor_values(msg)

although the proper way is obviously to change _convert_bytes.

On a related note, I have model 42099 (which I guess from the examples you also got?) and I wonder if you have some input on the following: I have written a small control program for the 42099 model which takes keyboard inputs and try to accelerate and turn the front wheels using .set_pos(...). I change the position in small increments (+/- 15 degrees) based on keyboard inputs. Sometimes, it seems the motor will not fully perform the command, and instead freeze and make a high-pitched whining sound for about 0.5-1 seconds (and in this mode subsequent commands are paused). I have tried to change the max_power to 100 but this does not seem to fully solve the issue. I have also tried mucking around with the other input parameters to set_pos, including the speed, but to no avail (I confess I do not know what all of them really do).

This behavior is not one I have observed with the lego smartphone app, which seems to respond much more "crisply" to inputs. So my question is fairly high-level: If I wanted to write a control app to control the wheels, and avoid the above behavior (or more specifically, imitate the lego smartphone app), do you know if I should still use .set_pos and is there something obvious I am missing? I am attaching the code just in case it has any interest to anyone.

lego_device.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions