Back in college (yeah, those were the days) I was in a hackathon with a couple other guys. What we decided to do was to build a robot platform out of a wheelchair. While researching for this article I found out that we are not the only ones to do that with this style wheelchair, but I think we implement the most functionality.
We chose to interface with the existing controller since it already does what we want. Power was not an issue as you can see the battery voltage is brought right to the controller and helpfully labeled. The inputs and outputs were:
- in: power state (using an analog pin and LED)
- in: power switch (manual control passed through our code)
- in: speed up switch (manual control passed through our code)
- in: speed down switch (manual control passed through our code)
- out: power relay (controls the power switch on the pcb)
- out: speed up (controls the speed up switch on the pcb)
- out: speed down (controls the speed down switch on the pcb)
- out: speed/speed2 (sets the position of the virtual analog stick)
- out: turn/turn2 (sets the position of the virtual analog stick)
In addition to these we also used the usb-serial converter on the serial lines to communicate with the laptop. Through incredible self restraint we didn’t implement the horn functionality.
Here is our modified controller. You can see the joystick connection is modular so we could probe the lines in circuit before connecting our controller to them. That proved absolutely essential because this controller is a little smarter than you might imagine. The joystick has 2 separate potentiometers for each axis which we drive with identically controlled pins on the arduino pro mini. The controller also throws an error when the virtual joystick goes too far out of the range of the mechanical joystick. we have capped these pwm outputs using a helpful map function:
speedOut = map(speedVar, 0, 1023, 50, 210);
turnOut = map(turnVar, 0, 1023, 50, 210);
This allows us to work in 1024 increments of turn and speed while knowing we won’t trip the internal protections against an unplugged or shorted joystick.
The code written here is non-blocking and runs in a continuous loop. It checks to see if any switch is pressed and does the corresponding command if needed. It then checks to see if there are any serial commands that need executing (I’ve used this serialcommand library before). Once it executes any needed commands it sets the virtual joystick based on the internal variables stored for the position. It checks to see if it has been more than 3000 loops since the last command given, and if so it re-centers the joystick (a crashed python program sent it driving off since we no longer had a spring return joystick). The commands it takes are :
- TURN [0-1023]
- SPEED [0-1023]
- SPEEDLEVEL [-1,1]
- POWER [0,1]
Turn and speed set the joystick position (512 is center), speed level pushes the relevant up or down speed button (which just scales the joystick, increasing or decreasing the max speed), and power turns on or off the wheelchair controller (not our controller). Since these commands just push buttons it is not possible to know if you are at the max or minimum speed (we did not read any more LEDs, but you could). We did, however, implement the power LED. When you want to turn on the controller it checks to see if it is already on and then sets the joystick to center, presses and holds the button for 100ms, then releases the button. This is also part of a safety interlock to keep the wheelchair form just taking off when turned on.
The power connector passes 12V for charging and is labeled as such. I didn’t do that part, I promise.
The next bit of software I didn’t write. We interfaced this robot with a laptop and a kinect for doing depth mapping. You can see that code here and your interpretation is about as good as mine, but I will try. I will say that this code is sending speed, turn, and power commands as one even though I am processing them individually. The speed up and speed down are not used (we used the manual switches in the robot). The logic in the python code looks at a center depth, a left and right side. If the robot is clear to move forward it does, else it goes left, else it goes right, else it backs up. The behavior is very simple and the movements around our oval-shaped hallway were interesting. There’s enough lash and randomness in the mechanics of the wheelchair to make sure it never gets stuck even without more complex self-correcting code.
That’s it. How to make a wheelchair based robotics platform and how to interface that low-level arduino control to a python script.
pictures are here.
code is here (forked in case he wants to bring it down)