The main aim of this project is to build an autonomous mobile robot which is named as Chefbot. The chefbot can able to supply food and drinks to the people in a hotel, like a supplier.
Chefbot is a differential drive robot having encoder motor, IMU , 3D vision sensor and on board PC to process all the sensor. The PC is loaded with Ubuntu 14.04 and Robot Operating System(R.O.S)(http://www.ros.org).
Using ROS framework, we can process the sensors values and can send command velocity to the motors. ROS is having standard implementation of navigation algorithm(navigation stack), mapping algorithm(SLAM) and localization algorithm(AMCL)
Using these algorithms, we can build the map of the hotel and navigate inside the hotel autonomously. The project was done as a part of a book called "Learning Robotics using Python" published by PACKT.(http://learn-robotics.com)
Details
Here is the book promo video which describe the Chefbot Project and the each chapters in the book
As the title says, we are going to see how to build an autonomous mobile robot called Chefbot which is for serving food and beverages in hotels and restaurants.
This was a hobby project and i built this robot after seeing a robot calledTurtlebot2. The main aim of the project was to build an open source autonomous mobile robot research platform and doing some application using it. Serving food was one of the application of the robot and i have named the robot as Chefbot.
Note : The robot is not using Roomba as the base platform which is used in Turtlebot2; instead of Roomba, i have built the entire mechanism from scratch.
The header images shows the book cover page and the Chefbot prototype.
This tutorials is a quick start guide for developing this robot, for detailed designing and development, you should refer the book itself.
You should have basic knowledge in Python and ROS for starting with this tutorials.
In this tutorials series, you can see an abstract of each chapters of this book. Following are main steps that we are going to discuss
Mechanical Design of Chefbot
Working with Robot Simulation using ROS and Gazebo
Designing Chefbot Hardware
Interfacing Robotics Actuators and Wheel Encoders
Working with Chefbot Sensors
Programming Vision sensors using R.O.S and Python
Working with Speech Recognition and Synthesis
Applying Artificial Intelligence to Chefbot using Python
Integrating of Chefbot Hardware and Interfacing to ROS using Python
Designing a GUI for Chefbot using Qt and Python
Calibrating and Testing of Chefbot
2
Step 2
Step 1: Mechanical Design of Chefbot
In this step, we can see an abstract of the Chefbot design process mentioned in the book.
The robot design starts from a set of requirements.
Following conditions have to be met by the robot design.
Here are the requirements
The robot should have a provision to carry food and drinks.
The robot should be able to carry a maximum payload of 5 kg.
The robot should travel at a speed between 0.25 m/s and 1 m/s
The ground clearance of the robot should be greater than 3 cm
The robot must be able to work for 2 hours continuously
The robot should be able to move and supply food to any table by avoiding obstacles
The robot height should be between 40 cm and 1 meter
The robot should be of low cost
After analyzing and designing from the requirement we are coming to the conclusion that, following parameters should be on the robot.
Motor Specification
Robot drive : Differential wheeled drive
Required Motor Speed : 80 RPM
Wheel diameter : 9 cm
Motor Torque : 20 Kg-cm
So we should design a drive system of robot and buy motors that is matching with these specs.
Next step is to design the robot chassis.
Robot Chassis Design
We are taking the 3-platform layered architecture in this robot which is similar to Turtlebot 2.
I have used following free software tools for sketching and viewing the 2D and 3D design of the robot
LibreCAD: LibreCAD is a fully comprehensive 2D CAD application that you can download and install for free.
Blender: Blender is the free and open source 3D modeling tool.
Meshlab : MeshLab is an open source, portable, and extensible system for the processing and editing of unstructured 3D triangular meshes.
In Ubuntu you can install these tool using following command
Installing LibreCAD
$ sudo apt-get install librecad
Installing Blender
$ sudo apt-get install blender
Installing Meshlab
$ sudo apt-get install meshlab
You can see the 2D design of robot, base plate, middle plate and top plate of the robot modeled using LibreCAD.
The dimensions of plates and dimensions of each holes are given below
Dimensions
Here are the dimensions of each plate
Base plate:
M1 and M2(motors): 5x4 cm
C1 and C2(caster wheels) Radius : 1.5 cm
S(Screw) radius : 0.15 cm
P1-1,P1-2,P1-3,P1-4 : Outer radius = 0.7 cm, Height = 3.5 cm
Left and Right Wheel sections : 2.5 x 10 cm
Base plate Radius: 15 cm
The middle and top plate have the same dimensions of base plate with same screw size and other dimensions. You can view these plates from the image gallery.
Each plates are connected using hollow tubes with screws. You can see its dimensions from the images.
The 3D modeling is done using Python script inside Blender. You can see screenshot of Blender with robot model from the images.
The Python script and Blender 3D model file is attached along with this step.
We can export the robot model to STL it can viewed in 3D mesh viewing tool called Meshlab which is included in the images.
The python script to generate robot model in Blender is given below
import bpy
#This function will draw base plate
def Draw_Base_Plate():
#Added two cubes for cutting sides of base plate
bpy.ops.mesh.primitive_cube_add(radius=0.05, location=(0.175,0,0.09))
bpy.ops.mesh.primitive_cube_add(radius=0.05, location=(-0.175,0,0.09))
################################################
#Adding base plate
bpy.ops.mesh.primitive_cylinder_add(radius=0.15,depth=0.005, location=(0,0,0.09))
#Adding booleab difference modifier from first cube
bpy.ops.object.modifier_add(type='BOOLEAN')
bpy.context.object.modifiers["Boolean"].operation = 'DIFFERENCE'
bpy.context.object.modifiers["Boolean"].object = bpy.data.objects["Cube"]
bpy.ops.object.modifier_apply(modifier="Boolean")
################################################
#Adding booleab difference modifier from second cube
bpy.ops.object.modifier_add(type='BOOLEAN')
bpy.context.object.modifiers["Boolean"].operation = 'DIFFERENCE'
bpy.context.object.modifiers["Boolean"].object = bpy.data.objects["Cube.001"]
bpy.ops.object.modifier_apply(modifier="Boolean")
################################################
#Deselect cylinder and delete cubes
bpy.ops.object.select_pattern(pattern="Cube")
bpy.ops.object.select_pattern(pattern="Cube.001")
bpy.data.objects['Cylinder'].select = False
bpy.ops.object.delete(use_global=False)
#This function will draw motors and wheels
def Draw_Motors_Wheels():
#Create first Wheel
bpy.ops.mesh.primitive_cylinder_add(radius=0.045,depth=0.01, location=(0,0,0.07))
#Rotate
bpy.context.object.rotation_euler[1] = 1.5708
#Transalation
bpy.context.object.location[0] = 0.135
#Create second wheel
bpy.ops.mesh.primitive_cylinder_add(radius=0.045,depth=0.01, location=(0,0,0.07))
#Rotate
bpy.context.object.rotation_euler[1] = 1.5708
#Transalation
bpy.context.object.location[0] = -0.135
#Adding motors
bpy.ops.mesh.primitive_cylinder_add(radius=0.018,depth=0.06, location=(0.075,0,0.075))
bpy.context.object.rotation_euler[1] = 1.5708
bpy.ops.mesh.primitive_cylinder_add(radius=0.018,depth=0.06, location=(-0.075,0,0.075))
bpy.context.object.rotation_euler[1] = 1.5708
#Adding motor shaft
bpy.ops.mesh.primitive_cylinder_add(radius=0.006,depth=0.04, location=(0.12,0,0.075))
bpy.context.object.rotation_euler[1] = 1.5708
bpy.ops.mesh.primitive_cylinder_add(radius=0.006,depth=0.04, location=(-0.12,0,0.075))
bpy.context.object.rotation_euler[1] = 1.5708
################################################
#Addubg Caster Wheel
bpy.ops.mesh.primitive_cylinder_add(radius=0.015,depth=0.05, location=(0,0.125,0.065))
bpy.ops.mesh.primitive_cylinder_add(radius=0.015,depth=0.05, location=(0,-0.125,0.065))
#Adding Kinect
bpy.ops.mesh.primitive_cube_add(radius=0.04, location=(0,0,0.26))
#Draw middle plate
def Draw_Middle_Plate():
bpy.ops.mesh.primitive_cylinder_add(radius=0.15,depth=0.005, location=(0,0,0.22))
#Adding top plate
def Draw_Top_Plate():
bpy.ops.mesh.primitive_cylinder_add(radius=0.15,depth=0.005, location=(0,0,0.37))
#Adding support tubes
def Draw_Support_Tubes():
####################################################
#Cylinders
bpy.ops.mesh.primitive_cylinder_add(radius=0.007,depth=0.30, location=(0.09,0.09,0.23))
bpy.ops.mesh.primitive_cylinder_add(radius=0.007,depth=0.30, location=(-0.09,0.09,0.23))
bpy.ops.mesh.primitive_cylinder_add(radius=0.007,depth=0.30, location=(-0.09,-0.09,0.23))
bpy.ops.mesh.primitive_cylinder_add(radius=0.007,depth=0.30, location=(0.09,-0.09,0.23))
#Exporting into STL
def Save_to_STL():
bpy.ops.object.select_all(action='SELECT')
# bpy.ops.mesh.select_all(action='TOGGLE')
bpy.ops.export_mesh.stl(check_existing=True, filepath="/home/lentin/Desktop/exported.stl", filter_glob="*.stl", ascii=False, use_mesh_modifiers=True, axis_forward='Y', axis_up='Z', global_scale=1.0)
#Main code
if __name__ == "__main__":
Draw_Base_Plate()
Draw_Motors_Wheels()
Draw_Middle_Plate()
Draw_Top_Plate()
Draw_Support_Tubes()
Save_to_STL()
3
Step 3
Step 2: Working with Robot Simulation using R.O.S and Gazebo
After designing the robot 3D model, the next step is to simulate the robot. I have describe complete simulation of this robot from scratch in the book. The simulation is done using R.O.S and Gazebo.
Here is the quick start to do the robot simulation.
This will open Gazebo simulator with a hotel like environment which is shown in the second image.
Now we are trying to implement autonomous navigation in simulation. First we have to perform SLAM for building map of the environment and after building the map, we have to run AMCL nodes for localizing the robot on the map.
After localization, we can command robot to go into a particular table position for delivering the food and will return to the home position after delivering food.
Performing SLAM using Chefbot
We can see how to perform SLAM and AMCL using the simulated environment.
Start the SLAM algorithm using the following command
$ roslaunch chefbot_gazebo gmapping_demo.launch
Start visualizing the map in Rviz using the following command
Now we can see the robot is localized on the map which is having the same position of Gazebo.
We can command the robot to go to a particular position inside map using Rviz2D Nav Goal Button.
Using 2D Nav goal button we can give a goal pose to the robot and then you can see the robot will plan a path to that position and move to that path by avoiding obstacles autonomously.
We have performed the simulation of complete robot, now it's the time for designing the hardware prototype of the simulated robot.