by l3v3rz » Tue May 04, 2010 12:25 am
by l3v3rz
Tue May 04, 2010 12:25 am
I have a demo of auto-balance written in Lisp work - albeit very simple. It moves the arms to counteract the force being applied, but it can easily be extended as its data driven, to move any combination of servos. It requires custom firmware to get a reasonable speed.
When running on the standard firmware you have to switch between the two modes, PC remote and Direct control (DC) mode. In DC mode you can control the servos and in PC mode you can read the sensors, but to switch between the modes takes time. What's worse is that if you switch too early you get bad data sent, or it misses requests. It takes around 100 ms to switch modes reliably and you need to to twice each cycle i.e. (read sensor, switch, update servos, switch) So the fast cycle time is around 200-250ms or 5 Hz. I have written a custom piece of firmware called DC mode plus that enable the sensors to be read without switching modes. It does this by hijacking servo 30. read positions on that servo will return various sensor data. Its speed is around 40-50ms or 20-22Hz Hz
[Edit: the speed is limited by L# - writing in C# improves the speed of the loop to sub 10ms/+100Hz]
I have a dynamic balance demo working. The LISP code is quite straight forward, details and links at the end
- Code: Select all
(def calibrateXYZ ()
(= xyz (readAcc))
(= x (car xyz)) (= y (cadr xyz)) (= z (car (cddr xyz)))
(= gx x)
(= gy y)
(= gz z)
(prn "Calibrated: " gx " " gy " " gz)
)
;reading Z value - by reading position of Servo 30 (with parameter "1")
(def getZ ()
"DCMP - quicker if we just want Z"
(.wckReadPos wck 30 1) ; get y & Z
(with (z (nth (.respnse wck) 1))
(= z (if (> z 127) (- z 256) z))
)
)
(def bt4 () "dcm plus mode - high speed"
(if (not (bound 'DCMODEPLUS)) (err "load DCMP.lisp"))
(standup)
(calibrateXYZ)
(= base (getallServos 15))
(pause)
(try
(while (not (Console.keyavailable))
(= c1 (- (getZ) gz))
(= dz (rmatch c1 Z2))
(if (or dz)
(do
(= nxt (mapcar + base dz))
(try (.SyncPosSend wck 15 4 (toarray nxt) 0) (do (pr "overflow") (prl nxt)) null)
(= base nxt)
)
)
)
(prn "Exception caught")
null
)
(standup)
)
Note: This is only some of the code - the rest will be posted on line. It only works with customer firmware
How it works: Its extending the arms based on the offset of the Z value. The amount of offset is determined by rmatch - which looks for ranges and returns an array which is then added to the current position. SynchPosSend then updates the servo.
Edit: Latest version of balance code - available here
http://code.google.com/p/robobuildervc/ ... lance.lisp
Download stable version:
http://robobuildervc.googlecode.com/files/balance.lisp
Function to call is (bt4)
I have a demo of auto-balance written in Lisp work - albeit very simple. It moves the arms to counteract the force being applied, but it can easily be extended as its data driven, to move any combination of servos. It requires custom firmware to get a reasonable speed.
When running on the standard firmware you have to switch between the two modes, PC remote and Direct control (DC) mode. In DC mode you can control the servos and in PC mode you can read the sensors, but to switch between the modes takes time. What's worse is that if you switch too early you get bad data sent, or it misses requests. It takes around 100 ms to switch modes reliably and you need to to twice each cycle i.e. (read sensor, switch, update servos, switch) So the fast cycle time is around 200-250ms or 5 Hz. I have written a custom piece of firmware called DC mode plus that enable the sensors to be read without switching modes. It does this by hijacking servo 30. read positions on that servo will return various sensor data. Its speed is around 40-50ms or 20-22Hz Hz
[Edit: the speed is limited by L# - writing in C# improves the speed of the loop to sub 10ms/+100Hz]
I have a dynamic balance demo working. The LISP code is quite straight forward, details and links at the end
- Code: Select all
(def calibrateXYZ ()
(= xyz (readAcc))
(= x (car xyz)) (= y (cadr xyz)) (= z (car (cddr xyz)))
(= gx x)
(= gy y)
(= gz z)
(prn "Calibrated: " gx " " gy " " gz)
)
;reading Z value - by reading position of Servo 30 (with parameter "1")
(def getZ ()
"DCMP - quicker if we just want Z"
(.wckReadPos wck 30 1) ; get y & Z
(with (z (nth (.respnse wck) 1))
(= z (if (> z 127) (- z 256) z))
)
)
(def bt4 () "dcm plus mode - high speed"
(if (not (bound 'DCMODEPLUS)) (err "load DCMP.lisp"))
(standup)
(calibrateXYZ)
(= base (getallServos 15))
(pause)
(try
(while (not (Console.keyavailable))
(= c1 (- (getZ) gz))
(= dz (rmatch c1 Z2))
(if (or dz)
(do
(= nxt (mapcar + base dz))
(try (.SyncPosSend wck 15 4 (toarray nxt) 0) (do (pr "overflow") (prl nxt)) null)
(= base nxt)
)
)
)
(prn "Exception caught")
null
)
(standup)
)
Note: This is only some of the code - the rest will be posted on line. It only works with customer firmware
How it works: Its extending the arms based on the offset of the Z value. The amount of offset is determined by rmatch - which looks for ranges and returns an array which is then added to the current position. SynchPosSend then updates the servo.
Edit: Latest version of balance code - available here
http://code.google.com/p/robobuildervc/ ... lance.lisp
Download stable version:
http://robobuildervc.googlecode.com/files/balance.lisp
Function to call is (bt4)
Last edited by l3v3rz on Sat May 08, 2010 10:56 am, edited 8 times in total.