Turtlebot 3 is the perfect platform to deep into electronics, robotics and even AI! I propose you to build your own turtlebot step-by-step with affordable components without sacrificing features and performance. With one thing in mind: keeping the best from the initial robot, its modularity, simplicity and the huge number of packages for autonomous navigation and AI from the open-source community.
This project is an opportunity for beginners to acquire notions of electronics, mechanics and computer sciences, and for the more experienced to get a powerful platform to test and develop artificial intelligence algorithms.
What you will discover in this project?
You are about to discover which essential mechanical and electronic parts must be kept from the original bot to guarantee complete compatibility.
The whole build process will be detailed: going from 3D parts printing, assembling and the several components, soldering and integrating electronics to finally code compiling on Arduino. This instructable will conclude on a 'hello world' example to familiarize you with ROS. If anything seems unclear, feel free to ask question!
1 x Arduino DUE, you could also use a UNO or a MEGA
1 x Proto-board that fits Arduino DUE pin-out available here
2 x 12V DC motors with encoders (100 RPM option)
1 x L298N motor driver
1 x Battery (3S/4S LiPo battery for example)
2 x ON/OFF switches
2 x LED
2 x 470kOhm Resistors
3 x 4 pins JST connectors
1 x USB cable (at least one between the SBC and the Arduino)
1 x Current sensor (optional)
1 x 9 Degrees of Freedom IMU (optional)
1 x LIDAR (optional)
2 x Wheels 65mm diameter (6mm width option)
4 x Nylon spacers 30mm (optional)
20 x M3 inserts (optional)
M2.5 and M3 screws and inserts
3D printer or someone who can print the parts for you
A hand drill with a set a drill bits like this one
Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.
Step 1: Description
This robot is a simple differential drive that uses 2 wheels directly mounted on their motor and a roller caster which is placed in the rear to prevent the robot from falling over. The robot is divided into two layers:
- the Bottom Layer: with the propulsion group (battery, motor controller and motors), and the 'low level' electronics: Arduino microcontroller, voltage regulator, switches...
- the Upper Layer: with the 'high level' electronic namely the Single Board Computer and the LIDAR
Those layers are linked with printed parts and screws to ensure the robustness of the structure.
The schematic might appear a bit messy. It's a schematic drawing and it doesn't represent all wires, connectors and the proto-board but it can be read as follow:
A 3S Litihum Ion Polymer battery with 3000mAh capacity powers the first circuit, it powers both the motor controller board (L298N) and a first 5V regulator for motor encoders and Arduino. This circuit is enabled through a switch with a LED that indicates its ON/OFF state.
The same battery powers a second circuit, the input voltage is converted to 5V to power the Single Board Computer. Here also, the circuit is enabled through a switch and a LED.
Additional sensors like a LIDAR or a camera can then be added directly on the Raspberry Pi through USB or the CSI port.
The robot frame is composed of 16 identical parts that formed 2 squared layers (28cm width). The many holes allow to mount additional parts wherever you need it and offer a complete modular design. For this project, I decided to get the originals TurtleBot3 plates but you can also 3D printed them as their design is open source.
Step 2: Motor Block Assembly
The first step is to add 1mm thick foam tape around each motor to prevent vibrations and noise when motor will spinning.
The motor holder results in two parts that grip the motor like a vice. 4 screws achieved to tight the motor in the holder.
Each holder is composed of several holes that host M3 inserts to be mounted on the structure. There are more holes than actually needed, the extra holes could eventually be used to mount extra part.
3D printer settings : all parts are printed with the following parameters
- 0.4mm diameter nozzle
- 15% material infill
- 0.2 mm height layer
Wheels chosen are covered with rubber to maximize adhesion and ensure slip free rolling condition. A clamping screw maintains the wheel mounted on the motor shaft. The diameter of the wheel should be large enough to cross minor step and ground irregularity (those wheels are 65mm diameter).
When you have done with one motor block, repeat the previous operations and then simply fix them into the layer with M3 screws.
Step 3: Switches and Cable Preparation
Motor cable preparation
Generally the motor-encoder comes with a cable including on one side a 6pin connector that connects the back of the encoder PCB, and naked wires on the other side .
You have the possibility to directly solder them on your proto-board or even your Arduino, but I recommend you to use female pin headers and JST-XH connectors instead. Thus you can plug/unplugged them on your proto-board and make your assembly easier.
Tips : you can add expandable sleeving braid around your wires and pieces of shrink tube near connectors, doing so you will get a 'clean' cable.
Switch and LED
To enable the two power circuits, prepare 2 LED and switches cables: at first solder a 470kOhm resistor on one of the LED pin, then solder the LED on one the switch pin. Here also, you can use a piece of shrink tube to hide the resistor inside. Be careful to solder the LED in the right direction! Repeat this operation to get two switch/led cables.
Assemble the previously made cables on the corresponding 3D printed part. Use a nut to maintain the switch, the LEDs don't require glue, just force enough to fit it in the hole.
Step 4: Electronic Boards Wiring
A proto-board fitting the Arduino board layout is used to reduce the number of wires. On the top of the proto-board, the L298N is stacked with Dupont female header (Dupont are 'Arduino like' headers).
Originally, L298N board doesn't come with corresponding male Dupont header, you need to add a 9 pins row below the board. You need to realize 9 holes with 1mm diameter drill bit in parallel of the existing holes as you can see on the picture. Then link the corresponding pins of the 2 rows with soldering materials and short wires.
The L298N is composed of 2 channels allowing speed and direction control:
- direction through 2 digital outputs, called IN1, IN2 for the first channel, and IN3 and IN4 for the second
- speed through 1 digital outputs, called ENA for the first channel and ENB for the second
I chose the following pin-out with the Arduino:
- left motor: IN1 on pin 3, IN2 on pin 4, ENA on pin 2
- right motor: IN3 on pin 5, IN4 on pin 6, ENB on pin 7
Even if the l298N is normally able to provide 5V, I still add a small regulator. It powers the Arduino through VIN port and the 2 encoders on the motors. You could skip this step by directly using the built-in L298N 5V regulator.
JST connectors and Encoder pin-out
Use 4 pins female JST-XH connector adapters, each connector is then linked to:
- 5V from regulator
- a Ground
- two digital input ports (for exemple: 34 and 38 for the right encoder and 26 and 30 for the left one)
As you may have noticed, there is an extra 4pin JST connector on the proto-board. It is used for connecting I2C device like an IMU, you can do the same and even add your own port.
Step 5: Motor Group and Arduino on the Bottom Layer
Motor blocks fixation
Once the bottom layer is assembled with the 8 Turtlebot's plates, simply use 4 M3 screws directly in the inserts to maintain motor blocks. Then you can plug motor power wires to the L298N outputs and the previously made cables to the proto-board JST connectors.
Power distribution is simply realized with a barrier terminal block. On one side of the barrier, a cable with a XT60 female plug is screwed to connect to LiPo battery. On the other side, our two LED/switch cables previously soldered are screwed. Thus each circuit (Motor and Arduino) could be enabled with its own switch and the corresponding green LED.
Quickly you will have to deal with a lot of cables! To reduce the messy aspect, you can use the 'table' previously 3D printed. On the table, maintain your electronic boards with double sided tape, and under the table let the wires freely flow.
To avoid the ejection of the battery when driving your robot, you can simply use a hair elastic band.
Not really a roller caster but a simple half sphere fixed with 4 screws on the bottom layer. It is enough to ensure stability of the robot.
Step 6: Single Board Computer and Sensors on the Upper Layer
Which Single Board Computer to choose?
I don't need to present you the famous Raspberry Pi, its number of use cases largely exceeds the robotics field. But there is a much more powerful challenger for the Raspberry Pi that you might ignore. Indeed the Jetson Nano from Nvidia embeds a powerful 128-core graphical card in addition to its processor. This particular graphical card has been develop to accelerate computational expensive tasks such as image processing or neural network inference.
For this project I chose the Jetson Nano and you can find the corresponding 3D part among the attached files, but if you want to go with the Raspberry Pi there are many printable cases here.
Whatever board you decided to bring on your robot, you need a 5V regulator. The latest Raspberry Pi 4 requires 1.25A max but Jetson Nano requires up to 3A on stress so I opted for the Pololu 5V 6A to have a power reserve for future components (sensors, lights, steppers...), but any cheap 5V 2A should do the job. The Jetson use a 5.5mm DC barrel and the Pi a micro USB, grab the corresponding cable and solder it to the regulator output.
The LIDAR used here is the LDS-01, there are various others 2D LIDAR that could be used like RPLidar A1/A2/A3, YDLidar X4/G4 or even Hokuyo LIDARs. The only requirement is that it needs to be plugged through USB and be placed centered above the structure. Indeed if the LIDAR is not well centered, the map created by the SLAM algorithm may shift the estimated position of walls and obstacles from their real position. Also if any obstacles from the robot cross the laser beam, it is going to reduce range and field of view.
The LIDAR is mounted on a 3D printed part that follow its shape, the part itself is hold on a rectangular plate (actually in plywood on the picture but could be 3D printed as well). Then an adapter part allows the ensemble to be fixed on the upper turtlebot plate with nylon spacers.
Camera as additional sensor or LIDAR replacement
If you don't want to spend too much money into a LIDAR (which cost around 100$), go for a camera: there also exist SLAM algorithms that run only with a monocular RGB camera. Both SBC accept USB or CSI camera.
Moreover the camera will let you run computer vision and object detection scripts!
Before closing the robot, pass cables through the bigger holes in the upper plate:
- the corresponding cable from the 5V regulator to your SBC
- the USB cable from the Programming Port of the Arduino DUE (the closest to the DC barrel) to a USB port of your SBC
Then hold the upper plate in position with a dozen of screws. Your robot is now ready to be programmed, WELL DONE!
Step 7: Make It Move!
Compile the Arduino
Open your favorite Arduino IDE, and import the project folder called own_turtlebot_core, then select your board and the corresponding port, you can refer to this excellent tutorial.
Adjust the Core settings
The project is composed of two files, and one needs to be adapted to your robot. So let's open own_turtlebot_config.h, and discover which lines require our attention:
#define ARDUINO_DUE // ** COMMENT THIS LINE IF YOUR NOT USING A DUE **
Should be used only with Arduino DUE, if not comment the line.
#define RATE_CONTROLLER_KP 130.0 // ** TUNE THIS VALUE ** #define RATE_CONTROLLER_KD 5000000000000.0 // ** TUNE THIS VALUE ** #define RATE_CONTROLLER_KI 0.00005 // ** TUNE THIS VALUE **
Those 3 parameters correspond to the rate controller gains used by the PID to maintain the desired speed. Depending on the battery voltage, the mass of the robot, the wheel diameter and mechanical gear of your motor, you will need to adapt their values. PID is a classic controller and you will be not detailed here but this link should give you enough inputs to tune your own.
/* Define pins */ // motor A (right) const byte motorRightEncoderPinA = 38; // ** MODIFY WITH YOUR PIN NB ** const byte motorRightEncoderPinB = 34; // ** MODIFY WITH YOUR PIN NB ** const byte enMotorRight = 2; // ** MODIFY WITH YOUR PIN NB ** const byte in1MotorRight = 4; // ** MODIFY WITH YOUR PIN NB ** const byte in2MotorRight = 3; // ** MODIFY WITH YOUR PIN NB ** // motor B (left) const byte motorLeftEncoderPinA = 26; // ** MODIFY WITH YOUR PIN NB ** const byte motorLeftEncoderPinB = 30; // ** MODIFY WITH YOUR PIN NB ** const byte enMotorLeft = 7; // ** MODIFY WITH YOUR PIN NB ** const byte in1MotorLeft = 6; // ** MODIFY WITH YOUR PIN NB ** const byte in2MotorLeft = 5; // ** MODIFY WITH YOUR PIN NB **
This block defines the pinout between the L298N and the Arduino, simply modify the pin number to match yours. When you have done with the config file, compile and upload the code!
Install and configure ROS
Once you have reach this step, the instructions are exactly the same as the ones detailed on the excellent TurtleBot3's manual , you need to scrupulously follow
well done TurtleBot 3 is now yours and you can run all the existing packages and tutorials with ROS.
Ok but what is ROS?
ROS stands for Robots Operating System, it might seems quite complex at first but it's not, just imagine a way of communication between hardware (sensors and actuators) and software (algorithms for navigation, control, computer vision...). For example, you can easily swap your current LIDAR with an other model without break your setup, because each LIDAR publish the same LaserScan message. ROS is widely used is robotics,
Run your first example
The 'hello world' equivalent for ROS consist in teleoperate your robot through the remote computer. What you want to do is to send velocity commands to make the motors spin, the commands follow this pipe:
- a turtlebot_teleop node, running on the remote computer, publish a "/cmd_vel" topic including a Twist message
- this message is forwarded through the ROS messages network to the SBC
- a serial node allows the "/cmd_vel" to be received on the Arduino
- the Arduino reads the message and set the angular rate on each motor to match the desired linear and angular velocity of the robot
This operation is simple and can be achieved by running the command lines listed above! If you want more detailed information just watch the video.
rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=115200
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
To go further
You need to know a last thing before trying all the official examples, in the manual each time you face this command:
roslaunch turtlebot3_bringup turtlebot3_robot.launch
you need to run this command on your SBC instead:
rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=115200
And if you have a LIDAR run the associated command on your SBC, in my case I run a LDS01 with the line below:
roslaunch hls_lfcd_lds_driver hlds_laser.launch
And that's all, you have definitively built your own turtlebot :) You are ready to discover the fantastic capabilities of ROS, and to code vision and machine learning algorithms.
This is an entry in the