ev3dev / ev3dev-lang-python

Pure python bindings for ev3dev
MIT License
429 stars 145 forks source link

Add the ability to reset the position of the motors in odometry_start() #758

Open foocross opened 4 years ago

foocross commented 4 years ago

It would be helpful to be able top reset the motor positions at odometry start as well as set the coordinates. There are many instances (such as when you want to move the robot) that you want to have a clean slate on your odometry.

WasabiFan commented 4 years ago

Thanks for the contribution! To help me understand the use-case here, how does this differ from setting the positions before starting odometry? It seems like resetting motor positions is not directly related to starting the odometry thread; is the idea that you often want to reset the motor positions at the same time as starting odometry, so you might as well have it together?

foocross commented 4 years ago

Hello - thanks for looking at my request. The use case is for FLL where someone would want to run some code, then move the robot and run a the code again or new code without restarting the program. You could create a different function to reset the positions but since the code already resets the odometry x,y it makes sense to also have the option to do it here.

WasabiFan commented 4 years ago

I suppose I'm just confused about why calling code cares about the motor position. The odometry uses the "position" value of the motors to compute deltas, but not absolute positions, meaning it shouldn't matter to the odometry system whether you have reset the position or not. Is your code separately using the position values of individual motors for something other than odometry? Or is there something about odometry that doesn't work if you don't reset the position (i.e., a bug)?

In case this isn't making sense, perhaps a brief explanation of Motor.position would help. This property exposes the number of encoder ticks -- by coincidence, also the number of degrees -- the individual motor has rotated since the EV3 booted. The absolute number is rather meaningless for a wheel unless you are taking a delta relative to some known position, which can either be done by subtraction or by setting the position manually to reset it. It's also meaningless in the sense that an individual motor's position doesn't tell you how much you've rotated, which significantly affects your real position.

foocross commented 4 years ago

If you look in motor.py in def _odometry_monitor. you see the code:

def _odometry_monitor():
            left_previous = 0
            right_previous = 0
            self.theta = math.radians(theta_degrees_start)  # robot heading
            self.x_pos_mm = x_pos_start  # robot X position in mm
            self.y_pos_mm = y_pos_start  # robot Y position in mm
            TWO_PI = 2 * math.pi
            self.odometry_thread_run = True

            while self.odometry_thread_run:

                # sample the left and right encoder counts as close together
                # in time as possible
                left_current = self.left_motor.position
                right_current = self.right_motor.position

                # determine how many ticks since our last sampling
                left_ticks = left_current - left_previous
                right_ticks = right_current - right_previous

If the robot has moved then self.left_motor.position and self.right_motor.position are not 0 but the left_current and right_current are 0. So the first pass makes it seem like the robot has moved a large distance which I doesn't make sense to me.

WasabiFan commented 4 years ago

Ah, I see what you're saying; that definitely seems like a bug. I think the following:

left_previous = 0
right_previous = 0

Should have presumably been:

left_previous = self.left_motor.position
right_previous = self.right_motor.position

Good catch!

@dwalton76 Are you watching this thread? Could you weigh in here?