Monday, November 16, 2015

Running ROS across multiple machines (multi-agent system) problem and solution


If you are not familiar with ROS across multiple machines, please refer to Running ROS across multiple machines tutorial. 

Running ROS across multiple machines requires only ONE master, however, if you are trying to build an autonomous multi-robot system you will need to run all robots i.e. there will be more than one master. There is no solution till now for  running ROS across multi-agent machines. 

Lightweight Communications and Marshalling (LCM) is maybe one option to be used, it is  "a set of libraries and tools for message passing and data marshalling, targeted at real-time systems where high-bandwidth and low latency are critical", for more info look here.

The idea is to use ROS to control and communicate between notebook and turtlebot base robot, and to use LCM to communicate over network. LCM supports C/C++, Java, Python, Lua, C#/.Net.



Installing LCM

-          Download LCM from this link
-          Build instruction here, replace X,Y,Z with the version you are using
o   $ unzip lcm-X.Y.Z.zip
o   $ cd lcm-X.Y.Z
o   $ ./configure
o   $ make
o   $ sudo make install
o   $ sudo ldconfig

-          Getting started with LCM

What you need to start with LCM is to create a message type, here you are going to pub/sub using lcm format, then use lcm-gen to generate the massage with the language you are using (C,C++, Python, etc), no more delay, start pub and sub.
There are some ready examples we can use for demonistration
o   Create a message type
§  Go to /lcm-1.3.0/examples/types
§  You will find example_t.lcm message type
or simply create new file with the following content and name it example_t.lcm
package exlcm;

struct example_t
{
    int64_t  timestamp;
    double   position[3];
    double   orientation[4]; 
    int32_t  num_ranges;
    int16_t  ranges[num_ranges];
    string   name;
    boolean  enabled;
}
o   Compile it based on the language you use
§   for python  lcm-gen -p example_t.lcm
o   Copy generated folder and past it next to your publisher and subscriber code.
§  Copy exlcm generated folder and past it into lcm-1.3.0/example/python, there is two simple examples for pub/sub listener.py and send-message.py, here is the content of them 
# listener.py

import lcm
from exlcm import example_t

def my_handler(channel, data):
    msg = example_t.decode(data)
    print("Received message on channel \"%s\"" % channel)
    print("   timestamp   = %s" % str(msg.timestamp))
    print("   position    = %s" % str(msg.position))
    print("   orientation = %s" % str(msg.orientation))
    print("   ranges: %s" % str(msg.ranges))
    print("   name        = '%s'" % msg.name)
    print("   enabled     = %s" % str(msg.enabled))
    print("")

lc = lcm.LCM()
subscription = lc.subscribe("EXAMPLE", my_handler)

try:
    while True:
        lc.handle()
except KeyboardInterrupt:
    pass

lc.unsubscribe(subscription)
# send-message.py
import lcm
import time

from exlcm import example_t

lc = lcm.LCM()

msg = example_t()
msg.timestamp = int(time.time() * 1000000)
msg.position = (1, 2, 3)
msg.orientation = (1, 0, 0, 0)
msg.ranges = range(15)
msg.num_ranges = len(msg.ranges)
msg.name = "example string"
msg.enabled = True

lc.publish("turtlebot1", msg.encode())
o   On lcm-1.3.0/example/python change listener.py and send-message.py to be executable file
§  chmod +x listener.py
§  chmod +x send-message.py
o   now you are ready to run the listener and sender within the same pc.
§  python listener.py
§  python send-message.py

o However, to send and receive within the network, you need to configure multicast address. It usually enabled in ubuntu, you can check by this command
§  Netstat –g
§  Most probably you will get default multicast ip 224.0.0.251
§  Then you need to change TTL from 0 (default) into number of hops you want. Simply export this environment variable on .bachrc file
 export LCM_DEFAULT_URL=udpm:// 224.0.0.251:7667?ttl=3

§ Do the same for all nodes you want to communicate
§ Now run python listener.py on one node, and send-message.py on another node

Combine LCM with ROS 

After installing and testing LCM, here is a sample for running running LCM over network and ROS within the robot.

 #!/usr/bin/env python
# altered by M. Al-shaboti
import rospy import lcm
from exlcm import example_t
from std_msgs.msg import String
def my_handler(channel, data):
from geometry_msgs.msg import Twist is_moving = False;
print("Received message on channel \"%s\"" % channel)
msg = example_t.decode(data) print(" timestamp = %s" % str(msg.timestamp))
print(" orientation = %s" % str(msg.orientation))
print(" position = %s" % str(msg.position)) print(" ranges: %s" % str(msg.ranges))
# let's go forward at 0.2 m/s
print(" name = '%s'" % msg.name) print(" enabled = %s" % str(msg.enabled)) print("") if msg.enabled:
move_cmd.linear.x = 0
move_cmd.linear.x = 0.2 # let's turn at 0 radians/s move_cmd.angular.z = 0 else: # let's go forward at 0.2 m/s # let's turn at 0 radians/s
rospy.loginfo("To stop TurtleBot CTRL + C")
move_cmd.angular.z = 0 def main(): rospy.init_node('turtlebot_node', anonymous=True) # tell user how to stop TurtleBot
cmd_vel = rospy.Publisher('cmd_vel_mux/input/navi', Twist, queue_size=10)
# Create a publisher which can "talk" to TurtleBot and tell it to move # Tip: You may need to change cmd_vel_mux/input/navi to /cmd_vel if you're not using TurtleBot2
move_cmd = Twist()
#TurtleBot will stop if we don't keep telling it to move. How often should we tell it to move? 10 HZ r = rospy.Rate(10); # Twist is a datatype for velocity global move_cmd # let's go forward at 0.2 m/s move_cmd.linear.x = 0.2 # let's turn at 0 radians/s
# wait for 0.1 seconds (10 HZ) and publish again
move_cmd.angular.z = 0 lc = lcm.LCM() subscription = lc.subscribe("turtlebot1", my_handler) try: while not rospy.is_shutdown(): lc.handle() # publish the velocity cmd_vel.publish(move_cmd) r.sleep() except KeyboardInterrupt: pass
main()
lc.unsubscribe(subscription) # spin() simply keeps python from exiting until this node is stopped #rospy.spin()
if __name__ == '__main__':





import lcm
import time from exlcm import example_t lc = lcm.LCM() msg = example_t() msg.timestamp = int(time.time() * 1000000) msg.position = (1, 2, 3) msg.orientation = (1, 0, 0, 0) msg.ranges = range(15) msg.num_ranges = len(msg.ranges) msg.name = "example string" msg.enabled = True lc.publish("turtlebot1", msg.encode())





Wednesday, September 23, 2015

Turtlebot (ROS) with Xtion pro live driver in virtual machine (ready to use)


Ubuntu-14-04 ROS workstation (virtualbox)


I have installed ROS and Xtion pro live driver in a vertualbox machine such that it is ready to be used as a workstation. 

https://drive.google.com/file/d/0BxgVJIO4HcYFNDRrTGRQYXMwWjQ/view?usp=sharing

User name: turtlebot
Password: kfupmturtle

Note:
Link above has only the hard drive of the virtualbox, so you need to create one and select this hard when it ask you to create new one.