The code below implements the controller described above.5.1
(set! *mc-handle* (start (make <system-handle>))) (define-splat (bf-controller robot setpoint ke kth v) (local-vars (e 0) (th 0) (init-state-covariance #f) (omega 0) (kf (boundary-following::set-kalman-filter ke kth v)) ) (finalizer (halt robot)) (method #t (define (current-e-theta) (bind ((ang r (min-free-space robot (deg->rad -120) (deg->rad -60)))) (set! e (- r setpoint)) (set! th (- (deg->rad -90) ang )))) ;; set initial estimates of error and thetha and initialize the ;; kalman filter (set! init-state-covariance (matrix:create 2 2 0)) (matrix:set! init-state-covariance 1 1 (sqr (deg->rad 2))) (matrix:set! init-state-covariance 2 2 (sqr 0.2)) (current-e-theta) (start kf (boundary-following::make-reading e th) init-state-covariance) ;; follow the wall (let loop () (current-e-theta) (project kf (boundary-following::make-reading e th)) (set! omega (* (/ -1.0 (max 0.01 v)) (+ (* ke (matrix:ref (state kf) 2 1)) (* kth v (matrix:ref (state kf) 1 1))))) (trace *mc-handle* (format #f "reading: (~a,~a) --> state: (~a, ~a) --> omega = ~a" e (rad->deg th) (matrix:ref (state kf) 2 1) (rad->deg (matrix:ref (state kf) 1 1)) (rad->deg omega))) (check-and-possibly-quit self) (set-drive-and-turn robot v omega) (loop)) ) )The function
boundary-following::set-kalman-filter
defines the Kalman filter associated with the controller (see next section). The value of e and 9#9
can be calculated directly from the robot readings. However, this calculation might be erroneous and we use a Kalman filter to filter out errors in it.