Category Archives: Robotics

Fritzing Part for a generic Dual Motor Controller

I needed a part for a generic motor driver when I was working in Fritzing the other day, and I couldn’t find one so I decided to create one.

Download the part here.

This motor driver consists of the basics needed for any dual motor controller:

  • VIN
  • GND
  • Motor 1 IN (+)
  • Motor 1 IN (-)
  • Motor 2 IN (+)
  • Motor 2 IN (-)
  • VCC
  • M1A
  • M1B
  • M2A
  • M2B

For example the DFRobot DRI0002 2A Dual Motor Controller or the Robokits RKI-1004 5A Dual Motor Driver.

Download the part here.

iohannes: a robot based off the Sparkfun IOIO

I will post something more thorough next week, but I wanted to get some pictures and a video up for the robot I’ve been working on.

The robot was inspired by the Sparkfun IOIO: a great little board that allows you to merge the world of Android phones with the world of hobby electronics. The result? A relatively cheap robotics platform with a huge range of possibilities.

Code is here: https://github.com/jessicaaustin/robotics-projects

Here’s the breakdown:

Base:
Lynxmotion Tri-Track chassis with two 12V DC motors — $220.95 (I actually got this used for $175)
Robokits RKI-1004 Dual Motor Driver (up to 5A) — $16 (thanks, Robot City Workshop!)
12.0V 2200mAh NiMh battery pack — $24

Electronics:
SparkFun IOIO — $49.95
HC-SR04 Ultrasonic distance sensor — $13.95
HTC Evo — “free”
9.6V 1800mA NiMh battery pack — $18

Total cost: $342.85

Currently the robot has two modes: a manual control mode and an autonomous, obstacle-avoidance mode. In manual mode you simply tell the motors to go forward, backwards, left or right. In obstacle-avoidance mode the robot will move forward until an obstacle is detected, at which point it will execute an “evasive maneuver” to clear the obstacle, and continue as before.

Code is here: https://github.com/jessicaaustin/robotics-projects

Next steps: get rosjava installed and integrated with the application. This will allow for remote control of the robot, plus remote computation like image processing of camera data.

Example code for Python OpenCV tutorials

Lately I’ve been getting into OpenCV. There are plenty of great tutorials out there, but I hate copy/pasting snippets of code from a blog post when I want to try something out.

So I started this repo on github: opencv-tutorial.

All the code runs! and has plenty of comments. I hope you find it useful as you go through these tutorials yourself. I also think the files are good starter templates for more complex scripts.

Moving from Stage 3 to Stage 4: laser and ranger

I recently moved to a new laptop, and in the process of installing player/stage, I moved from Stage 3.2.2 to Stage 4.0.1.

When I tried running a project of mine, however, I got the following error:

jaustin@navi:~/dev/player-bots/voronoibot$ robot-player cfg/voronoi.cfg
Registering driver
Player v.3.0.2

* Part of the Player/Stage/Gazebo Project [http://playerstage.sourceforge.net].
* Copyright (C) 2000 - 2009 Brian Gerkey, Richard Vaughan, Andrew Howard,
* Nate Koenig, and contributors. Released under the GNU General Public License.
* Player comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
* are welcome to redistribute it under certain conditions; see COPYING
* for details.

invoking player_driver_init()...
 Stage driver plugin init
 
 ** Stage plugin v4.0.1 **
 * Part of the Player Project [http://playerstage.sourceforge.net]
 * Copyright 2000-2009 Richard Vaughan, Brian Gerkey and contributors.
 * Released under the GNU General Public License v2. 
 
success
 Stage plugin:  6665.simulation.0 is a Stage world
stall icon /usr/share/stage/assets/stall.png 
 [Loading cfg/lab.world][Include pioneer.inc][Include map.inc][Include sick.inc]f: cfg/lab.world
 
err: Model type laser not found in model typetable (/build/buildd/stage-4.0.1/libstage/world.cc CreateModel)
err: Unknown model type laser in world file. (/build/buildd/stage-4.0.1/libstage/world.cc CreateModel)

The model type laser is defined in a couple of configs I have, like so:

driver
( 
  name "stage"
  provides [ "position2d:0" "laser:0" "speech:0" "graphics2d:0" "graphics3d:0" ]
  model "r0" 
) 
define sicklaser laser
(
  # laser-specific properties
  # factory settings for LMS200
  range_max 8.0 
  fov 180.0 
  samples 361
  
  #samples 90 # still useful but much faster to compute
  
  # generic model properties
  color "blue"
  size [ 0.156 0.155 0.19 ] # dimensions from LMS200 data sheet
) 

At first I thought I had screwed up my stage installation, and was at the point where I was going to try to install from source. But then! I saw this in the README.txt file that is bundled with Stage 4 source:

Version 4.0.0
————-

Major new release since worldfile syntax and API have both changed due
to a new unified ranger model. Laser model is now deprecated in favour
of the ranger. This follows a similar change in Player 3, where laser
interface support was deprecated but still in place due to lack of
Stage support. This release fixes that.

So since “laser” has been replaced by “ranger”, I replaced those words in my config files as well:

driver
( 
  name "stage"
  provides [ "position2d:0" "ranger:0" "speech:0" "graphics2d:0" "graphics3d:0" ]
  model "r0" 
) 
define sicklaser ranger
(
  # laser-specific properties
  # factory settings for LMS200
  range_max 8.0 
  fov 180.0 
  samples 361
  
  #samples 90 # still useful but much faster to compute
  
  # generic model properties
  color "blue"
  size [ 0.156 0.155 0.19 ] # dimensions from LMS200 data sheet
) 

And it worked!

Remotely controlled pan/tilt camera unit

 

One of my colleagues at work works remotely, and we make good use of Skype and gchat to communicate with each other. However, when he’s calling in and talking to a big group, it can be hard for him to see everyone at once unless we constantly rotate the laptop around to focus on whoever is talking. Thus I thought it would be neat for him to able to control the movement of a webcam remotely.
I was inspired by seeing this pan/tilt bracket from SparkFun.com. Using an Arduino would make things very easy, since it has the Servo library and built-in serial communication. As for the “remotely controlled” part, I set up an apache webserver on the local machine (apache http server is actually already installed if you’re running OSX, more on that later) that would use a CGI script to send commands to the Arduino via a serial connection.

Parts List

Assembling the pan/tilt unit

Assembly was pretty straightforward, using the instructions on SparkFun’s product page.

 

I used balsa wood (available at hardware stores and art supply stores–that is, pretty much everywhere) and wood glue to provide a mount for the pan servo. This is probably the cheapest and most low-tech approach, but you could of course use any material you like.

 

For mounting the camera, I pulled the camera part from the base and then screwed this on to the top of the pan/tilt bracket. Again, this will depend on your camera. Some cameras, like the Microsoft LifeCam VX-3000 Webcam, have screw-on bases and thus make this part pretty easy.

Arduino connections

I wanted to keep things modular, so to connect the servos to the Arduino I installed 2 3-pin male headers on a PC board. I wired wires going from the servo signal pins to Arduino pins 8 and 9, and from the power pins to Arduino pins GND and +5V. I also threw in an LED in parallel with the power as an extra indicator that the board was plugged in and powered.

Arduino Code

githubblack Code available at Github here: https://github.com/jessicaaustin/robotics-projects/tree/master/pan-tilt-unit

Once you’ve uploaded the following code to your Arduino, you should be able to control the pan/tilt unit via the Serial Monitor.

#include <Servo.h> 
 
Servo pan_servo;
Servo tilt_servo;
int incomingByte;
 
void setup()
{
 // attach the servos and startup the serial connection
 pan_servo.attach(9);
 tilt_servo.attach(8);
 Serial.begin(9600);
 resetAll();
}
 
void loop()
{
 
 // check to see if something was sent via the serial connection
 if (Serial.available() > 0) {
 incomingByte = Serial.read();
 
 // move the servos based on the byte sent
 if (incomingByte == 'e') {
 moveServo(tilt_servo, 1);
 } else if (incomingByte == 'x') {
 moveServo(tilt_servo, -1);
 } else if (incomingByte == 'd') {
 moveServo(pan_servo, 1);
 } else if (incomingByte == 's') {
 moveServo(pan_servo, -1);
 } else if (incomingByte == 'r') {
 resetAll();
 } else if (incomingByte == '/') {
 Serial.println("pan: " + pan_servo.read());
 Serial.println("tilt: " + tilt_servo.read());
 }
 }

}
 
// move the servo a given amount
void moveServo(Servo servo, int delta) {
 int previousValue = servo.read();
 int newValue = previousValue + delta;
 if (newValue > 180 || newValue < 30) {
 return;
 }
 servo.write(newValue);
}
 
// put the servos back to the "default" position
void resetAll() {
 reset(pan_servo);
 reset(tilt_servo);
}
 
// put a servo back to the "default" position (100 deg)
void reset(Servo servo) {
 
 int newPos = 130;
 int previousPos = servo.read();
 if (newPos > previousPos) {
 for (int i=previousPos; i<newPos; i++) {
 servo.write(i);
 delay(15);
 }
 } else {
 for (int i=previousPos; i>newPos; i--) {
 servo.write(i);
 delay(15);
 }
 }
 
}

Controlling the Arduino via a script

I used todbot‘s arduno-serial.c program to control the Arduino via the command line.

Get arduino-serial.c and test it out:


wget http://todbot.com/arduino/host/arduino-serial/arduino-serial.c

gcc -o arduino-serial arduino-serial.c

# test moving the camera up and to the right

./arduino-serial -b 9600 -p /dev/tty.usbmodem3d11 -s dddddddddddddddeeeeeeeeeeeeeee

Running the script via Apache HTTP Server

At this point, someone could ssh in to the computer running the camera and control it via the command line, but I wanted to have a slightly more sophisticated interface. I decided to go with a simple jQuery-powered web page that hits a CGI script served up by apache. (Note: of course, if you want people to be able to control the camera from outside your local network, you’ll need a static IP address for your machine. In that case, you should probably also make sure you set up basic authentication for your apache server.)

If you’re running OSX, apache is already installed. You can start it up by running sudo apachectl start, the config is located at /etc/apache2, and the DocumentRoot points to /Library/WebServer/ by default.

cd /Library/Webserver/CGI-Executables
vim pan-tilt.cgi

pan-tilt.cgi is the following ruby script:

#!/opt/local/bin/ruby

query_string=`echo $QUERY_STRING`

if query_string.length != 0
`/opt/local/bin/arduino-serial -b 9600 -p /dev/tty.usbmodem3d11 -s #{query_string}`
result=`echo $?`
result=result.gsub(/n/,"")
end

print "Content-type: application/jsonnn"
print "{"result": "#{result}"}n"

Finally, create the web page:

cd /Library/Webserver/Documents
vim pan-tilt.html

pan-tilt.html:


<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>// <![CDATA[
            // send the input to the cgi script
            // note: sending 3x the input for every keypress, to make the movement smoother
            var submitInput = function(input) {
                $.post("/cgi-bin/pan-tilt.cgi?" + input + input + input);
            };

            // submit input when someone presses a key down
            $(document).keydown(function(event) {
                console.log(event.keyCode);
                switch(event.keyCode) {
                   case 82:
                    submitInput('r');
                    break;
                  case 83:
                    submitInput('s');
                    break;
                  case 68:
                    submitInput('d');
                    break;
                  case 69:
                    submitInput('e');
                    break;
                  case 88:
                    submitInput('x');
                    break;
                  case 37:
                    submitInput('s');
                    break;
                  case 39:
                    submitInput('d');
                    break;
                  case 38:
                    submitInput('e');
                    break;
                  case 40:
                    submitInput('x');
                    break;
                  default:
                }
            });
        
// ]]></script>

&nbsp;
<h1>Pan/Tilt Camera Control</h1>
<div>
<table>
<tbody>
<tr>
<td></td>
<td>&amp;amp;uarr;</td>
<td></td>
</tr>
<tr>
<td>&amp;amp;larr;</td>
<td>r</td>
<td>&amp;amp;rarr;</td>
</tr>
<tr>
<td></td>
<td>&amp;amp;darr;</td>
<td></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td></td>
<td>e</td>
<td></td>
</tr>
<tr>
<td>s</td>
<td>r</td>
<td>d</td>
</tr>
<tr>
<td></td>
<td>x</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div style="clear: left;">
todo: add security</div>

Testing

At this point you should be able to go http://localhost/pan-tilt.html and control the camera from there. Check out the video below!