import os
indir = 'c:\\datafilepath\\'
for filename in os.listdir(indir):
if filename.startswith("xyz_"):
newname = filename.replace("xyz_","abc_")
try:
os.rename(indir + filename, indir + newname)
print "[NEW]", filename, "-->", newname
except:
print "[OLD]", filename, "-->", newname
Python
Not much progress to report. My compass module seems to have died, probably due to the fact I was feeding it 5V instead of the required 3.3V… Never mind, new module ordered.
I’ve added a new level to the robot and now looks neater. Here are a couple of photos:
With a camera (placeholder – not really attached):

Without camera:

Arduino, Gadgets, Projects, Python, Videos, robotics / Comments Off
As promised, here is a video I’ve put together of the RC mode.
Robot Challenge 008 from Arkadian.Eu on Vimeo.
Also as promised, here is the Python code which, when run on a Raspberry Pi, it receives OSC signals from my iPad, interprets them and gets the Arduino board to perform the required action.
This is very rough, and doesn’t not include the code for clockwise and anticlockwise rotation (as I made the addition directly on the raspberry and it’s now out of battery). Clearly, this requires the simpleOSC and pyFirmata libraries to be installed. Most of the code you see here is just a quick mashup, based on examples from the SimpleOSC and pyFirmata libraries. For me the key is that it works!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | import OSC, time, threading, os, serial import pyfirmata from pyfirmata import * from boards import BOARDS class ArduinoMega(Board): """ A board that will set itself up as an Arduino Mega. """ def __init__(self, *args, **kwargs): args = list(args) args.append(BOARDS['arduino_mega']) super(ArduinoMega, self).__init__(*args, **kwargs) def __str__(self): return 'Arduino Mega %s on %s' % (self.name, self.sp.port) # Adjust that the port match your system: PORT = '\\.\COM4' #On Windows #PORT = '/dev/ttyACM0' #On RPi # Creates a new board board = ArduinoMega(PORT) # ################################################################## def engine(path, tags, args, source): print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source file = "Car_Start_2.mp3" print "starting engine" #os.startfile(file) # # ################################################################## def rcMode(path, tags, args, source): print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source print "Switching to RC mode" #os.startfile(file) # ################################################################## def autoMode(path, tags, args, source): print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source print "Switching to AUTO mode" #os.startfile(file) # ################################################################## def questMode(path, tags, args, source): print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source print "Switching to QUEST mode" #os.startfile(file) # LIGHTS SECTION # ################################################################## PIN2 = board.get_pin('d:2:p') def lightR(path, tags, args, source): PIN2.write(1 - args[0]) print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source # ################################################################## # ################################################################## PIN3 = board.get_pin('d:3:p') def lightG(path, tags, args, source): PIN3.write(1- args[0]) print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source # ################################################################## # ################################################################## PIN4 = board.get_pin('d:4:p') def lightB(path, tags, args, source): PIN4.write(1-args[0]) print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source # ################################################################## # ################################################################## PIN13 = board.get_pin('d:13:p') def lightFloor(path, tags, args, source): PIN13.write(1 - args[0]) print path, "@TAGS", tags, "@ARGS", args, "@SOURCE", source # ################################################################## # MOTOR SECTION # ################################################################## PINA = board.get_pin('d:8:s') PINB = board.get_pin('d:9:s') PINC = board.get_pin('d:10:s') PIND = board.get_pin('d:11:s') def motor(aa,bb,cc,dd): print aa, bb, cc, dd if aa==1: PINA.write(20) if aa==-1: PINA.write(138) if aa==0: PINA.write(91) if bb==1: PINB.write(20) if bb==-1: PINB.write(138) if bb==0: PINB.write(91) if cc==1: PINC.write(20) if cc==-1: PINC.write(138) if cc==0: PINC.write(91) if dd==1: PIND.write(20) if dd==-1: PIND.write(138) if dd==0: PIND.write(91) def xmotor(path, tags, args, source): direction = path.split("/")[2] print "PIN", path.split("/")[2], "@TAGS", print tags, "@ARGS", args, "@SOURCE", source if args[0]==0: motor(0,0,0,0) else: if direction == "nn" : motor(1,0,-1,0) if direction == "ne" : motor(1,1,-1,-1) if direction == "ee" : motor(0,1,0,-1) if direction == "se" : motor(-1,1,1,-1) if direction == "ss" : motor(-1,0,1,0) if direction == "sw" : motor(-1,-1,1,1) if direction == "ww" : motor(0,-1,0,1) if direction == "nw" : motor(1,-1,-1,1) if direction == "freeze": motor(0,0,0,0) # ################################################################## # ################################################################## def user_callback(path, tags, args, source): user = ''.join(path.split("/")) print "cb-->", path, "@TAGS", tags, print "@ARGS", args, "@SOURCE", source def quit_callback(path, tags, args, source): #pass # don't do this at home (or it'll quit blender) global run run = False # tupple with ip, port receive_address = "192.168.0.47", 7110 # OSC Server. there are three different types of server. #s = OSC.OSCServer(receive_address) # basic s = OSC.ThreadingOSCServer(receive_address) # threading ##s = OSC.ForkingOSCServer(receive_address) # forking s.addDefaultHandlers() s.addMsgHandler( "/1/start", engine) s.addMsgHandler( "/1/rc", rcMode) s.addMsgHandler( "/1/auto", autoMode) s.addMsgHandler( "/1/quest", questMode) s.addMsgHandler( "/1/nn", xmotor) s.addMsgHandler( "/1/ne", xmotor) s.addMsgHandler( "/1/ee", xmotor) s.addMsgHandler( "/1/se", xmotor) s.addMsgHandler( "/1/ss", xmotor) s.addMsgHandler( "/1/sw", xmotor) s.addMsgHandler( "/1/ww", xmotor) s.addMsgHandler( "/1/nw", xmotor) s.addMsgHandler( "/1/freeze", xmotor) s.addMsgHandler( "/2/red", lightR) s.addMsgHandler( "/2/green", lightG) s.addMsgHandler( "/2/blue", lightB) s.addMsgHandler( "/2/grey", lightFloor) s.addMsgHandler( "/ping", user_callback ) s.addMsgHandler( "/quit", quit_callback ) # define a message-handler function for the server to call. def printing_handler(addr, tags, stuff, source): print "---" print "received new osc msg from %s" % OSC.getUrlStr(source) print "with addr : %s" % addr print "typetags %s" % tags print "data %s" % stuff print "---" s.addMsgHandler("/print", printing_handler) # adding our function # just checking which handlers we have added print "Registered Callback-functions are :" for addr in s.getOSCAddressSpace(): print addr # Start OSCServer print "\nStarting OSCServer. Use ctrl-C to quit." st = threading.Thread( target = s.serve_forever ) st.start() try : while 1 : pass except KeyboardInterrupt : print "\nClosing OSCServer." s.close() print "Waiting for Server-thread to finish" st.join() ##!!! print "Done" |
Lines 150-173 are linked to my touchOSC template. For instance “nn” stands for North, “ne” for North East etc…
The TouchOSC editor allows you to give your buttons friendly names. The created template itself, while suffixed with a “.touchosc”, is simply a zipped xml file (in case you want to really fine-tune it!). The editor does a great job – pity it doesn’t work with Android…
Lines 116-124 control the wheels. Basically, 1 is clockwise, -1 is acti-clockwise and 0 is break. The list in motor(1,0,-1,0) includes a value for each one of my four motors. The two rotation functions missing here, simply have motor(1,1,1,1) and motor(-1,-1,-1,-1).
The engine function (line 28) will be playing an mp3 with the sound of a car engine starting, when the virtual engine key is turned. It works fine on Windows and it should be quite easy to get it to work on RPi too.
Arduino, Linux, Projects, Python, examples, robotics / Comments Off
I had a productive couple of days. Arkadian AV-1 is now operational as a remote control vehicle.
Arduino
I’m using the StandardFirmata library on the Arduino Mega 2560, with no modifications whatsoever. It was by far the easiest way to get RaspberryPi to control the 4 motors, receive feedback from the 4 sensors (on order from Sparkfun, should be here soon) and have the ability to switch on and off the lights on the robot.
RaspberryPi
The RaspberryPi is loaded with Ladyada’s RPi distro, as it had the latest python library and a few other things that I’m planning on using later on. I have added the PyFirmata library (to control the Arduino) and the OSC library (as described previously) to receive instructions from the OSC pad.
TouchOSC
I have been using TouchOSC to create the remote control interface. My original plan was to use the Nexus tablet to control the robot. The problem is that TouchOSC is a bit behind when it comes to Android. The app is available to buy, but you cannot upload your own templates, which makes it pretty useless. I’ll be using an iPad for now, but I hope they get the android version sorted soon.
Here is my latest layout (first page):

The two buttons under the “Quest”, are for clockwise and anti-clockwise rotation.
Vehicle is very responsive and drives really well. Orientation gets a bit tricky for the human brain if the rotation buttons are not used, but for the “Quest Mode” this will really be ideal.
I’ll post the code, photos and a video tomorrow.
Next week, I’ll finish off the sensors (proximity and compass), tidy up the cables and put everything in a more permanent position. My code needs a bit of tidying up too; it’s really a mess right now (but, hey, it works!).
Today I have quite a bit of work to do on this project. By the end of the day, I should have a fully functional remote control vehicle.
Earlier this morning, I finished the joystick. I will be using a Nexus 7 with touchOSC as my joystick and I put together the following layout:

Rotating the “Start” icon to “Full” will wake up the robot.
The three toggle switches underneath will simply be switching between RC mode, Auto mode (just avoiding stuff) and Quest mode (which I will be able to finetune a bit better, for our competition).
The navigation buttons on the right will be doing what you expect: North, East, South, West and their combinations. The red button in the middle will be the stop button.
When the robot is ready, I will add additional pages to the remote control to increase the number of options available to the user (e.g. speech, reactions, specific moves, etc).
There is a great OSC Python library (PyOSC) which makes interfacing the Nexus with python very easy. While OSC was created to control music, you can make it do whatever you want in Python, which is really cool.
By the way, while I’ll be using a Nexus 7 tablet, it’s worth mentioning that TouchOSC works on iPhones and iPads too. Excellent app!
Today I worked on a few necessary but rather boring parts of the construction.
I got the Sparkfun compass module from Proto-Pic and spent a few hours setting it up and calibrating it.
I used the HMC5883L Arduino library example to generate the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <Wire.h> #include <HMC5883L.h> HMC5883L compass; int error = 0; void setup() { Serial.begin(9600); Wire.begin(); // Start the I2C interface. compass = HMC5883L(); // Construct a new HMC5883 compass. error = compass.SetScale(1); // Set the scale of the compass. Was 1.3 in the original error = compass.SetMeasurementMode(Measurement_Continuous); } // Our main program loop. void loop() { MagnetometerRaw raw = compass.ReadRawAxis(); float heading = atan2(raw.YAxis, raw.XAxis); if(heading < 0) heading += 2*PI; // Check for wrap due to addition of declination. if(heading > 2*PI) heading -= 2*PI; int headingDegrees = int(heading * 180/M_PI); Serial.println("@|"+ String(headingDegrees) + "|#"); } |
I wasn’t getting the readings I wanted though. I was hoping to get 0 for North, 90 for East, 180 for South and 270 for West, with an offset or something.This is what I was getting: N=330, E=90, S=200 and W=265, which meant that the distances N-E, E-S, S-W, W-N were not 90 and were not equal. Not sure why, but for my project it doesn’t make much difference, given I’ll be using a Raspberry Pi for the brain.
I wrote the following python script for calibrating the arduino results:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import serial from time import sleep def xmap(OldValue, OldMin, OldMax, NewMin, NewMax): t = ((OldValue - OldMin) * (NewMax - NewMin)) t = t / (OldMax - OldMin) + NewMin return t ser = serial.Serial(2, 9600, timeout=0) data = "" while True: try: data = data + ser.read(9999) if data.find("@")>-1 and data.find("#")>-1: data = data.strip(' \t\n\r') x = data.split("@")[1] x = x.split("#")[0] x = x.split("|")[1] x = (float(x)/10 + 3)%36 if 0<=x<12: y = xmap(x,0,12,0,90) if 12<=x<23: y = xmap(x,12,23,90,180) if 23<=x<29.4: y = xmap(x,23,29.4,180,270) if 29.4<=x<36: y = xmap(x,29.4,36,270,360) print int(round(y,0)) data = "" except: pass ser.close() |
The above script actually gives very acceptable results. If you use it, just ensure you feed the xmap function the information you observe in your compass.
In the final project, the compass module will be detecting the rotation of the robot and report it to the main python script. if the robot has rotated by mistake then the main python script will make the necessary adjustments.
On the battery front: I received the battery I ordered from VEX. Originally I was thinking of using sealed led acid batteries, but I didn’t want to use high voltage on the motors. Tomorrow I’ll time the battery to see how long it lasts when it powers 2 motors together.
I think I’m now ready to build the body of the robot and setup the main Python script on the Raspberry Pi for the RC mode. When that’s all done, I will add the proximity sensors and the autonomous mode on the main Python script.
The plan is also to buy an Arduino Mega, as I will need 8 digital ports for the motors, 2 ports for the compass,