This is because the basic forward
, backward
, left
, and right
commands don’t allow for precision in turning or motion - these commands are intended to be used in simple “teach me about the robot” cases - like bloxter - where precision is not a requirement.
To move and turn with precision, you need to use the set_motor_dps
commands like this:
- Measure/capture the actual value - with the sign - of the y_axis, (forward and back) and the x_axis, (left and right).
- Decide on what maximum speed you want the robot to travel at - 100 dps, 500 dps, whatever - and set
max_speed
to that value.
- 300 is a good starting point. Use a smaller number if you want the robot to move more slowly.
- For forward and backward motion, you need to generate a speed value for the motors that is proportional to the degree of deflection of the y_axis.
- Since a normalized gamepad’s joystick returns values between 0 and 1, you can use these as percentages directly and calculate the speed by doing this:
desired_speed = int((max_speed * y_axis) * -1)
- The “-1” flips the sign so that the robot moves in the correct direction and the
int
makes sure the value is a whole number without a fractional part.)
- For straight travel, you do this:
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_LEFT, desired_speed)
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_RIGHT, desired_speed)
- In order to turn, the inside wheel - the wheel you are turning toward - has to be moving more slowly than the outside wheel. To do that, you need to calculate a “differential_speed” which is a speed value that is some fraction of the desired_speed - such that the greater the x_axis deflection, the slower the inside wheel goes. This way, a small movement of the joystick to the left or right makes a small turn and a large movement of the x_axis makes a correspondingly sharper turn.
- You do that calculation like this:
differential_speed = int(desired_speed - abs(desired_speed * x_axis))
This requires a bit more explanation:
- The (
desired_speed * x_axis
) gives the fractional part of the desired speed represented by the x_axis movement.
- (i.e. If the x_axis is moved a small amount, (0.1), the product becomes a very tiny number. If it is moved more, (0.5), that number becomes larger.)
- What we want is the amount of the desired speed left over after the tiny number is removed - so we subtract it from the desired speed.
- As you move the x_axis further, the number gets larger and the subtracted speed becomes smaller - which is what you want since that will make the turn sharper the further the x_axis is moved.
- You then apply the
differential_speed
to the inside wheel.
- Moving backward is exactly the same, except the sign is negative.
-
You also have to test the sign of the x_axis value so you know which wheel needs to move more slowly.
- If the x_axis is negative, you apply the
desired_speed
to the right wheel and differential_speed
to the left wheel.
- If the x_axis is positive, you apply the
desired_speed
to the left wheel and the differential_speed
to the right wheel. This will make the robot turn in the correct direction regardless of if it is moving backwards or forward.
Try it and tell me how it works.
=======================
Update
I tried adjusting my calculations as shown above and there were difficulties.
My original logic works.
############################
## Motion Selection ##
############################
# Depending on the position of the x and y axes
# and the state of trigger_1, we determine
# **IF** the robot should be moving,
# and **WHAT DIRECTION** it should be moving in.
#
if force == 0 or trigger_1 == 0:
my_gopigo3.stop()
print("Robot Stopped. . .\n")
elif trigger_1 == 1 and y_axis < 0:
# We're moving forward - either straight, left, or right.
print("The robot is moving forward and is ", end="")
# if we're not moving directly forward, the inside wheel must be slower
# than the outside wheel by some percentage.
# When moving to the left, the left wheel must be moving slower than
# the right wheel by some percentage, depending on the sharpness of the turn.
# "set_motor_dps" allows the wheels to be set to individual speeds.
if x_axis < 0: # Moving fowrard to the left
desired_speed = int(calc_desired_speed(speed, force))
differential_speed = int(calculate_differential_speed(desired_speed, x_axis))
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_RIGHT, desired_speed)
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_LEFT, differential_speed)
print("moving forward to the left\n")
# Moving to the right, we apply the same logic as before, but swap wheels.
elif x_axis > 0: # Moving fowrard to the right
desired_speed = int(calc_desired_speed(speed, force))
differential_speed = int(calculate_differential_speed(desired_speed, x_axis))
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_LEFT, desired_speed)
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_RIGHT, differential_speed)
print("moving forward to the right\n")
else: # Moving directly forward
desired_speed = int(calc_desired_speed(speed, force))
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_LEFT, desired_speed)
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_RIGHT, desired_speed)
print("moving forward straight ahead\n")
elif trigger_1 == 1 and y_axis > 0:
# We're moving backward
# This is the exact same logic and calculation as moving forward
# Except that it's "backwards" (bad pun!)
# We do this by changing the sign of the speed requested.
# if we're not moving directly backward, the inside wheel must be slower
# than the outside wheel by some percentage.
print("The robot is moving backward and is ", end="")
# reduce maximum reverse speed to 1/2 forward speed
speed = speed * 0.5
if x_axis < 0: # Moving backward to the left
# Moving to the left, the left wheel must be moving slower than
# the right wheel by some percentage.
desired_speed = int(calc_desired_speed(speed, force))
differential_speed = int(calculate_differential_speed(desired_speed, x_axis))
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_RIGHT, -desired_speed)
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_LEFT, -differential_speed)
print("moving backward to the left\n")
elif x_axis > 0: # Moving backward to the right
# Moving to the right, we apply the same logic, but swap wheels.
desired_speed = int(calc_desired_speed(speed, force))
differential_speed = int(calculate_differential_speed(desired_speed, x_axis))
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_LEFT, -desired_speed)
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_RIGHT, -differential_speed)
print("moving backward to the right\n")
else: # Moving directly backward.
desired_speed = int(calc_desired_speed(speed, force))
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_LEFT, -desired_speed)
my_gopigo3.set_motor_dps(my_gopigo3.MOTOR_RIGHT, -desired_speed)
print("moving straight backward\n")
You will have to adjust variable names and such to match your code.