Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dimitriskatos/my_robot

Two wheel robot with camera, lidar and differential drive.
https://github.com/dimitriskatos/my_robot

differential-drive-robot gazebo-plugins gazebo-simulator navigation-algorithms ros2 ros2-humble rviz2

Last synced: 3 days ago
JSON representation

Two wheel robot with camera, lidar and differential drive.

Awesome Lists containing this project

README

        

# Differential drive controller robot with two sensors.
In this tutorial we will build a differential drive controller robot using xacro properties. We will add two sensors, a camera, lidar and finally we control the robot model by adding differential drive plugin.

Totally, you will learn the following:
- how to add lidar to robot and adding a new mesh file.
- how to add a camera to robot.
- how to add differential drive control to the robot.
- Create a simple algorithm for obsackle avoidance.

You can find a presentation that will guide you through this tutorial. In the presentation, you can find information on how to build this robot.
- [Create a differential drive controller robot](https://docs.google.com/presentation/d/1JCBwxNok0eC-tr-dRsIzfJUy-XPxEjk6/edit?usp=drive_web&ouid=106628092038381749227&rtpof=true) Greek language.
- Create a differential drive controller robot. English language (comming soon).

You can find a project in the following link:
- [Project]() Greek language.
- [Project]() English language( Coming soon).

## Create, build and setup a new package.
Create a new ROS 2 package for the differential drive control robot
```
cd ~/ros2_ws/src
ros2 pkg create --build-type ament-python my_robot
```

Create some folders to the package for better organization.
```
cd ~/ros2_ws/src
mkdir launch urdf meshes worlds
```

After creating the package and the folders, you need to modify the setup.py file of the package.
Add the following modules.
```py
from glob import glob
import os
```
In the data_files list of the script add the following.
```py
        (os.path.join('share',package_name,'launch'),
         glob(os.path.join('launch','*.launch.py'))),
        (os.path.join('share',package_name,'urdf'),
         glob(os.path.join('urdf','*.xacro'))),
         (os.path.join('share',package_name,'urdf'),
         glob(os.path.join('urdf','*.gazebo'))),
        (os.path.join('share',package_name,'worlds'),
         glob(os.path.join('worlds','*.world'))),
        (os.path.join('share',package_name,'meshes'),
         glob(os.path.join('meshes','*.dae'))),
```

The next step is building the package using the colcon tool.
```
cd ~/ros2_ws/
colcon build --packages-select my_robot
```

## Two wheel robot with camera, lidar and differential drive controller.
First of all we need to create the robot model. We will create two files which is the following
- Create [myrobot.xacro](https://github.com/DimitrisKatos/my_robot/blob/master/urdf/myrobot.xacro) in the urdf folder of the package. This file is the two-wheeled robot.
- Create [robot.gazebo](https://github.com/DimitrisKatos/my_robot/blob/master/urdf/robot.gazebo) in the urdf folder of the package. In this file we define all the Gazebo plugins. So far, we define colors for every link and attrition.

Now the robot is ready. Let's move to some more interest staff.

---
## Add a camera to robotmodel.
Now we will add a camera to robot model. For this reason we need to add a new link and joint to the robot model. Furthermore you need to add a new Gazebo plugin to the robot.gazebo file.
- In the [myrobot.xacro](https://github.com/DimitrisKatos/my_robot/blob/master/urdf/myrobot.xacro) file we add a box link in front of the robot model.
- In the robot.gazebo file we add the following xml code to enable the camera in the gazebo simulator.
```xml



30.0

1.3962634

800
800
R8G8B8


0.02
300



true
0.0
my_robot/camera1
image_raw
camera_info
camera_link
0.07
0.0
0.0
0.0
0.0
0.0



```

Now we can use the Gazebo Classic Simulator to see if the camera works properly. Also we will visualize the results from the camera to RVIZ. Now let's visualize the robot to Gazebo. Run the next commands.
```
cd ~/ros2_ws
colcon build --package-select my_robot
cd src/my_robot # For WSL run the next command
export LIBGL_ALWAYS_SOFTWARE=1 LIBGL_ALWAYS_INDIRECT=0
ros2 launch my_robot my_robot_gazebo.launch.py
```

![Poll Mockup](./images/image3.png)

After the robot spawn in gazebo we add to obstacles. Now let's visualize the data from the hokuyo laser to RVIZ 2. In a new terminal begin Rviz and you need to make some changes:
- Add RobotModel and change the topic to /robot_descriptiion.
- Add Camera from displays panel and change the topic.
- Finally, change the Fixed Frame to base_link from the displays panel.

In the left bottom you can see what the camera's robot are watching.

![Poll Mockup](./images/image4.png)

## Add lidar to robot model.

First of all, you need to add an new link and joint to robot model. The new link defines the lidar to your robot. Furthermore this link reads a mesh file and visualize a real lidar. In the meshes folder you need to save the [hokuyo.dae file](https://github.com/DimitrisKatos/my_robot/blob/master/meshes/hokuyo.dae).
In the robot model add the following.
```xml
 
   
   
   
   
 
 
 
 
   
     
     
   
     
   
   
     
     
           
     
   
   
     
     
     
   
 
```

Also add a new gazebo plugin to robot.gazebo file. The XML code will enable lidar to the Gazebo simulator.
```xml



0 0 0 0 0 0
true
20



360
-1.57
1.57



0.2
12




~/out:=scan

sensor_msgs/LaserScan
hokuyo



```
Now let's visualize the robot to Gazebo. Run the next commands.
```
cd ~/ros2_ws
colcon build --package-select my_robot
cd src/my_robot # For WSL run the next command
export LIBGL_ALWAYS_SOFTWARE=1 LIBGL_ALWAYS_INDIRECT=0
ros2 launch my_robot my_robot_gazebo.launch.py
```
![Poll Mockup](./images/image.png)

Now let's visualize the data from the hokuyo laser to RVIZ 2. In a new terminal begin Rviz and you need to make some changes:
- Add RobotModel and change the topic to /robot_descriptiion.
- Add /laser_scan from displays panel and change the topic.
- Finally, change the Fixed Frame to base_link from the displays panel.

You will see that the obstacles have been detected by hokuyo lidar.
![Poll Mockup](./images/image2.png)

## Differential drive controller and obstacle avoidance algorithm.

For differential drive control we need to add an extra Gazebo plugin to robot.gazebo file. The XML code you need to add is the following:
```xml




left_wheel_hinge
right_wheel_hinge
0.4
0.1


200
10.0


odom
chassis
true
true
true


```

Now the differential drive is enable and we can send messages to the /cmd_vel topic.
```
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist '{linear:{x: 0.4}, angular:{z: 0.2}}'
```

The following Python Script is a simple Publisher and Subscriber for ROS 2. We subcribe data from the lidar and we publish to /cmd_vel topic. Create a new file name [diff_drive.py](https://github.com/DimitrisKatos/my_robot/blob/master/my_robot/diff_drive.py) to my_robot folder.
```py
import rclpy
from rclpy.node import Node

from geometry_msgs.msg import Twist
from sensor_msgs.msg import LaserScan

class diff_drive(Node):

def __init__(self):
super().__init__('obstacle_avoider')
# Create the publisher, define the type of message, the topic
# and the frame rate.
self.__publisher = self.create_publisher(Twist,'cmd_vel',1)

# Create the subscriber, define the type of message,
# the topic and the frame rate
self.subscription = self.create_subscription(
LaserScan,
'/scan',
self.listener_callback,
10)

# Create a method for the class.
def listener_callback(self,msg):
# Create a variable and Define the position of the scanner,
# which will subcribe the distance.
self.msg = min(msg.ranges[165:179]+msg.ranges[180:195])
# Print the measurment distance.
print(f"The measurment distance is {msg}.")

# Create a variable, and give him the type of Twist()
command_msg = Twist()

# Define the speed of the robot to 0.2 m/s in x axis
command_msg.linear.x = 0.2

if self.msg < 0.5:
# Define the speed of the robot, if the obstacle is in front.
command_msg.angular.z = 2.0
command_msg.linear.x = 0.0

# Publish the speed.
self.__publisher.publish(command_msg)

def main(args=None):
rclpy.init(args=args)
# Create an instance
avoider = diff_drive()
# run the instance
rclpy.spin(avoider)

# End the programm with Cntr+C
avoider.destroy_node()
rclpy.shutdown()

# Call the main function
if __name__=='__main__':
main()
```

In the setup.py file inform the entry_points dictionary to the following.
```py
entry_points={
'console_scripts': [
'diff_drive = my_robot_description.diff_drive:main'
],
},
```

Put your robot to a building and run the next commands.
```
cd ~/ros2_ws
colcon build --packages-select my_robot
ros2 run my_robot diff_drive
```
You will see your robot moving forward. When he detects an obstacle he tries to turn.