Categories
Educational Material * Procedures *

Spawn getty over serial: systemd

The switch to systemd from init has been wonderful in the world of *nix. Here’s how you could quickly get a getty running on a serial ttyUSB device in the old system:

  • Create a ttyUSB0.conf file inside /etc/init/ and fill it with start on stopped and RUNLEVEL information, followed by an exec statement, that reads something like: /sbin/getty -L 9600 ttyUSB0 vt102. (see addendum)
  • Tell init to pick it up, by adding to /etc/rc.local the line sudo start ttyUSB0.

(Warning: this is the way I do it, which naturally means there’s something ugly about it!).

Here’s how you’d do this through systemd:

  • Modify the system-file in /lib/systemd/system/serial-getty@.service to change the baud-rate to what you need (technically you shouldn’t do this, but we need to get moving quick).
    The line: ExecStart:-/sbin/agetty 9600 %I $TERM instead of --keep-baud. This will tell it to use a specific baudrate as opposed to scanning through a list.
  • The systemctl daemon needs to know that you meddled with the file (which you shouldn’t have, you know.. but we did anyway, spilt milk). Do:
    sudo systemctl daemon-reload
  • Fun part: just enable this setup once, and systemd will remember over reboots:
    sudo systemctl enable serial-getty@ttyUSB0Of course you can disable, start or stop this. Apparently it is not smart enough to ignore you when you start it twice. The way it enables is by creating a symlink from /etc/systemd/system/getty.target.wants/serial-getty@ttyUSB0.service to /lib/systemd/system/serial-getty@.service, in case the command doesn’t work (note that the latter is the file you edited previously). Feel free to explain this to me after reading more on this RHEL KB. :)

Addendum:

My old setup (using init) had this inside the ttyUSB0.conf file:
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty -L 9600 ttyUSB0 vt102


Ooh, how do you know if you’re using systemd or init? If you’re system is up, then PID 1 should tell you :)
(ps -p1).

Categories
Educational Material * Procedures *

Beginning C++ GUI Development in ROS

Disclaimer:  Part 1 – This tutorial is designed to get you started with developing a GUI for your ROS project using C++ and Qt.  If you’d like to use Python, you should check out the official ROS tutorial here.  Also, the assumption is that you have a basic understanding of creating/building a ROS application in C++ (to include editing the CMakeLists.txt and package.xml files) and know how pull a package from the Nimbus SVN.

Part 2 – This is not the only way to develop a Qt GUI in ROS.  It is a very iterative approach that should help you understand how ROS uses rqt plugins, at least at a basic level. Also, it allows you to make sure that you’ve got working code at certain points before moving on to the next phase of development.

Part 3 – This is not a tutorial on the ins and outs of Qt Creator, but it should at least get you to the point where you can get the IDE up and running.

Part 4 – The below has been tested with both Ubuntu 14/ROS Indigo and Ubuntu 16/ROS Kinetic.

==============================

There are two ways to configure your project.  You can use the “manual” method, or you can use the “automatic” method provided by way of the create_gui.py script included in the ros_gui_template project located in the Nimbus SVN.  Both methods are described below.

 

Manual Method
============

Step 1: Get the ros_gui_template package from the Nimbus SVN.  It’s located in  var/www/svn/UAV/ros-workspaces/ros_gui_template.  You can check it out directly into whatever project you’re working on, or you can put it in it’s own ROS workspace for later use.  Remember, the files in the ros_gui_template project must be somewhere under the src directory of your catkin workspace – either directly or within a subdirectory.

Step 2: Put the ros_gui_template folder in the src folder of whatever package you want to add a gui to.  For instance, you could put it inside of ~/nimbus_asctec/src/nimbus_asctec/

Step 3: Now go back to ~/nimbus_asctec (or whatever your root catkin workspace is) and run catkin_make.  If you’ve already built you project once, then you’ll probably just see it build the ros_gui_template.  Once that’s done, you should be able to run the following:
roslaunch ros_gui_template ros_gui_template.launch

You should eventually see the following:

If you do, then success!  Now the fun begins.

Step 4: Obviously, you want your code in there with your file names and so on.  That means you’ll need to make some changes to the files in your project.  Basically, you’re going to replace any instances of “ros_gui_template” and “RosGuiTemplate” with your own project name.  For tutorial purposes, we’ll use “your_project” and “YourProject.”

Start with the folder that you just placed inside you project.  Rename it to “your_project.”  Now go into the base directory of “your_project” (where you see CMakeLists.txt, package.xml, plugin.xml, and so on) and make the the following changes to the following files:

CMakeLists.txt
===============
-Find and replace all instances of “ros_gui_template” with “your_project”

package.xml
===========
-Find and replace all instances of “ros_gui_template” with “your_project”
-Change the other tags as/if required.  Remember, ROS stuff will probably
change here as your project progresses.

plugin.xml
==========
-Change path=”lib/libros_gui_template” to path=”lib/libyour_project”
-Change class name=”ros_gui_template/RosGuiTemplate” to class name=”your_project/YourProject”
-Change type=”ros_gui_template::RosGuiTemplate” to type=”your_project::YourProject”
-Change the other stuff as/if needed

Rename ros_gui_template.launch to whatever-you-want.launch

whatever-you-want.launch
=======================
-Find and replace all instances of “ros_gui_template” with “your_project”

In the include folder, rename “ros_gui_template.h” to “your_project.h”

your_project.h
==============
-Change the #ifndef and #define lines as you see fit
-Find and replace all instances of “ros_gui_template” with “your_project”
-Find and replace all instances of “RosGuiTemplate” with “YourProject”

In the src folder, rename “ros_gui_template.cpp” to “your_project.cpp”

your_project.cpp
================
-Find and replace all instances of “ros_gui_template” with “your_project”
-Find and replace all instances of “RosGuiTemplate” with “YourProject”

In the resource folder, rename “ros_gui_template.ui” to “your_project.ui”

your_project.ui
===============
-Find and replace all instances of “RosGuiTemplate” with “YourProject”

In the scripts folder, rename “ros_gui_template.py” to “your_project.py”
(make sure this file stays executable)

your_project.py
===============
-Find and replace all instances of “ros_gui_template” with “your_project”

Step 5: ROS has a tendency to cache certain things, and sometimes this can pose a problem, especially after you change file/folder names within a project.  In order to ensure you’ll be able to run your new GUI, you’ll have to clear your rqt_gui cache with the following command: rm ~/.config/ros.org/rqt_gui.ini

Step 6: Now go back to the root of your workspace and run catkin_make.  Hopefully, everything will build and you’ll be able to test your project with
roslaunch your_project whatever-you-want.launch

At this point you should see the exact same window as before.

Step 7: After you get that working, you’ll be ready to use Qt Creator to get in there and edit your UI and whatever else you need to do.  If you don’t have Qt Creator, you can get it with sudo apt-get install qtcreator Remember, you need to source your devel/setup.bash and THEN launch qtcreator from that same command line!  From there, you open a project and choose the CMakeLists.txt file in your_project’s directory (where package.xml is and so on).  You will be then asked to configure your project by picking a default build directory.  You can safely accept the default presented as you will not be using Qt Creator to build your project – see the warning below.

WARNING

***************************************

Qt Creator is an excellent IDE that you can use to edit your ROS C++ code as well as graphically create/edit your user interface; HOWEVER, it uses the QMake utility to build and manage its projects.  QMake does not play well with ROS and catkin_make.  Therefore, DO NOT USE Qt Creator’s “build” button on your project.  ALWAYS use catkin_make from the command line!

***************************************

Step 8: If you’re not a Qt expert, there are plenty of awesome tutorials on youtube that will take you through the basics of creating buttons, assigning functions to those buttons and so on.  It’s a fairly simply process, but it’s not quite as easy as Visual Studio development.  VoidRealms has an excellent set of 107 videos on YouTube that can help you gain some understanding of Qt and Qt programming.  Be advised, it’s only about Qt and C++ – you’ll have to bring your own understanding of ROS to bear as needed.

Automatic Method
===============

Step 1: Get the ros_gui_template package from the Nimbus SVN.  It’s located in  var/www/svn/UAV/ros-workspaces/ros_gui_template.  You can check it out directly into whatever project you’re working on, or you can put it in it’s own ROS workspace for later use.  Remember, the files in the ros_gui_template project must be somewhere under the src directory of your catkin workspace – either directly or within a subdirectory.

Step 2: Navigate to the directory where you placed the ros_gui_template files.  You should see CMakeLists.txt, package.xml, create_gui.py, and others.

Step 3: Run the create_gui.py script with two arguments.  The first argument is the name of your package, and the second is the name of the class that defines your gui.  Typically, these are an underscored version and a CamelCased version of the same word as specified in the ROS C++ Style Guide.  See the below example.

./create_gui.py your_project YourProject

You’ll see some output as the script goes through all the files that were downloaded with the ros_gui_template and makes all the needed changes as described in the “manual” section of this tutorial.

The final thing the script does is to remove the SVN info from the downloaded files so that you won’t inadvertently change the repository master.

Step 4: Now go back to the root of your workspace and run catkin_make.  Hopefully, everything will build and you’ll be able to test your project with
roslaunch your_project your_project.launch

At this point you should see a gui that looks like the one shown in Step 3 of the “manual” section of this tutorial.

Step 5: After you get that working, you’ll be ready to use Qt Creator to get in there and edit your UI and whatever else you need to do.  If you don’t have Qt Creator, you can get it with sudo apt-get install qtcreator Remember, you need to source your devel/setup.bash and THEN launch qtcreator from that same command line!  From there, you open a project and choose the CMakeLists.txt file in your_project’s directory (where package.xml is and so on).  You will be then asked to configure your project by picking a default build directory.  You can safely accept the default presented as you will not be using Qt Creator to build your project – see the warning below.

WARNING

***************************************

Qt Creator is an excellent IDE that you can use to edit your ROS C++ code as well as graphically create/edit your user interface; HOWEVER, it uses the QMake utility to build and manage its projects.  QMake does not play well with ROS and catkin_make.  Therefore, DO NOT USE Qt Creator’s “build” button on your project.  ALWAYS use catkin_make from the command line!

***************************************

Step 6: If you’re not a Qt expert, there are plenty of awesome tutorials on youtube that will take you through the basics of creating buttons, assigning functions to those buttons and so on.  It’s a fairly simply process, but it’s not quite as easy as Visual Studio development.  VoidRealms has an excellent set of 107 videos on YouTube that can help you gain some understanding of Qt and Qt programming.  Be advised, it’s only about Qt and C++ – you’ll have to bring your own understanding of ROS to bear as needed.

If you have comments or questions, don’t hesitate to let me know.

–Adam

Categories
Educational Material *

Exporting ROS Bag Files to Matlab, v2.0

A while ago I wrote a post about bag2csv, which is a tool I wrote to import data from ROS bags to Matlab workspaces. This tool first converted the bag data to CSV files, and then read the CSV files into Matlab. We’ve discovered a lot of shortcomings to this approach since that post was written, and as a result, have developed a different tool for importing bag data into Matlab. The two largest issues we encountered were correctly putting ROS messages with arbitrary string fields into a CSV file and dealing with complex ROS messages that contained things like variable arrays of other ROS messages. Putting these types of data into CSV files is hard, because arbitrary strings may contain sequences that break the CSV parser, and variable length arrays do not mesh well with CSV’s tabular format.

I wrote a replacement tool for bag2csv called bag2matlab that uses ROS’s Python bag manipulation modules to directly read the bag data into a Matlab workspace. This tool is not only addresses the problems with bag2csv, but is much simpler. Users can call the bagReader.m Matlab function from within their Matlab environment, and it will seamlessly read all of the data on a given topic from the requested bag file. The data is returned as a table, where each column in the table corresponds to a field in the requested topic. In the case where the topic contains nested ROS messages, the tool flattens these structures, so every field in every subtopic has a column in the output table.

Using this tool is is very simple. From within Matlab, users can simply call it using syntax like:

msg_data = bagReader('input.bag', 'topic_name');

Our university Matlab license does not include the Robotics Toolbox, so I do not depend on anything in that toolbox in this project. The only dependencies should be a ROS installation and Matlab. I tested this with ROS Kinetic Kame and Matlab R2015b on Ubuntu 16.04.

I’ve posted the code to GitHub here, and I hope others will find it useful.

Categories
Educational Material *

Dancing with Drones at Lincoln High School

Last year we collaborated with the international dance company STREB (really they are “Extreme Action Heros,” not dancers) to put on a workshop with dancers and robotics students at UNL. There is a nice video giving an overview of the collaboration here:

A couple of days ago we worked with a Lincoln High School dance class to teach them how technology and dance can interact. We did this by teaching them about how UAVs fly (Najeeb did an excellent job), showing them a dance with a UAV, and then giving them small flying ferries to try to create their own dance with. It was a short class, but still very rewarding to see how quickly the students took to creating new ways to interact with the flying vehicles. Here are a few pictures from the day.

 

IMG_4650

IMG_4664

IMG_4663

IMG_4675

 

 

 

Categories
Educational Material * Media

Sunday with a scientist

IMG_5006-sml IMG_5084-sml

On Sunday, February 15th the Nimbus Lab was involved in Sunday with a Scientist Day at the University of Nebraska Morrill Hall State Museum. During this event we presented some of the research conducted in our lab to the public.

We demonstrated our water sampling hexacopter, and sampled water from a small container (2x4x4) feet, and demonstrated both autonomous and human controlled flight and operation. This water sampling demonstration attracted many people as well as queries from children with interesting questions, like how much load can one of these vehicles carry and still operate (a question asked by an 8 year old). Besides showing the value of such a UAV in both the field of Water Ecology and surface water analysis, we were also able to talk about the safety involved in operating such systems. People were able to feel the power of such machines by noticing the air dynamics created by a relatively small robot.

IMG_5030-smlAnother thing we tried to help young kids understand is how to control a UAV. People were allowed to control a UAV in a constrained environment. We tethered a UAV to limit its motion in all dimensions of a 3D space, and then we handed the control to kids. The person then starts applying thrust, pitch, roll or yaw and observes the impact the control has on the UAV. This helps someone with no prior experience with UAVs understand both the dynamics of how a UAV operates and the impact of each parameter on the other, in a very safe and controlled environment. It also helped young observers notice the means of communication between a human and a robot (in this case via a hand heled controller).

Another demonstration presented during the event was streaming live video feeds. Using a done equipped with both a camera and a wifi router, and typical hand held devices (iPad-mini) and a regular TV, we were able to demonstrate both controlling a UAV and capturing live video feed and relaying it to the TV set. While flying at a safe distance from the observers, we were still able to display their faces on the TV screen. At first young children were excited to see themselves on a TV, but then they started wondering how is all this happening, we were successful in triggering their intellectual curiosity. Children started experimenting to figure out where the camera was and how was it transmitting these pictures.

IMG_5041-smlLearning the power of air dynamics can never start too early. So one of the experiments kids (young future pilots) were given an opportunity to perform was creating their own flying planes, and observing how well the wind can fly them. We had a couple of fans creating a wind stream, then had the children cut paper sheets to create wind gliding shapes (paper copters). Then they released them in the wind stream and they observed how high they could reach. This helped introduce the power of wind lift, and made it easier for the young ones to understand how the rest of the demonstrations were operating.

After the kids were able to have hands on experience with things, more and more questions started coming in. And more and more interests started showing up. As for us, the more we presented to the public, the more we realized people are starting to know more about UAVs, and want to figure out how things work. I actually had a few high school students ask me some very interesting questions regarding how to connect different parts of a UAV. It turned out they were actually attempting to build their own UAV, and wanted to figure out how to connect some electronic components.

Working with UAVs today is similar to working with PCs back in the early 90s. It may sound intimidating for some but within a few years (a blink of an eye) everyone will be familiar with terms like IMU, localization, PID controller, etc., when each person will have a UAV at home to take out the trash. But before that can become a reality, safety is still a concern, and that is another area of research our lab is investing in and investigating.

We also attracted new agencies, by having new technology flying besides ancient fossils.

http://www.1011now.com/home/headlines/UNL-Professors-Give-Drone-Demonstration-Explain-Why-They-Are-Important-292021231.html

http://www.klkntv.com/category/190066/klkn-channel-8-video?clipId=11140407&autostart=true

http://journalstar.com/news/local/drones-fly-amid-praise-at-morrill-hall/article_311c501a-169a-5740-b01d-4a434ad248f7.html

 

Categories
Educational Material *

Exporting ROS Bag Files to Matlab

This tool has been deprecated in favor of a new method which directly reads bag data into Matlab. See this post for details.

 

Original post:

Recently, Adam introduced a tool to analyze ROS bag files using the Python pandas package, and plot the data using matplotlib. You can read his post here. While this is a great tool, I have a a couple of requirements not addressed by the tool. First, I usually analyze my data in Matlab, and getting the bag data to a CSV file only gets me half way to my goal. Second, the pandas script does not handle some of the messages I use in my code, specifically, arrays of geometry_msgs/Vector3 in a message. Finally, I want to be able to analyze bags that I do not have the message file definitions for. Since I often modify my message files in the field in response to debugging problems I encounter during an experiment, I sometimes do not have the message files used to create a bag.

Once in Matlab, I can use the wide range of Matlab data analysis tools to analyze my information, or send the data to our partner researchers who are more familiar with Matlab than they are with ROS or Python. To satisfy my needs, I have created a toolchain of Python and Matlab scripts that allow me to import bagged data into Matlab.

All of the following programs can be found at the following GitHub repository, along with more examples of importing CSV files to Matlab.

https://github.com/unl-nimbus-lab/bag2csv

Getting the data into a CSV

One of the first tasks I did when I joined the lab was modify a Python script my advisor, Carrick Detweiler, wrote for extracting data from bag files to CSV files. The bag_reader.py program in this repo represents a further refinement of this script that addresses shortcomings in the first script that made it incapable of analyzing bag files that contained messages with fields of arrays.

This script is capable of converting all of the messages for a specified topic in a bag file to a CSV representation. bag_reader outputs a CSV file where the columns are the fields within the messages published on a specified topic. There is a header line at the beginning with the field names within the specified topic. If bag_reader encounters a field that is an array type, for example, ranges from a Hokuyo laser scanner, it joins the array contents with underscores and puts them into one column in the CSV file.

The two most common tasks I do with bag_reader is to list all the messages in a bag, and extract messages from a certain topic. To list the contents of a bag, simply run the following command:

bag_reader -b test.bag -i

The -b option specifies the bag file I want to work on, and -i tells the script to list all of the topics and the fields within the messages.

The second common task I perform is to convert all messages published on a certain topic to a CSV file. The following code does this task. -t is the flag to specify the topic to read, and -o specifies the output CSV file.

bag_reader -b test.bag -t /temperature -o temperature.csv

The script will also print out help text with the -h option.

bag_reader -b test.bag -h

The script has one major shortcoming. One of the first things the script does is search for the first message of a specified topic in the bag file, and uses that as a template for formatting the remaining messages. If the first message has a different format from the remaining messages in the file, the script will fail. One example of how this could happen is if the message should contain a vector of geometry_msgs/Vector3 types, and the first message has a blank array. The ROS bag format will not place the x, y, and z elements in the blank array, so my script does not learn that this message should contain those elements, and will fail when it encounters messages with values in the array.

Matlab

Once I have the data in CSV files, it becomes trivial to get the data into Matlab. I use the builtin Matlab tools and create scripts that import each message type into Matlab. For example, the temperature.csv file used in the prior example contains messages from the standard ROS sensor_msgs/temperature message. To read all of the data into a Matlab struct, I can use the following script.

function [bag_data] = sensor_msgs_temperature_extract(filename)
fid = fopen(filename);
C = textscan(fid, ...
'%s%n%n%n%n%n', ...
'delimiter',',', ...
'headerLines', 1);
fclose(fid);
bag_data = struct(...
'seq', C{2}, ...
'nsecs', C{3}, ...
'secs', C{4}, ...
'times', C{4} + (C{3} / 1e9), ...
'temperature', C{5}, ...
'variance', C{6});
end

The textscan() command uses the data format to read all of the lines in the file into a cell array called ‘C’. I use ‘C’ to fill out a struct with the information.

Conclusion

I hope other people find this tool useful, and can use it in their research. If you find any bugs or have a good feature to add, let me know, as I plan to continuously improve this tool.