Chapter 9: Computer Vision for Robotics
Activity 9: A Robotic Security Guard
Solution
Create a new package in your catkin workspace to contain the integration node. Do it with this command to include the correct dependencies:
cd ~/catkin_ws/ source devel/setup.bash roscore cd src catkin_create_pkg activity1 rospy cv_bridge geometry_msgs image_transport sensor_msgs std_msgs
Switch to the package folder and create a new scripts directory. Then, create the Python file and make it executable:
cd activity1 mkdir scripts cd scripts touch activity.py touch activity_sub.py chmod +x activity.py chmod +x activity_sub.py
This is the implementation of the first node:
Libraries importation:
#!/usr/bin/env python import rospy import cv2 import sys import os from cv_bridge import CvBridge, CvBridgeError from sensor_msgs.msg import Image from std_msgs.msg import String sys.path.append(os.path.join(os.getcwd(), '/home/alvaro/Escritorio/tfg/darknet/python/')) import darknet as dn
Note
The above mentioned path may change as per the directories placed in your computer.
Class definition:
class Activity(): def __init__(self):
Node, subscriber, and network initialization:
rospy.init_node('Activity', anonymous=True) self.bridge = CvBridge() self.image_sub = rospy.Subscriber("camera/rgb/image_raw", Image, self.imageCallback) self.pub = rospy.Publisher('yolo_topic', String, queue_size=10) self.imageToProcess = None cfgPath = "/home/alvaro/Escritorio/tfg/darknet/cfg/yolov3.cfg" weightsPath = "/home/alvaro/Escritorio/tfg/darknet/yolov3.weights" dataPath = "/home/alvaro/Escritorio/tfg/darknet/cfg/coco2.data" self.net = dn.load_net(cfgPath, weightsPath, 0) self.meta = dn.load_meta(dataPath) self.fileName = 'predict.jpg' self.rate = rospy.Rate(10)
Note
The above mentioned path may change as per the directories placed in your computer.
Function image callback. It obtains images from the robot camera:
def imageCallback(self, data): self.imageToProcess = self.bridge.imgmsg_to_cv2(data, "bgr8")
Main function of the node:
def run(self): print("The robot is recognizing objects") while not rospy.core.is_shutdown(): if(self.imageToProcess is not None): cv2.imwrite(self.fileName, self.imageToProcess)
Method for making predictions on images:
r = dn.detect(self.net, self.meta, self.fileName) objects = "" for obj in r: objects += obj[0] + " "
Publish the predictions:
self.pub.publish(objects) self.rate.sleep()
Program entry:
if __name__ == '__main__': dn.set_gpu(0) node = Activity() try: node.run() except rospy.ROSInterruptException: pass
This is the implementation of the second node:
Libraries importation:
#!/usr/bin/env python import rospy from std_msgs.msg import String
Class definition:
class ActivitySub(): yolo_data = "" def __init__(self):
Node initialization and subscriber definition:
rospy.init_node('ThiefDetector', anonymous=True) rospy.Subscriber("yolo_topic", String, self.callback)
The callback function for obtaining published data:
def callback(self, data): self.yolo_data = data def run(self): while True:
Start the alarm if a person is detected in the data:
if "person" in str(self.yolo_data): print("ALERT: THIEF DETECTED") break
Program entry:
if __name__ == '__main__': node = ActivitySub() try: node.run() except rospy.ROSInterruptException: pass
Now, you need to set the destination to the scripts folder:
cd ../../ cd .. cd src/activity1/scripts/
Execute the movement.py file:
touch movement.py chmod +x movement.py cd ~/catkin_ws source devel/setup.bash roslaunch turtlebot_gazebo turtlebot_world.launch
Open a new terminal and execute the command to get the output:
cd ~/catkin_ws source devel/setup.bash rosrun activity1 activity.py cd ~/catkin_ws source devel/setup.bash rosrun activity1 activity_sub.py cd ~/catkin_ws source devel/setup.bash rosrun activity1 movement.py
Run both nodes at the same time. This is an execution example:
Gazebo situation:
First node output:
Second node output: