Mercurial > cortex
comparison org/worm_learn.clj @ 451:0a4362d1f138
finishing up chapter 3.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 26 Mar 2014 20:38:17 -0400 |
parents | 09b7c8dd4365 |
children | ced955c3c84f |
comparison
equal
deleted
inserted
replaced
450:432f2c4646cb | 451:0a4362d1f138 |
---|---|
31 (let [model (load-blender-model "Models/worm/worm.blend")] | 31 (let [model (load-blender-model "Models/worm/worm.blend")] |
32 {:body (doto model (body!)) | 32 {:body (doto model (body!)) |
33 :touch (touch! model) | 33 :touch (touch! model) |
34 :proprioception (proprioception! model) | 34 :proprioception (proprioception! model) |
35 :muscles (movement! model)})) | 35 :muscles (movement! model)})) |
36 | |
37 (defn worm* [] | |
38 (let [model (load-blender-model "Models/worm/worm-of-the-imagination.blend")] | |
39 {:body (doto model (body!)) | |
40 :touch (touch! model) | |
41 :proprioception (proprioception! model) | |
42 :muscles (movement! model)})) | |
43 | |
36 | 44 |
37 (def output-base (File. "/home/r/proj/cortex/render/worm-learn/curl")) | 45 (def output-base (File. "/home/r/proj/cortex/render/worm-learn/curl")) |
38 | 46 |
39 | 47 |
40 (defn motor-control-program | 48 (defn motor-control-program |
196 (first (sort-by (comp - second) (indexed s)))) | 204 (first (sort-by (comp - second) (indexed s)))) |
197 | 205 |
198 (defn wiggling? | 206 (defn wiggling? |
199 "Is the worm wiggling?" | 207 "Is the worm wiggling?" |
200 [experiences] | 208 [experiences] |
201 (let [analysis-interval 0x40] | 209 (let [analysis-interval 96] |
202 (when (> (count experiences) analysis-interval) | 210 (when (> (count experiences) analysis-interval) |
203 (let [a-flex 3 | 211 (let [a-flex 3 |
204 a-ex 2 | 212 a-ex 2 |
205 muscle-activity | 213 muscle-activity |
206 (map :muscle (vector:last-n experiences analysis-interval)) | 214 (map :muscle (vector:last-n experiences analysis-interval)) |
207 base-activity | 215 base-activity |
208 (map #(- (% a-flex) (% a-ex)) muscle-activity)] | 216 (map #(- (% a-flex) (% a-ex)) muscle-activity) |
209 (= 2 | 217 accept? |
210 (first | 218 (fn [activity] |
211 (max-indexed | 219 (->> activity (fft) (take 20) (map #(Math/abs %)) |
212 (map #(Math/abs %) | 220 (max-indexed) (first) (<= 2)))] |
213 (take 20 (fft base-activity)))))))))) | 221 (or (accept? (take 64 base-activity)) |
222 (accept? (take 64 (drop 20 base-activity)))))))) | |
223 | |
224 | |
214 | 225 |
215 (def worm-segment-bottom-tip (rect-region [15 15] [22 22])) | 226 (def worm-segment-bottom-tip (rect-region [15 15] [22 22])) |
216 | 227 |
217 (def worm-segment-top-tip (rect-region [0 15] [7 22])) | 228 (def worm-segment-top-tip (rect-region [0 15] [7 22])) |
218 | 229 |
221 [experiences] | 232 [experiences] |
222 (and (curled? experiences) | 233 (and (curled? experiences) |
223 (let [worm-touch (:touch (peek experiences)) | 234 (let [worm-touch (:touch (peek experiences)) |
224 tail-touch (worm-touch 0) | 235 tail-touch (worm-touch 0) |
225 head-touch (worm-touch 4)] | 236 head-touch (worm-touch 4)] |
226 (and (< 0.55 (contact worm-segment-bottom-tip tail-touch)) | 237 (and (< 0.1 (contact worm-segment-bottom-tip tail-touch)) |
227 (< 0.55 (contact worm-segment-top-tip head-touch)))))) | 238 (< 0.1 (contact worm-segment-top-tip head-touch)))))) |
228 | 239 |
229 | 240 |
230 (declare phi-space phi-scan debug-experience) | 241 (declare phi-space phi-scan debug-experience) |
231 | 242 |
232 | 243 |
248 (merge direct-control | 259 (merge direct-control |
249 {:view worm-side-view | 260 {:view worm-side-view |
250 :record nil | 261 :record nil |
251 :experiences (atom []) | 262 :experiences (atom []) |
252 :experience-watch debug-experience | 263 :experience-watch debug-experience |
253 :worm-model worm-model | 264 :worm worm |
254 :end-frame nil}))) | 265 :end-frame nil}))) |
255 | 266 |
256 (defn dir! [file] | 267 (defn dir! [file] |
257 (if-not (.exists file) | 268 (if-not (.exists file) |
258 (.mkdir file)) | 269 (.mkdir file)) |
281 [experiences text] | 292 [experiences text] |
282 (cond | 293 (cond |
283 (grand-circle? experiences) (.setText text "Grand Circle") | 294 (grand-circle? experiences) (.setText text "Grand Circle") |
284 (curled? experiences) (.setText text "Curled") | 295 (curled? experiences) (.setText text "Curled") |
285 (wiggling? experiences) (.setText text "Wiggling") | 296 (wiggling? experiences) (.setText text "Wiggling") |
286 (resting? experiences) (.setText text "Resting"))) | 297 (resting? experiences) (.setText text "Resting") |
298 :else (.setText text "Unknown"))) | |
287 | 299 |
288 | 300 |
289 (defn worm-world | 301 (defn worm-world |
290 [& {:keys [record motor-control keybindings view experiences | 302 [& {:keys [record motor-control keybindings view experiences |
291 worm-model end-frame experience-watch] :as settings}] | 303 worm end-frame experience-watch] :as settings}] |
292 (let [{:keys [record motor-control keybindings view experiences | 304 (let [{:keys [record motor-control keybindings view experiences |
293 worm-model end-frame experience-watch]} | 305 worm end-frame experience-watch]} |
294 (merge (worm-world-defaults) settings) | 306 (merge (worm-world-defaults) settings) |
295 | 307 |
296 touch-display (view-touch) | 308 touch-display (view-touch) |
297 prop-display (view-proprioception) | 309 prop-display (view-proprioception) |
298 muscle-display (view-movement) | 310 muscle-display (view-movement) |
331 (when record | 343 (when record |
332 (dir! record) | 344 (dir! record) |
333 (Capture/captureVideo | 345 (Capture/captureVideo |
334 world | 346 world |
335 (dir! (File. record "main-view")))) | 347 (dir! (File. record "main-view")))) |
336 (speed-up world) | 348 (speed-up world 0.5) |
337 ;;(light-up-everything world) | 349 ;;(light-up-everything world) |
338 ) | 350 ) |
339 (fn [world tpf] | 351 (fn [world tpf] |
340 (if (and end-frame (> (.getTime timer) end-frame)) | 352 (if (and end-frame (> (.getTime timer) end-frame)) |
341 (.stop world)) | 353 (.stop world)) |
473 ;;(infer-nils [1 nil 1 1]) [1 1 1 1] | 485 ;;(infer-nils [1 nil 1 1]) [1 1 1 1] |
474 ;;(infer-nils [1 1 1 nil]) [1 1 1 0] | 486 ;;(infer-nils [1 1 1 nil]) [1 1 1 0] |
475 ;;(infer-nils [nil 2 1 1]) [2 2 1 1] | 487 ;;(infer-nils [nil 2 1 1]) [2 2 1 1] |
476 | 488 |
477 | 489 |
478 (defn debug-experience-phi [] | 490 (defn empathy-demonstration [] |
479 (let [proprio (atom ())] | 491 (let [proprio (atom ())] |
480 (fn | 492 (fn |
481 [experiences] | 493 [experiences text] |
482 (let [phi-indices (phi-scan (:proprioception (peek experiences)))] | 494 (let [phi-indices (phi-scan (:proprioception (peek experiences)))] |
483 (swap! proprio (partial cons phi-indices)) | 495 (swap! proprio (partial cons phi-indices)) |
484 (let [exp-thread (longest-thread (take 300 @proprio)) | 496 (let [exp-thread (longest-thread (take 300 @proprio)) |
485 phi-loop (mapv phi-space (infer-nils exp-thread))] | 497 empathy (mapv phi-space (infer-nils exp-thread))] |
486 (println-repl (vector:last-n exp-thread 22)) | 498 (println-repl (vector:last-n exp-thread 22)) |
487 (cond | 499 (cond |
488 (grand-circle? phi-loop) (println "Grand Circle") | 500 (grand-circle? empathy) (.setText text "Grand Circle") |
489 (curled? phi-loop) (println "Curled") | 501 (curled? empathy) (.setText text "Curled") |
490 (wiggling? phi-loop) (println "Wiggling") | 502 (wiggling? empathy) (.setText text "Wiggling") |
491 (resting? phi-loop) (println "Resting") | 503 (resting? empathy) (.setText text "Resting") |
492 :else (println "Unknown"))))))) | 504 :else (.setText text "Unknown"))))))) |
493 | |
494 | 505 |
495 (defn init-interactive [] | 506 (defn init-interactive [] |
496 (def phi-space | 507 (def phi-space |
497 (let [experiences (atom [])] | 508 (let [experiences (atom [])] |
498 (run-world | 509 (run-world |
501 (merge | 512 (merge |
502 (worm-world-defaults) | 513 (worm-world-defaults) |
503 {:experiences experiences}))) | 514 {:experiences experiences}))) |
504 @experiences)) | 515 @experiences)) |
505 (def phi-scan (gen-phi-scan phi-space))) | 516 (def phi-scan (gen-phi-scan phi-space))) |
506 | 517 |
507 | 518 (defn empathy-experiment-1 [record] |
508 (defn run-experiment-1 [] | 519 (.start (worm-world :experience-watch (empathy-demonstration) |
509 (.start (worm-world :experience-watch (debug-experience-phi)))) | 520 :record record :worm worm*))) |
521 | |
522 | |
523 (def worm-action-label | |
524 (juxt grand-circle? curled? wiggling?)) | |
525 | |
526 (defn compare-empathy-with-baseline [accuracy] | |
527 (let [proprio (atom ())] | |
528 (fn | |
529 [experiences text] | |
530 (let [phi-indices (phi-scan (:proprioception (peek experiences)))] | |
531 (swap! proprio (partial cons phi-indices)) | |
532 (let [exp-thread (longest-thread (take 300 @proprio)) | |
533 empathy (mapv phi-space (infer-nils exp-thread)) | |
534 experience-matches-empathy | |
535 (= (worm-action-label experiences) | |
536 (worm-action-label empathy))] | |
537 (cond | |
538 (grand-circle? empathy) (.setText text "Grand Circle") | |
539 (curled? empathy) (.setText text "Curled") | |
540 (wiggling? empathy) (.setText text "Wiggling") | |
541 (resting? empathy) (.setText text "Resting") | |
542 :else (.setText text "Unknown")) | |
543 | |
544 (println-repl experience-matches-empathy) | |
545 (swap! accuracy #(conj % experience-matches-empathy))))))) | |
546 | |
547 (defn accuracy [v] | |
548 (float (/ (count (filter true? v)) (count v)))) | |
549 | |
550 (defn test-empathy-accuracy [] | |
551 (let [res (atom [])] | |
552 (run-world | |
553 (worm-world :experience-watch | |
554 (compare-empathy-with-baseline res) | |
555 :worm worm*)) | |
556 (accuracy @res))) | |
557 | |
558 | |
559 | |
560 | |
561 | |
562 |