Creating a teleoperation node using the Leap Motion controller

In this section, we will demonstrate how to create a teleoperation node for a robot using Leap Motion data. The procedure is very simple. We can create a ROS package for this node using the following steps:

  1. The following is the command to create a new package. You can also find this package in chapter_11_ws/vr_leap_teleop:
$ catkin_create_pkg vr_leap_teleop roscpp rospy std_msgs visualization_msgs geometry_msgs message_generation visualization_msgs  

After creation, you could build the workspace using catkin_make command.

  1. Now, let's create the node to convert Leap Motion data to Twist. You can create a folder called scripts inside the vr_leap_teleop package.
  2. Now you can copy the node called vr_leap_teleop.py from our repository at https://github.com/PacktPublishing/ROS-Robotics-Projects-SecondEdition/blob/master/chapter_11_ws/vr_leap_teleop/scripts/vr_leap_teleop.py. Let's look at how this code works.

We need the following Python modules in this node. Here, we require message definitions from the leap_motion package, which is the driver package:

import rospy 
from leap_motion.msg import leap 
from leap_motion.msg import leapros 
from geometry_msgs.msg import Twist 
  1. Now, we have to set some range values in which we can check whether the current hand value is within range. We are also defining the teleop_topic name here:
teleop_topic = '/cmd_vel_mux/input/teleop' 
 
low_speed = -0.5 
stop_speed = 0 
high_speed = 0.5 
 
low_turn = -0.5 
stop_turn = 0 
high_turn = 0.5 
 
pitch_low_range = -30 
pitch_high_range = 30 
 
roll_low_range = -150 
roll_high_range = 150 

Here is the main code of this node. In this code, you can see that the topic from the Leap Motion driver is being subscribed to. When a topic is received, it will call the callback_ros() function:

def listener(): 
    global pub 
    rospy.init_node('leap_sub', anonymous=True) 
    rospy.Subscriber("leapmotion/data", leapros, callback_ros) 
    pub = rospy.Publisher(teleop_topic, Twist, queue_size=1) 
 
    rospy.spin() 
 
if __name__ == '__main__': 
    listener() 

The following is the definition of the callback_ros() function. Essentially, it will receive the Leap Motion data and extract the orientation components of the palm only. Therefore, we will get yaw, pitch, and roll from this function.

We are also creating a Twist() message to send the velocity values to the robot:

def callback_ros(data): 
    global pub 
 
    msg = leapros() 
    msg = data 
     
    yaw = msg.ypr.x 
    pitch = msg.ypr.y 
    roll = msg.ypr.z 
 
    twist = Twist() 
 
    twist.linear.x = 0; twist.linear.y = 0; twist.linear.z = 0 
    twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0 

We are performing a basic comparison with the current roll and pitch values again within the following ranges. Here are the actions we've assigned for each movement of the robot:

Action

Description

Hand gesture

Robot movement

Hand pitch low

Move forward

Hand pitch high

Move backward

Hand roll anticlockwise

Rotate anticlockwise

Hand roll clockwise

Rotate clockwise

 

Here is a code snippet that takes care of one condition. In this case, if the pitch is low, then we are providing a high value for linear velocity in the x direction for moving forward:

if(pitch > pitch_low_range and pitch < pitch_low_range + 30):
twist.linear.x = high_speed; twist.linear.y = 0;
twist.linear.z = 0 twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0

Okay, so we have built the node, and we can test it at the end of the project. In the next section, we will look at how to implement VR in ROS.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset