4. Obstacle Avoidance¶
In this project, PiCar-X will detect obstacles in front of it while moving forward, and when the obstacles are too close, it will change the direction of moving forward.
Run the Code
cd ~/picar-x/example
sudo python3 4.avoiding_obstacles.py
After running the code, PiCar-X will walk forward.
If it detects that the distance of the obstacle ahead is less than 20cm, it will go backward.
If there is an obstacle within 20 to 40cm, it will turn left.
If there is no obstacle in the direction after turning left or the obstacle distance is greater than 25cm, it will continue to move forward.
Code
Note
You can Modify/Reset/Copy/Run/Stop the code below. But before that, you need to go to source code path like picar-x/example
. After modifying the code, you can run it directly to see the effect.
from picarx import Picarx
import time
POWER = 50
SafeDistance = 40 # > 40 safe
DangerDistance = 20 # > 20 && < 40 turn around,
# < 20 backward
def main():
try:
px = Picarx()
# px = Picarx(ultrasonic_pins=['D2','D3']) # tring, echo
while True:
distance = round(px.ultrasonic.read(), 2)
print("distance: ",distance)
if distance >= SafeDistance:
px.set_dir_servo_angle(0)
px.forward(POWER)
elif distance >= DangerDistance:
px.set_dir_servo_angle(30)
px.forward(POWER)
time.sleep(0.1)
else:
px.set_dir_servo_angle(-30)
px.backward(POWER)
time.sleep(0.5)
finally:
px.forward(0)
if __name__ == "__main__":
main()
How it works?
Importing the Picarx Module and Initializing Constants:
This section of the code imports the
Picarx
class from thepicarx
module, which is essential for controlling the Picarx robot. Constants likePOWER
,SafeDistance
, andDangerDistance
are defined, which will be used later in the script to control the robot’s movement based on distance measurements.from picarx import Picarx import time POWER = 50 SafeDistance = 40 # > 40 safe DangerDistance = 20 # > 20 && < 40 turn around, # < 20 backward
Main Function Definition and Ultrasonic Sensor Reading:
The
main
function is where the Picarx robot is controlled. An instance ofPicarx
is created, which activates the robot’s functionalities. The code enters an infinite loop, constantly reading the distance from the ultrasonic sensor. This distance is used to determine the robot’s movement.def main(): try: px = Picarx() while True: distance = round(px.ultrasonic.read(), 2) # [Rest of the logic]
Movement Logic Based on Distance:
The robot’s movement is controlled based on the
distance
read from the ultrasonic sensor. If thedistance
is greater thanSafeDistance
, the robot moves forward. If the distance is betweenDangerDistance
andSafeDistance
, it slightly turns and moves forward. If thedistance
is less thanDangerDistance
, the robot reverses while turning in the opposite direction.if distance >= SafeDistance: px.set_dir_servo_angle(0) px.forward(POWER) elif distance >= DangerDistance: px.set_dir_servo_angle(30) px.forward(POWER) time.sleep(0.1) else: px.set_dir_servo_angle(-30) px.backward(POWER) time.sleep(0.5)
Safety and Cleanup with the ‘finally’ Block:
The
try...finally
block ensures safety by stopping the robot’s motion in case of an interruption or error. This is a crucial part for preventing uncontrollable behavior of the robot.try: # [Control logic] finally: px.forward(0)
Execution Entry Point:
The standard Python entry point
if __name__ == "__main__":
is used to run the main function when the script is executed as a standalone program.if name == "main": main()
In summary, the script uses the Picarx module to control a robot, utilizing an ultrasonic sensor for distance measurement. The robot’s movement is adapted based on these measurements, ensuring safe operation through careful control and a safety mechanism in the finally block.