Foreword
Connect blog post: ROS robot programming practice (12.1) - with turtlebot inspection robot simulation
Transmission line design
Design gazebo with custom picture floor
First, we need to design a gazebo floor, here to thank the older generation's answer: Reference Answers
The first step: in the home directory ctrl + h Show hidden files
Step Two: Create the following folder file folder .gazebo
mkdir ~/.gazebo/models/my_ground_plane
mkdir -p ~/.gazebo/models/my_ground_plane/materials/textures
mkdir -p ~/.gazebo/models/my_ground_plane/materials/scripts
Step 3: Create material file
cd ~/.gazebo/models/my_ground_plane/materials/scripts
vi my_ground_plane.material
my_ground_plane.material file as follows:
material MyGroundPlane/Image
{
receive_shadows on
technique
{
pass
{
ambient 0.5 0.5 0.5 1.0
texture_unit
{
texture MyImage.png
}
}
}
}
Step 4: textures Xiacun we want to use the floor picture MyImage.png
As shown, put it ~ / .gazebo / models / my_ground_plane / materials / textures following
can use the command:
cp 你的图片路径/MyImage.png ~/.gazebo/models/my_ground_plane/materials/textures/
Step Five: In my_ground_plane folder, create a file model.sdf
cd ~/.gazebo/models/my_ground_plane
vi model.sdf
model.sdf as follows:
<?xml version="1.0" encoding="UTF-8"?>
<sdf version="1.4">
<model name="my_ground_plane">
<static>true</static>
<link name="link">
<collision name="collision">
<geometry>
<plane>
<normal>0 0 1</normal>
<size>15 15</size>
</plane>
</geometry>
<surface>
<friction>
<ode>
<mu>100</mu>
<mu2>50</mu2>
</ode>
</friction>
</surface>
</collision>
<visual name="visual">
<cast_shadows>false</cast_shadows>
<geometry>
<plane>
<normal>0 0 1</normal>
<size>15 15</size>
</plane>
</geometry>
<material>
<script>
<uri>model://my_ground_plane/materials/scripts</uri>
<uri>model://my_ground_plane/materials/textures/</uri>
<name>MyGroundPlane/Image</name>
</script>
</material>
</visual>
</link>
</model>
</sdf>
Step Six: In my_ground_plane folder, create a file model.config, reads as follows:
<?xml version="1.0" encoding="UTF-8"?>
<model>
<name>My Ground Plane</name>
<version>1.0</version>
<sdf version="1.4">model.sdf</sdf>
<description>My textured ground plane.</description>
</model>
Import your own floor model in the gazebo in
Open gazebo:
roslaunch turtlebot_gazebo turtlebot_world.launch
In the following a further command to open the input terminal rviz:
roslaunch turtlebot_rviz_launchers view_robot.launch --screen
Click on the top left corner of the insert inserted into the gazebo model just built:
Select My Ground Plane:
Left-click and move the mouse to drag into it:
Right-models list deleted except to build their own robots and other furniture floor:
with gazebo mobile tools, line into the robot:
a gazebo rotary tool of the robot camera at the yellow line:
rotation blue piece, so that the robot around the z axis, and the alignment:
Write scripts to control the robot patrol line
Create a workspace ros
mkdir -p ~/turtlebot_ws/src
cd ~/turtlebot_ws
catkin_init_workspace
cd src
catkin_create_pkg turtlebot1 rospy geometry_msgs sensor_msgs
cd ..
catkin_make
source ./devel/setup.bash
Write the script filter yellow line
Hsv used here to extract the yellow line
to Baidu search yellow hsv maximum and minimum:
written filtering script follower_color_filter.py in src turtlebot1 package
cd src/turtlebot1/src
vi follower_color_filter.py
rosrun turtlebot1 follower_color_filter.py
follower_color_filter.py as follows:
#!/usr/bin/env python
# BEGIN ALL
import rospy, cv2, cv_bridge, numpy
from sensor_msgs.msg import Image
class Follower:
def __init__(self):
self.bridge = cv_bridge.CvBridge()
cv2.namedWindow("window", 1)
self.image_sub = rospy.Subscriber('camera/rgb/image_raw',
Image, self.image_callback)
def image_callback(self, msg):
# BEGIN BRIDGE
image = self.bridge.imgmsg_to_cv2(msg)
cv2.imshow("ori", image )
# END BRIDGE
# BEGIN HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", hsv )
# END HSV
# BEGIN FILTER
lower_yellow = numpy.array([ 26, 43, 46])
upper_yellow = numpy.array([34, 255, 255])
mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
# END FILTER
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("window2", mask )
cv2.waitKey(3)
rospy.init_node('follower')
follower = Follower()
rospy.spin()
# END ALL
Operating results:
you can see very nice !!!
Write transmission line Scripting
vi follower_line.py
rosrun turtlebot1 follower_line.py
#!/usr/bin/env python
# BEGIN ALL
import rospy, cv2, cv_bridge, numpy
from sensor_msgs.msg import Image
from geometry_msgs.msg import Twist
class Follower:
def __init__(self):
self.bridge = cv_bridge.CvBridge()
cv2.namedWindow("window", 1)
self.image_sub = rospy.Subscriber('camera/rgb/image_raw',
Image, self.image_callback)
self.cmd_vel_pub = rospy.Publisher('cmd_vel_mux/input/teleop',
Twist, queue_size=1)
self.twist = Twist()
def image_callback(self, msg):
image = self.bridge.imgmsg_to_cv2(msg,desired_encoding='bgr8')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower_yellow = numpy.array([ 26, 43, 46])
upper_yellow = numpy.array([34, 255, 255])
mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
h, w, d = image.shape
search_top = 3*h/4
search_bot = 3*h/4 + 20
mask[0:search_top, 0:w] = 0
mask[search_bot:h, 0:w] = 0
M = cv2.moments(mask)
if M['m00'] > 0:
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
cv2.circle(image, (cx, cy), 20, (0,0,255), -1)
# BEGIN CONTROL
err = cx - w/2
self.twist.linear.x = 0.2
self.twist.angular.z = -float(err) / 100
self.cmd_vel_pub.publish(self.twist)
# END CONTROL
cv2.imshow("window", image)
cv2.waitKey(3)
rospy.init_node('follower')
follower = Follower()
rospy.spin()
# END ALL
Run the script:
to sum up
Really fun it can be simulated under the patrol line algorithm ha ha ha ha, did the smart small car partner should not be unfamiliar Oh ~
Enjoy ~ IT