Lane following with Obstacles (LFP)
Contents
Lane following with Obstacles (LFP
)#
What you will need
An assembled and initialized Duckiebot;
Wheels calibration completed;
Camera calibration completed;
Joystick demo has been successfully launched;
A Duckietown city loop, as detailed in the appearance specifications.
What you will get
A Duckiebot driving autonomously in a Duckietown city loop with obstacles.
Difficulty Level
Easy
Expected results#
record results
Duckietown setup notes#
Before getting started, make sure your Duckietown is ready to go:
The layout adheres to the The Duckietown Operation Manual;
The lighting is “good”: ideally white diffused light. This demo relies on images from the camera and color detections, so avoid colored lights, reflections or other conditions that might confuse or blind the onboard image sensor;
Duckiebot setup notes#
Duckiebot in configuration DB21M, DB21J, or DB19.
The Duckiebot is powered on and connected to your network. You should be able to successfully ping it from your base station;
You are able to see what the Duckiebot sees;
You are able to remote control your Duckiebot;
The camera is calibrated;
Pre-flight checklist#
Place the Duckiebot inside a lane (driving on the right-hand side of the road), making sure it sees the lane lines;
Place some larger obstacles on the road
Demo instructions#
The instructions for running this demo are almost identical as the procedure for running the lane following demo, except we will use a different launcher. These instructions are:
Clone the dt-core
Repository#
First clone the dt-core
repository. From the command line run:
git clone [email protected]:duckietown/dt-core.git -b ente
which will create a folder called dt-core
with the contents of this repository.
Enter that repository:
cd dt-core
Optional: Running in the Duckiematrix#
If you would like to run the demo in the Duckiematrix, you should start by creating and starting your virtual robot:
dts duckiebot virtual create ![VIRTUAL_ROBOT_NAME]
dts duckiebot virtual start ![VIRTUAL_ROBOT_NAME]
Next, start the duckiematrix with command:
dts matrix run --standalone -m assets/duckiematrix/maps/loop_with_pedestrians
Note
This is a different map than the one used for the Lane Following Demo since now we have duckie pedestriancs crossing the street.
Then, in another terminal tab, you will need to attach your virtual robot to the entity in the duckiematrix by running:
dts matrix attach ![VIRTUAL_ROBOT_NAME] map_0/vehicle_0
Open a virtual joystick with
dts duckiebot keyboard_control ![VIRTUAL_ROBOT_NAME]
---
Pushing the controls on the virtual joystick should cause your robot
to move in the duckiematrix.
Build and Run the code#
Next build the code on your robot. From the dt-core
directory run:
dts devel build -H ![ROBOTNAME]
where ![ROBOTNAME]
is the name of your robot (virtual or real).
and then run with:
dts devel run -H ![ROBOTNAME] -L lane-following
When the demo is ready, you should see the LEDs on the Duckiebot turn
Start Autonomous Lane Following#
Run the keyboard controller:
dts duckiebot keyboard_control ![DUCKIEBOT_NAME]
and press A
to start the lane following “Autopilot”. You should see the front LEDs on the Duckiebot turn white
and the back ones turn
You can stop the “Autopilot” and return to joystick control by pressing S.
In this case, different than the basic Lane Following Demo, now if there
is an obstacle in the path that is big enough to be detected by the time-of-flight sensor (the little black square on
the front bumper), and you will see the LEDs all turn
If things are not working as expected, please look at the or Troubleshooting sections for suggestions.
You can also look at the same visualizations.
A specific signal you may be interested to observe is the range value that is being output by the time-of-flight sensor. To monitor it, a good way could be to do:
dts gui ![ROBOTNAME]
and then in the resulting terminal, open up an rqt_plot
window. In the top left, select the topic
![ROBOTNAME]/tof_driver_node/front_center_tof/range
.
How it Works#
The method of lane following is the same as How it Works. The additional
complexity here is due to the use of the time-of-flight sensor which is mounted on the
front bumper of your Duckiebot. Every time the reading from that sensor
drops below a certain threshold that is specified by a file in the
packages/obstacle_detection/tof_obstacle_detection_node
folder (either default.yaml
or ![ROBOTNAME].yaml
if you have created it).
You might look at the tof_obstacle_detection_node
source code (in packages/obstacle_detection/src/tof_obstacle_detection_node.py
and ask yourself exactly how this is causing the robot to stop when the range is too low.
The answer is through a finite state machine or FSM.
To understand this better, take a look at the file in packages/fsm/config/lane_following_pedestriancs.yaml
. This file
specifies what events
cause the FSM to transition states. In this case we can see:
obstacle_detected:
topic: "tof_obstacle_detection_node/obstacle_detected"
msg_type: "BoolStamped"
trigger: True
obstacle_cleared:
topic: "tof_obstacle_detection_node/obstacle_cleared"
msg_type: "BoolStamped"
trigger: True
in the list of events which are the topics that are published by the tof_obstacle_detection_node
.
Furthermore, if we look further below in the config file we can see
LANE_FOLLOWING:
transitions:
obstacle_detected: "STOP"
Which indicates that the obstacle_detected
event occuring will cause the FSM
to transition to state STOP
if it is presently in state LANE_FOLLOWING
.
This still doesn’t explain how the robot actually stops though. There is another node which helps with that
called the car_cmd_switch_node
whose configuration is located in robots/duckiebot/dagu_car/config/car_cmd_switch_node
.
If we look at the default.yaml
file in that folder we see a set of mappings
which indicate which
topic that produces control commands should be considered active for any given state. In there, we see
the following mappings:
mappings: #Mapping from FSMStates.state to cmd source names. Allows different FSM mode to use the same source.
NORMAL_JOYSTICK_CONTROL: "joystick"
LANE_FOLLOWING: "lane"
STOP: "stop"
This effectively acts as a multiplexer deciding which controller to actually connect to the wheels depending on the state output from the FSM.
Here we can see that in the STOP
mode we connect the simple_stop_controller_node
to the wheels
which has the effect of stopping them.
Parameter Tuning#
In this case there is really only one parameter that could be tuned, and that is the
threshold used by the tof_obstacle_detection_node
. Tuning this will result in
the stopping of the Duckiebot being triggered by obstacles that are further away.
But be careful, if you make it too large, the Duckiebot stopping could be triggered by
undesirable things (such as obstacles that are not actually in the road or by the road itself).