Skip to content

Robot not moving straight because of different friction in motor gears #13

@fjp

Description

@fjp

The odometry updates are working after the use of wheel joint delta angles to update the joint positions in the hardware interface (see the code here). However there is a problem when simply mapping the velocity command from the diff_drive_controller to the power output percentage for the motor driver in the RobotHW::write(). The robot is not moving straight, its moving slightly to the left. This is because one of the motors (the one on the left side) seems to have slightly higher internal gear friction. I have created a video to show this behaviour.

diff_drive_controller cannot solve this problem because it is only forwarding the /cmd_vel command: see its code here so it is not taking care whether the encoder ticks increase on one wheel but not the other.

As seen in the video possible solutions are:

  1. Use better hardware, more precise motors in this case - not really an option for me because I would like to keep using the current motors.
  2. Calibrate the motors in code using threshold/tolerance offset values to provide slightly different outputs to the motors, so that they move and stop at the same time.
  3. Implement a PID controller inside the high level DiffBot's RobotHW::write() method or in the low level motor driver node, something like u=k*(v_actual - v_target)? This should apply the correct amount of output power to a motor depending on the actual velocity error on the wheel joint. ROS Control expects that the commands coming from a controller such as diff_drive_controller (velocity command) must be applied at the actuators.

To get the robot driving straight are there other ways other than the ones mentioned above and which one should be used to solve the issue? I prefer the PID controller, because it seems to solve the problem with less code. I tried the 2nd option but it seems that a lot of if else cases or even a simple state machine are needed for this. And in case of the 3rd option where should the PID be implemented? In the high level hardware interface RobotHW::write() or the low level motor driver.py node? Currently I would put it in the high level hw interface because all the joint velocities (actual and desired) are already calculated there. But having it in the motor driver node seems also correct, although this will require at least another subscriber in this node or re-writing it so that it subscribes to the commanded and measured velocity.

Any suggestions are more than welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is neededquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions