ROS x Arduino
Today, I tried follow the guidence of "ROS Robotics Projects", succuessfully made the communication from Ubuntu on my laptop and Arduino MAGE 2560.
1. Install the rosserial package:
$ sudo apt-get install ros-indigo-rosseiral $ sudo apt-get install ros-indigo-rosseiral-arduino
2. Install Arduino IDE for linxu 64bit version, just download it and unzip, open IDE:
$ ./arduino
3. in /home/marc/Arduino folder, you will find a folder named libraries, if you cant find it, just mkdir
4. create ros_lib forlder by input this line:
$ rosrun rosserial_arduino make_libraries.py .
5. Reopen the Arduino IDE, you will find the example code inside ros_lib, select the Blink, almost lession 101:
you will find:
/* * rosserial Subscriber Example * Blinks an LED on callback */ #include <ros.h> #include <std_msgs/Empty.h> #include <std_msgs/String.h> ros::NodeHandle nh; void messageCb( const std_msgs::String& toggle_msg){ digitalWrite(13, HIGH-digitalRead(13)); // blink the led } ros::Subscriber<std_msgs::String> sub("toggle_led", &messageCb ); void setup() { pinMode(13, OUTPUT); nh.initNode(); nh.subscribe(sub); } void loop() { nh.spinOnce(); delay(1); }
change the std_msgs::Empty to std_msgs::String. and upload it to Arduino 2560 board.
6. Fire up the roscore and serial trans node in another terminal:
$ rosrun rosserial_python serial_node.py /dev/ttyACM0
7. Vim to create a publisher to send topic to Arduino:
/* * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ // %Tag(FULLTEXT)% // %Tag(ROS_HEADER)% #include "ros/ros.h" // %EndTag(ROS_HEADER)% // %Tag(MSG_HEADER)% #include "std_msgs/String.h" // %EndTag(MSG_HEADER)% #include <sstream> /** * This tutorial demonstrates simple sending of messages over the ROS system. */ int main(int argc, char **argv) { /** * The ros::init() function needs to see argc and argv so that it can perform * any ROS arguments and name remapping that were provided at the command line. * For programmatic remappings you can use a different version of init() which takes * remappings directly, but for most command-line programs, passing argc and argv is * the easiest way to do it. The third argument to init() is the name of the node. * * You must call one of the versions of ros::init() before using any other * part of the ROS system. */ // %Tag(INIT)% ros::init(argc, argv, "talker"); // %EndTag(INIT)% /** * NodeHandle is the main access point to communications with the ROS system. * The first NodeHandle constructed will fully initialize this node, and the last * NodeHandle destructed will close down the node. */ // %Tag(NODEHANDLE)% ros::NodeHandle n; // %EndTag(NODEHANDLE)% /** * The advertise() function is how you tell ROS that you want to * publish on a given topic name. This invokes a call to the ROS * master node, which keeps a registry of who is publishing and who * is subscribing. After this advertise() call is made, the master * node will notify anyone who is trying to subscribe to this topic name, * and they will in turn negotiate a peer-to-peer connection with this * node. advertise() returns a Publisher object which allows you to * publish messages on that topic through a call to publish(). Once * all copies of the returned Publisher object are destroyed, the topic * will be automatically unadvertised. * * The second parameter to advertise() is the size of the message queue * used for publishing messages. If messages are published more quickly * than we can send them, the number here specifies how many messages to * buffer up before throwing some away. */ // %Tag(PUBLISHER)% ros::Publisher chatter_pub = n.advertise<std_msgs::String>("toggle_led", 1000); // %EndTag(PUBLISHER)% // %Tag(LOOP_RATE)% ros::Rate loop_rate(1); // %EndTag(LOOP_RATE)% /** * A count of how many messages we have sent. This is used to create * a unique string for each message. */ // %Tag(ROS_OK)% int count = 0; while (ros::ok()) { // %EndTag(ROS_OK)% /** * This is a message object. You stuff it with data, and then publish it. */ // %Tag(FILL_MESSAGE)% std_msgs::String msg; std::stringstream ss; ss << "hello world " << count; msg.data = ss.str(); // %EndTag(FILL_MESSAGE)% // %Tag(ROSCONSOLE)% ROS_INFO("%s", msg.data.c_str()); // %EndTag(ROSCONSOLE)% /** * The publish() function is how you send messages. The parameter * is the message object. The type of this object must agree with the type * given as a template parameter to the advertise<>() call, as was done * in the constructor above. */ // %Tag(PUBLISH)% chatter_pub.publish(msg); // %EndTag(PUBLISH)% // %Tag(SPINONCE)% ros::spinOnce(); // %EndTag(SPINONCE)% // %Tag(RATE_SLEEP)% loop_rate.sleep(); // %EndTag(RATE_SLEEP)% ++count; } return 0; } // %EndTag(FULLTEXT)%
Just remember the msg type is std_msgs::string and the topic is "toggle_led";
make it and run the node.
8. use rostopic list and rostopic echo /toggle_led to check who is publishing and who is subscribing.
9. The result is you can see LED is blink after node arduinoTalker sent any words through serial port.