by l3v3rz » Fri Dec 18, 2009 12:33 am
by l3v3rz
Fri Dec 18, 2009 12:33 am
Day18 - 7 Days to go
================
Plotting data in real time from your Robobuilder robot. Todays' post uses the routines created over the last two days to display graphics to output of the values of the accelerometer.
First its important to know if we have a connection to the robot. So the following code does a couple of tests
serial? and
remote? to see a connection has been made. They look to see if the global variables exist;
sport - which is the handle for the serial port, and
pcr the handle to the RobobuilderLib.PCremote class. The functions return the name of a colour which is then passed to a display function called
status.
- Code: Select all
(def serial? () (if (and (bound 'sport) (.isopen sport)) "Green" "Red"))
(def remote? () (if (and (bound 'pcr) (is "Green" (serial?))) "Green" "Red"))
(def status(x y txt c)
(= pen (new "Pen" (Color.FromName c)))
(.fillellipse g (.Brush pen) (- x 10) (- y 6) 14 14)
(= pen (new "Pen" (Color.FromName "Black")))
(.drawellipse g pen (- x 10) (- y 6) 14 14)
(.drawstring g txt font (.Brush pen) (new "PointF" (+ x 10) (- y 4)))
)
(def demo2(f g)
(createwindow "status" 250 250)
(.show f)
(.clear g (Color.FromName "White") )
(status 205 8 "Serial" (serial?) )
(status 160 8 "Remote" (remote?) )
)
If you type (demo2) a window will appear with a couple of red indicators showing not connected yet. You will have need to use the functions created from the last few days post. The function
status creates the filled circles using the fillelipse rather than the drawelipse method. Also the
bound? function enables to test to see if a variable has been created or set. It returns false if it doesn't exist. very useful!
To debug code its simpler not to have the robot connected, so I simulate the accelerometer using random data. The function
readAcc will return the '(X Y Z) values as a list and so by replacing this with a function that generates random numbers means the plot routine can be tested easily. The random numbers are generated using the C# class Random which when instantiated returns random number using the .Next method. (.next r 50) generates a random integer between 0-50. The function then subtracts 25 to generate random number between -25 and +25. It does this 3 times to create a list i.e. '(10 -5 20).
- Code: Select all
(= r (new "Random"))
(def readAcc ()
(list (- (.next r 50) 25) (- (.next r 50) 25) (- (.next r 50) 25) ))
;replace with this for actual sensor reading
;(def readAcc () (.readXYZ pcr))
Now for the main code for
plotaccel. Its very similar to the
anim routine. It displays the values but also displays the serial status - showing if the robot is connected - although the serial port can't seem to detect if you turn the robot off!
- Code: Select all
(def plotaccel (r)
"Plot - sample rate rHz"
(= r (/ 1.0 r))
(with (acc 0)
(createwindow "Accelerometer Demo" 250 250)
(.show form1)
(= n 1)
(while (< n 1000)
(= acc (readAcc))
(scope (car acc) (cadr acc))
(status 205 8 "Serial" (serial?))
(status 160 8 "Remote" (remote?))
(drawlist g '((-125 40) (125 40)) "Black") ; limit
(drawlist g '((-125 -40) (125 -40)) "Black") ; limit
(= history (cons (list (car acc) (cadr acc)) history))
(= h (list (car history) (cadr history) (car (cdr (cdr history)))))
(drawlist g h "Blue")
(sleep r)
(= n (+ 1 n))
(exit?)
)
(.hide form1)
)
)
To run simply enter (plotaccel 5) the value 5 represents the frequency the accelerometer is read and plotted. 5Hz works well. If the routine works with dummy
readAcc routine then load Day7.lisp and (run_robobuilder) and connect to the COM port. Replace the
readAcc with a function to read the accelerometer as described in earlier post (day 9). The
scope function actually draws the axes and plot the point. Its is passed in this example X and Y values. But you could pass any 2 of the three values. The
plotaccel function also displays a couple of boundary lines - these represent the tipping points (or could do) of the robot. The idea would be when the accelerometer values cross the line would be the point to activate a balance routine for instance. When running move your robobuilder bot around and what the circle move - its great fun!
Not only - but also .. There was a question on another thread about read Joystick on windows machines, L# can do this as well and the outline Ive posted here reference the Joystick note (
http://robosavvy.com/forum/viewtopic.php?p=23913#23913)
Next for something a bit different. Developing the power of Lisp/L#
Tomorrow: Property lists
Day18 - 7 Days to go
================
Plotting data in real time from your Robobuilder robot. Todays' post uses the routines created over the last two days to display graphics to output of the values of the accelerometer.
First its important to know if we have a connection to the robot. So the following code does a couple of tests
serial? and
remote? to see a connection has been made. They look to see if the global variables exist;
sport - which is the handle for the serial port, and
pcr the handle to the RobobuilderLib.PCremote class. The functions return the name of a colour which is then passed to a display function called
status.
- Code: Select all
(def serial? () (if (and (bound 'sport) (.isopen sport)) "Green" "Red"))
(def remote? () (if (and (bound 'pcr) (is "Green" (serial?))) "Green" "Red"))
(def status(x y txt c)
(= pen (new "Pen" (Color.FromName c)))
(.fillellipse g (.Brush pen) (- x 10) (- y 6) 14 14)
(= pen (new "Pen" (Color.FromName "Black")))
(.drawellipse g pen (- x 10) (- y 6) 14 14)
(.drawstring g txt font (.Brush pen) (new "PointF" (+ x 10) (- y 4)))
)
(def demo2(f g)
(createwindow "status" 250 250)
(.show f)
(.clear g (Color.FromName "White") )
(status 205 8 "Serial" (serial?) )
(status 160 8 "Remote" (remote?) )
)
If you type (demo2) a window will appear with a couple of red indicators showing not connected yet. You will have need to use the functions created from the last few days post. The function
status creates the filled circles using the fillelipse rather than the drawelipse method. Also the
bound? function enables to test to see if a variable has been created or set. It returns false if it doesn't exist. very useful!
To debug code its simpler not to have the robot connected, so I simulate the accelerometer using random data. The function
readAcc will return the '(X Y Z) values as a list and so by replacing this with a function that generates random numbers means the plot routine can be tested easily. The random numbers are generated using the C# class Random which when instantiated returns random number using the .Next method. (.next r 50) generates a random integer between 0-50. The function then subtracts 25 to generate random number between -25 and +25. It does this 3 times to create a list i.e. '(10 -5 20).
- Code: Select all
(= r (new "Random"))
(def readAcc ()
(list (- (.next r 50) 25) (- (.next r 50) 25) (- (.next r 50) 25) ))
;replace with this for actual sensor reading
;(def readAcc () (.readXYZ pcr))
Now for the main code for
plotaccel. Its very similar to the
anim routine. It displays the values but also displays the serial status - showing if the robot is connected - although the serial port can't seem to detect if you turn the robot off!
- Code: Select all
(def plotaccel (r)
"Plot - sample rate rHz"
(= r (/ 1.0 r))
(with (acc 0)
(createwindow "Accelerometer Demo" 250 250)
(.show form1)
(= n 1)
(while (< n 1000)
(= acc (readAcc))
(scope (car acc) (cadr acc))
(status 205 8 "Serial" (serial?))
(status 160 8 "Remote" (remote?))
(drawlist g '((-125 40) (125 40)) "Black") ; limit
(drawlist g '((-125 -40) (125 -40)) "Black") ; limit
(= history (cons (list (car acc) (cadr acc)) history))
(= h (list (car history) (cadr history) (car (cdr (cdr history)))))
(drawlist g h "Blue")
(sleep r)
(= n (+ 1 n))
(exit?)
)
(.hide form1)
)
)
To run simply enter (plotaccel 5) the value 5 represents the frequency the accelerometer is read and plotted. 5Hz works well. If the routine works with dummy
readAcc routine then load Day7.lisp and (run_robobuilder) and connect to the COM port. Replace the
readAcc with a function to read the accelerometer as described in earlier post (day 9). The
scope function actually draws the axes and plot the point. Its is passed in this example X and Y values. But you could pass any 2 of the three values. The
plotaccel function also displays a couple of boundary lines - these represent the tipping points (or could do) of the robot. The idea would be when the accelerometer values cross the line would be the point to activate a balance routine for instance. When running move your robobuilder bot around and what the circle move - its great fun!
Not only - but also .. There was a question on another thread about read Joystick on windows machines, L# can do this as well and the outline Ive posted here reference the Joystick note (
http://robosavvy.com/forum/viewtopic.php?p=23913#23913)
Next for something a bit different. Developing the power of Lisp/L#
Tomorrow: Property lists