Building a 3-D Printed Robot – Part 4

Since my last update, I have been able to assemble the hand and arm.  Perhaps the trickiest part was threading the finger control lines through the wrist and forearm to reach the servos.

IMG_1012

I elected to use the dual track servo wheel created by Mats Önnerby and available here. The dual track servo wheel is designed to provide a uniform tension on the tendons.  Other solutions have involved the use of springs to maintain tension which still may be needed depending on the results of tension calibration.  Calibration is the determination of the range of servo rotation needed to open and close each of the fingers.  This will be interesting because the rotation of the wrist can change the tension depending on the degree of wrist rotation.  Because of the iterative nature of this termination, I’ve elected to create a Python-based user interface to change the servos interactively.  This post describes how I’ve built this user interface.

Building a Python-based GUI for ROS

This implementation use the Robot Operating System (ROS).  The ROS provides a flexible control panel called RQT that enables prebuilt or custom plugins to interact with the rest of your ROS-based robot.  There are quite a few existing plugins to monitor messages, logging, etc.  It’s called RQT because it is based on the powerful UI framework called Qt and the Python bindings for Qt4 are included in the ROS distribution.

There is a tutorial for building a custom plugin and it is among the most confusing documentation I’ve seen for ROS (poorly organized and written).  It could be that I am still learning the details of Python and the documentation assumes a level of Python expertise I have yet to achieve.   I’ve written this post partially for myself so that I can remember how to create additional plugins but also for anyone else who struggles to follow the ROS tutorial.

Designing the UI

My intent is to have the hand calibration UI run on the Raspberry Pi with the touchscreen, but that doesn’t mean the UI needs to be developed on the Raspberry Pi.  I installed Qt5 on my Ubuntu virtual machine running on my Mac.  This was very straightforward and I encountered no issues getting it up and running.

When a new project is created in Qt, you are asked to specify the base class for your user interface.  The RQT requires that your user interface use the QWidget class as the base class.  The Qt Creator is the WYSIWYG user interface design tool.  Here is how it looks after selecting QWidget as the base class and designing the hand calibration user interface:

qtcreator
The Qt Creator interface while within the Design perspective

The left side of the Qt Creator includes the perspectives such as the Design perspective as shown.  The Design perspective has the palette of layout constraints and various elements to place on the canvas.  The canvas has your user interface design – the hand calibration user interface design is shown here.  Below the canvas is the Signals and Slots Editor that enables you to connect simple event-based relationships.  In this case, as each of the sliders move, the number next to the slider is updated to reflect the new value.  On the right side is the widget containment hierarchy and the property sheet for the selected element.

Your interface design is stored in a *.ui file which is an XML document which describes the elements and property choices you made in the Qt Creator. This file is used by RQT to render your plugin.  There are alternative tools such as PyQt that includes utilities to convert the *.ui file into Python that uses the Python bindings included in Qt.  This approach only works with Python 3 and ROS uses Python 2.7, so don’t be tempted to take this route (I did and it took a while to sort it out).  Now that we have a user interface file, it’s time to integrate it into ROS.

Building the RQT Plugin

Since I would like to run the user interface on the Raspberry Pi, I had to revisit the ROS installation.  When I originally installed the ROS on the Raspberry Pi, I elected to install the ROS-Comm subset instead of the desktop version (that includes Qt) in section 3.1. This time I installed the desktop version and subsequently ran into several linker issues that required source code level patches to fix.  Now my Ubuntu and Raspberry Pi installations are equivalent.

Here are my notes related to the ROS RQT custom plugin tutorial.  A custom plugin is implemented with a ROS package.

  1. Create an Empty Package – this is trivial and the instructions are clear.  The naming convention for plugins is apparently to use rqt_ as a prefix for the package name.
  2. Modify the package.xml – A default package.xml was created in the step above and needs to have the tutorial updates made without changes.  The confusing ${prefix} string need not be updated with your package path or anything.  The tutorial text should be copied and pasted into your package.xml file verbatim.
  3. Create the plugin.xml file – This part is a bit confusing because it requires knowledge of the code you have not yet written.  Skip this for now and proceed to the next step.  Come back to this once you’ve written the code:
    • Here is how my plugin.xml looks after step 4:
    • pluginxml
    • The class tag name attribute must match the class name in the code
    • The type attribute should use <ROS package name>.<Python source file name (the module name)>.<Plugin class name>
    • The rest of the XML results in a menu on RQT that looks like this:
    • rqtinmoov
  4. Write a plugin code – Since this is going to be in Python, you can ignore most of what is written in the tutorial for this step and proceed to the Python specific instructions entitled Writing a Python Plugin.  A few points about these instructions:
    • It’s not clear to the ROS and Python neophytes that it’s important to recognize that the source directory should be named the same as the ROS package (e.g. rqt_mypkg) and the source file name represents a Python module (e.g. my_module).  These two names are important to know for the plugin.xml file updates.
    • I changed the default source code:
      • Changed the class name from MyPlugin to HandCalibrationPlugin
      • Changed the setObjectName parameters for the plugin and the widget.
      • Updated the ‘MyPlugin.ui’ reference to the name of the actual *.ui filename from Qt Creator.  While the tutorial does not mention it (except in the code comments), you need to create a ‘resource’ directory within the package source directory and place your *.ui file into the resource directory.
    • The section ‘4. Once code is done’ is in the wrong place.  You cannot run your plugin yet until it is installed, so ignore this step for now.
    • Go back an update the plugin.xml file now.
  5. Install & Run your plugin – The instructions are adequate provided you have a clear understanding of the resulting directory structure.  Here are few notes:
    • My directory structure is now this:
    • rqtdirectorystructure
    • The tutorial reference changes to setup.py and CMakeList.txt that are in your package source directory as shown above (e.g. src/rqt_handcalibration)
    • The tutorial does not mention it, but I believe that you must also go to your catkin_ws directory and issue a catkin_make command.
    • In order to run your plugin the first time, I needed to use the –force-discover option on rqt

The End Result

Now I have a ROS package that renders my calibration user interface that can run on my Mac or the Raspberry Pi.  The distributed architecture of ROS enables me to run it on either platform.

calibrationuilinux

Development Environment Note

My development environment is on an Ubuntu virtual machine running on my Mac.  I’ve been using rsync as part of a build step to move files from Ubuntu to the Raspberry Pi. With the addition of a new ROS package, the build script now has two rsync commands. Until now, I’ve lived with the need to enter the password for the SSH connection rsync uses to connect to the Raspberry Pi.  I found that this documentation was a pretty good explanation of how to configure SSH keys to enable a trusted connection without the need to supply a password.

 

 

 

 

Building a 3-D Printed Robot – Part 3

It’s been about a month since the last update and there has been some progress.  I received the 3D printed parts only to find that all of the parts had been printed using PLA instead of ABS plastic.  PLA is quite brittle and does not react to Acetone (the importance of this characteristic will become clear later).  It took over 2 weeks more to have all of the parts reprinted in ABS.  While I was waiting, I worked out the development environment.

The Development Environment

As I mentioned in my previous post, I am using the Robotics Operating System and that is very well supported on Ubuntu.  I am using VirtualBox to run Ubuntu on my Mac.  I found the default CPU and memory configuration to be a bit pokey, so I’ve juiced it up a bit (4 CPUs and 6G of memory).  I experimented with LiClipse and found that it was not responsive enough for my tastes and so I have decided to use Geany for the IDE.

 

geany on ubuntu
I am using Geany (IDE) and GitG (Git client) running on a Ubuntu VM hosted by Mac OS

Geany enables me to easily customize the build menu and I have found it to be very responsive within the VM.  I have also set up a Git repository on BitBucket and selected GitG for my Git client so that I don’t need to use the command line for commits.  I plan to publish the link to the repository as soon as I have the hand code working.  You can see from the screen shot above that I am working the foundational Servo and ServoController classes.

The use of a local and cloud-based Git repository helps to ensure I don’t lose my code but it doesn’t address how the code gets to the Raspberry Pi.  I experimented with several options including setting up the Raspberry Pi as an NFS server and finally settled on a shell script that uses the rsync command.

rsync -v -r -e ssh --delete --exclude ".*/" /home/mike/catkin_ws/src/inmoov pi@raspberrypi.local:/home/pi/catkin_ws/src

This command essentially does a difference comparison between the master source on Ubuntu and the source on the Raspberry Pi (you probably have to scroll the command to see the whole thing).  The command reconciles the differences and removes extra files from theRaspberry Pi and moving changes from Ubuntu to theRaspberry Pi (while ignoring the hidden directory for Git).  I plan to add the ROS commands to build the rest of code later but this is functional enough for now.

New Hardware

I’ve added a 7″ touch screen and case to the Raspberry Pi so that I will be able to monitor the robot standalone.  I’m currently using it to conveniently monitor what is going on in the Raspberry Pi.  See the parts list below for details.  I ran into a few problems with the display and case.

  1. I broke a part of the case during installation.  The case parts are made of plexiglass and cut with what appears to be a laser cutter. Two of the interlocking parts has no leeway in the dimensions and were too tight.  I broke one part but was able to get by.
  2. The display was upside down. Apparently, the display case was designed before the touch screen design was complete and the apparent lack of testing resulted in an upside down display.  To fix this issue, a software patch enabled a new configuration setting for the touchscreen to display upside down, negating the case design problem.
  3. Not enough clearance for USB power cables.  The Raspberry Pi is stacked on top of the touchscreen controller card and attached to the back of the touchscreen.  Power must be applied to the touchscreen controller first and then routed to the Raspberry Pi. There are several options to do this including connecting the two with a USB cable.  Unfortunately, the stress relieve plastic on a standard USB cable collides with the support structure of the case.  I had to cut a portion of the stress relief to make it fit.

I would not recommend this case for the above reasons plus it weighs quite a bit and would not be suitable for a mobile robot.  I’ll have to find an alternative to attach the touchscreen to the back of the robot later.

IMG_0994
Here is the Raspberry Pi with the touchscreen attached to a breadboard that houses the servo controller. The servos are installed in the right forearm.  The forearm parts have gone through quite a bit of finishing work.

Finishing the 3D Parts

I wanted to spiff up the look of the 3D parts and have done research and experimentation with different techniques.  Here is a side by side of my latest attempt.

IMG_0989
On the left is a white PLA plastic 3D print of the wrist parts with no finishing work. On the right is the ABS reprint (I said white damn it, not natural! sigh) after completing several finishing steps.  The difference is more pronounced in person.

I am using the following finishing process:

  1. Sand the part with 60, 120, 220 and then 320 grit sand paper.  A palm sander is very handy to help this get done.  This took many hours to complete.
  2. Fill in major gaps (e.g. between parts that are glued together) with a goopy mixture of acetone and extra ABS plastic soaked over night.  I made mine thicker than that described in to tutorial.  This goop creates a liquid filler that can be painted into crevices and defects.  Sand that down and repeat until all the gaps are filled.
  3. Wash and dry the part to remove the sanding dust
  4. Use the Cold Vapor Acetone Bath technique to smooth the surface of the ABS plastic. This will not work for PLA.  This is far less dangerous than techniques that heat the very flammable acetone.  This technique lines a paint can with acetone soaked paper towels.  The evaporating acetone condenses on the part surface and begins to melt the surface of the part.  After about an hour, I remove the paint can and let the part gas out for 24 hours.  I haven’t tried a longer duration for fear of melting the parts too much.  The results are pretty nice, however I found that the parts shown above still had a slightly rough feel possibly because I let the part gas out in my dusty garage or maybe I didn’t wash them enough.
  5. Apply a single coat of 30 minute epoxy.  I learned this technique here.

What’s Next?

I’ve got servo pulleys on order that will replace the defaults used by the InMoov project. I’ll get the hand assembled and tendons threaded.  I will also develop a ROS action server for the hand and wrist and write a Python GUI to control the hand on the touch screen.

Current Parts List

  1. [$40] Raspberry Pi 3 – Model B – ARMv8 with 1G RAM
  2. [$8] Assembled Pi T-Cobbler Plus – GPIO Breakout – for RasPi A+/B+/Pi 2/Pi 3
  3. [$15] Adafruit 16-Channel 12-bit PWM/Servo Driver – I2C interface – PCA9685
  4. [$2] 4700uF 10v Electrolytic Capacitor (for the Servo Driver board)
  5. [$15] Pimoroni Raspberry Pi 7″ Touchscreen Display Case – Noir
  6. [$80] Pi Foundation PiTFT – 7″ Touchscreen Display for Raspberry Pi
  7. [$5] Addicore Heat sinks for the Raspberry Pi 3
  8. [$330] 3D printing services for ABS plastic for the right hand, wrist and forearm
  9. [$20] sandpaper
  10. [$6] Metal paint can for the Cold Vapor Bath finishing techniqu
  11. [$5] Magnets to keep paper towel along the inside of the paint can
  12. [$10] 32 oz. of acetone
  13. [$20] various screws and super glue
  14. [$14] Pacer Technology Zpoxy, 30 minute set, 8 oz.