Friday, November 30, 2007

One step forward, two steps back:

Well I shot myself in the foot so to speak. I took my code to work to hammer out some of the details. This meant a lot of changes without being able to test them. Somehow I incorporated old code into the new code and contaminated both :(

Long story short, I'm going back to a reliable backup on 11/25/2007 which was before my last two posts. Thus, I'm progressing in the wrong direction. The good news it, I'm incorporating the code optimizations I made recently into the old code prior to me breaking out the functions into their own files. This way I can know they work before I change too many things at once.

On a good note, I've been mocking up a claw mechanism at lunch today. Saw a YouTube video of one I liked and fashioned a working model out of craft sticks.

Jay

Wednesday, November 28, 2007

Updates 11/28/2007:

I have successfully added RTOS (real time operating system) to my code. I'm using FreeRTOS (www.freertos.org) and it was relatively painless to incorporate. Some of the details that slowed me down:
  • The kernel timer uses Output Compare 1A which is the same I was using for the right motor PWM.
  • The port.c file configures the Timer 1 only for Output Compare 1A which overwrites all my settings for pwm I set in my motorInit code. As such, I changed the code in port.c to use |= when setting it's bits. This is the only kernel change I had to make.
  • I used to have all my code in one file. This is due to the fact that I just kept adding on to experimental code rather than formalize everything. Prior to the addition of the RTOS, I broke out functions in to separate files based on organization (motors, motion, and eventually sensors).
  • I was also using a lot of global variables (bad form I know but it's been fixed) in my one file. Rather than declare them extern in my new files (yes I tried that at first), I added functions to "get" and "set" key variables.
The benefits of this rework?
  • Now I can add a task to the list to execute without other functions having to call it or be aware.
  • No blocking (well except for serial, but it's the lowest priority) so now pauses (which used to nop for x milliseconds) just yield to other processes.
  • Now I can build behaviors that can layer on top of each other and turn them on or off via a monitor/command line program.
  • Sensors will run in their own task loops (like sonar) at set intervals which was more difficult to time with function calls especially when something new was added to the mix.
All in all I'm very pleased with this decision and I know it'll pay bigger dividends as my experimentation increases.

To do:
  • Wire up the 4 IRPD sensors and 2 bump switches.
  • Code a wall following behavior
  • Code a avoid behavior (to drive/navigate) around an obstacle while still trying to get to a target coordinate :)
Other updates:
  • I ordered a Lipo balancer for my battery. I got a great deal on the battery I use (4S 12C 33oomAH) and the replacement cost would be much more than I paid (thank you www.cheapbatterypacks.com) so I'm going to baby this one.
  • Through typos I ran my motors full speed using the new RTOS code. The measured speeds were 90 ticks/ 20ms. The movie below shows the motors going 18 ticks/20ms so I plan to increase the max speed a bit. For shorter runs the code will auto slow the bot anyway, but this make longer distance "shorter" ;)

Jay

Monday, November 26, 2007

Video of new code. Here is a short video of the robot now. The 4 commands I set are:
go 5 5
go -10 3
go 0 0
go 0 1

Friday, November 23, 2007

Updates for 11/23/2007

My code to command the robot to go x distance or turn x degrees works great .. .the issue is that due to slight differences in the motor speeds, the robot could be off by as much as an inch in a 2 foot span. So I decided to change the system over to a target based one.

The code is inspired/copied from David P Anderson's find_target and odometry code. I did add some tweaks of my own, and I've not yet started on using an RTOS.

I added a function that allows me to specify a target coordinate (x,y). Then I added find_target to my timer loop and call it every 30ms. The function looks at the distance and angle and commands the motors to those speeds. By using he distance left to set the speed I get nice fast and crisp movements. Before I added/fixed the code that your set the speeds proportionally, the robot was all over the map oscillating like crazy. Have a look at tonight's results.

The robot starts at 0,0. I then commanded it to go to 5,5 (that in inches BTW) and then to go to -10, 3. The pink and yellow lines are there for reference. The blue line is the plot of the X and Y coordinates reported by the robot. I have the printout function send data every 40ms (a bit too fast really) so the point markers are really close.



To dos:
1. Add the ability to create a point array from the drive pattern routine. Then have the robot traverse the array.
2. Figure out how to call the print routine every X ms. Because it uses an interrupt, it'll have to be outside the timer routine that I use for the PID and find_target.
3. Find a suitable and ready to go RTOS to port my code to. I'd rather quit fooling with ms timers and just run all the processes concurrently and have a central function call each when it's their turn.

Onward,
Jay