Mercurial > cortex
diff org/worm_learn.clj @ 415:af7945c27474
working on phi-space.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 19 Mar 2014 21:46:58 -0400 |
parents | 634795361af8 |
children | 9e52b6730fd0 |
line wrap: on
line diff
1.1 --- a/org/worm_learn.clj Wed Mar 19 15:59:46 2014 -0400 1.2 +++ b/org/worm_learn.clj Wed Mar 19 21:46:58 2014 -0400 1.3 @@ -81,8 +81,8 @@ 1.4 ;; motions that causes the worm to form a circle. 1.5 1.6 (def curl-script 1.7 - [[370 :d-flex 40] 1.8 - [600 :d-flex 0]]) 1.9 + [[150 :d-flex 40] 1.10 + [250 :d-flex 0]]) 1.11 1.12 (def period 18) 1.13 1.14 @@ -106,6 +106,17 @@ 1.15 (range 100 1000000 (+ 3 (* period 2))))) 1.16 1.17 1.18 +(defn shift-script [shift script] 1.19 + (map (fn [[time label power]] [(+ time shift) label power]) 1.20 + script)) 1.21 + 1.22 +(def do-all-the-things 1.23 + (concat 1.24 + curl-script 1.25 + [[300 :d-ex 40] 1.26 + [320 :d-ex 0]] 1.27 + (shift-script 280 (take 16 wiggle-script)))) 1.28 + 1.29 ;; Normally, we'd use unsupervised/supervised machine learning to pick 1.30 ;; out the defining features of the different actions available to the 1.31 ;; worm. For this project, I am going to explicitely define functions 1.32 @@ -118,13 +129,9 @@ 1.33 ;; thesis. 1.34 1.35 1.36 -(defn straight? 1.37 - "Is the worm straight?" 1.38 - [experiences] 1.39 - (every? 1.40 - (fn [[_ _ bend]] 1.41 - (< (Math/sin bend) 0.05)) 1.42 - (:proprioception (peek experiences)))) 1.43 +;; curled? relies on proprioception, resting? relies on touch, 1.44 +;; wiggling? relies on a fourier analysis of muscle contraction, and 1.45 +;; grand-circle? relies on touch and reuses curled? as a gaurd. 1.46 1.47 (defn curled? 1.48 "Is the worm curled up?" 1.49 @@ -134,17 +141,6 @@ 1.50 (> (Math/sin bend) 0.64)) 1.51 (:proprioception (peek experiences)))) 1.52 1.53 -(defn grand-circle? 1.54 - "Does the worm form a majestic circle (one end touching the other)?" 1.55 - [experiences] 1.56 - (and (curled? experiences) 1.57 - true)) ;; TODO: add code here. 1.58 - 1.59 -(defn vector:last-n [v n] 1.60 - (let [c (count v)] 1.61 - (if (< c n) v 1.62 - (subvec v (- c n) c)))) 1.63 - 1.64 (defn touch-average [[coords touch]] 1.65 (/ (average (map first touch)) (average (map second touch)))) 1.66 1.67 @@ -154,15 +150,15 @@ 1.68 y (range y0 (inc y1))] 1.69 [x y]))) 1.70 1.71 -(def worm-segment-touch-bottom (rect-region [8 15] [14 22])) 1.72 +(def worm-segment-bottom (rect-region [8 15] [14 22])) 1.73 1.74 (defn contact 1.75 "Determine how much contact a particular worm segment has with 1.76 other objects. Returns a value between 0 and 1, where 1 is full 1.77 contact and 0 is no contact." 1.78 - [[coords contact :as touch]] 1.79 + [touch-region [coords contact :as touch]] 1.80 (-> (zipmap coords contact) 1.81 - (select-keys worm-segment-touch-bottom) 1.82 + (select-keys touch-region) 1.83 (vals) 1.84 (#(map first %)) 1.85 (average) 1.86 @@ -170,6 +166,19 @@ 1.87 (- 1) 1.88 (Math/abs))) 1.89 1.90 +(defn resting? 1.91 + "Is the worm straight?" 1.92 + [experiences] 1.93 + (every? 1.94 + (fn [touch-data] 1.95 + (< 0.9 (contact worm-segment-bottom touch-data))) 1.96 + (:touch (peek experiences)))) 1.97 + 1.98 +(defn vector:last-n [v n] 1.99 + (let [c (count v)] 1.100 + (if (< c n) v 1.101 + (subvec v (- c n) c)))) 1.102 + 1.103 (defn fft [nums] 1.104 (map 1.105 #(.getReal %) 1.106 @@ -182,7 +191,6 @@ 1.107 (defn max-indexed [s] 1.108 (first (sort-by (comp - second) (indexed s)))) 1.109 1.110 - 1.111 (defn wiggling? 1.112 "Is the worm wiggling?" 1.113 [experiences] 1.114 @@ -196,24 +204,23 @@ 1.115 (map #(- (% a-flex) (% a-ex)) muscle-activity)] 1.116 (= 2 1.117 (first 1.118 - (max-indexed (map #(Math/abs %) (take 20 (fft base-activity)))))))))) 1.119 + (max-indexed 1.120 + (map #(Math/abs %) 1.121 + (take 20 (fft base-activity)))))))))) 1.122 1.123 - ;; (println-repl 1.124 - ;; (apply format "%d %.2f" 1.125 - ;; (first (sort-by 1.126 - ;; (comp - second) 1.127 - ;; (indexed (take 20 )))))))))) 1.128 +(def worm-segment-bottom-tip (rect-region [15 15] [22 22])) 1.129 1.130 - ;; (println-repl 1.131 - ;; (apply 1.132 - ;; format 1.133 - ;; (apply str (repeat analysis-interval "%5.1f")) 1.134 - ;; (fft base-activity))) 1.135 +(def worm-segment-top-tip (rect-region [0 15] [7 22])) 1.136 1.137 - ;; ;;(println-repl (last base-activity)) 1.138 - ;; ))) 1.139 - 1.140 - 1.141 +(defn grand-circle? 1.142 + "Does the worm form a majestic circle (one end touching the other)?" 1.143 + [experiences] 1.144 + (and true;; (curled? experiences) 1.145 + (let [worm-touch (:touch (peek experiences)) 1.146 + tail-touch (worm-touch 0) 1.147 + head-touch (worm-touch 4)] 1.148 + (and (< 0.55 (contact worm-segment-bottom-tip tail-touch)) 1.149 + (< 0.55 (contact worm-segment-top-tip head-touch)))))) 1.150 1.151 (def standard-world-view 1.152 [(Vector3f. 4.207176, -3.7366982, 3.0816958) 1.153 @@ -245,6 +252,50 @@ 1.154 (defn record-experience! [experiences data] 1.155 (swap! experiences #(conj % data))) 1.156 1.157 + 1.158 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.159 +;;;;;;;; Phi-Space ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.160 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.161 + 1.162 +(defn generate-phi-space [] 1.163 + (let [experiences (atom [])] 1.164 + (run-world 1.165 + (apply-map 1.166 + worm-world 1.167 + (merge 1.168 + (worm-world-defaults) 1.169 + {:end-frame 700 1.170 + :motor-control 1.171 + (motor-control-program worm-muscle-labels do-all-the-things) 1.172 + :experiences experiences}))) 1.173 + @experiences)) 1.174 + 1.175 + 1.176 +(defn bin [digits] 1.177 + (fn [angles] 1.178 + (->> angles 1.179 + (flatten) 1.180 + (map (juxt #(Math/sin %) #(Math/cos %))) 1.181 + (flatten) 1.182 + (mapv #(Math/round (* % (Math/pow 10 (dec digits)))))))) 1.183 + 1.184 +;; k-nearest neighbors with spatial binning. 1.185 +(defn gen-phi-scan [phi-space] 1.186 + (let [bin-keys (reverse (map bin (range 4))) 1.187 + bin-maps 1.188 + (map (fn [bin-key phi-space] 1.189 + (group-by (comp bin-key :proprioception) phi-space)) 1.190 + bin-keys (repeat phi-space)) 1.191 + lookups (map (fn [bin-key bin-map] 1.192 + (fn [proprio] (bin-map (bin-key proprio)))) 1.193 + bin-keys bin-maps)] 1.194 + (fn lookup [proprio-data] 1.195 + (some #(% proprio-data) lookups)))) 1.196 + 1.197 + 1.198 + 1.199 + 1.200 + 1.201 (defn worm-world 1.202 [& {:keys [record motor-control keybindings view experiences 1.203 worm-model end-frame] :as settings}] 1.204 @@ -282,18 +333,17 @@ 1.205 (.stop world)) 1.206 (let [muscle-data (vec (motor-control muscles)) 1.207 proprioception-data (prop) 1.208 - touch-data (map #(% (.getRootNode world)) touch)] 1.209 + touch-data (mapv #(% (.getRootNode world)) touch)] 1.210 (when experiences 1.211 (record-experience! 1.212 experiences {:touch touch-data 1.213 :proprioception proprioception-data 1.214 :muscle muscle-data}) 1.215 - ;;(if (curled? @experiences) (println "Curled")) 1.216 - ;;(if (straight? @experiences) (println "Straight")) 1.217 - ;; (println-repl 1.218 - ;; (apply format "%.2f %.2f %.2f %.2f %.2f\n" 1.219 - ;; (map contact touch-data))) 1.220 - (wiggling? @experiences) 1.221 + (cond 1.222 + (grand-circle? @experiences) (println "Grand Circle") 1.223 + (curled? @experiences) (println "Curled") 1.224 + (wiggling? @experiences) (println "Wiggling") 1.225 + (resting? @experiences) (println "Resting")) 1.226 ) 1.227 (muscle-display 1.228 muscle-data