Mercurial > cortex
comparison org/worm_learn.clj @ 548:0b891e0dd809
version 0.2 of thesis complete.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 01 May 2014 23:41:41 -0400 |
parents | 01934317b25b |
children |
comparison
equal
deleted
inserted
replaced
547:5d89879fc894 | 548:0b891e0dd809 |
---|---|
18 (use 'clojure.pprint) | 18 (use 'clojure.pprint) |
19 (use 'clojure.set) | 19 (use 'clojure.set) |
20 (dorun (cortex.import/mega-import-jme3)) | 20 (dorun (cortex.import/mega-import-jme3)) |
21 (rlm.rlm-commands/help) | 21 (rlm.rlm-commands/help) |
22 | 22 |
23 | |
23 (load-bullet) | 24 (load-bullet) |
25 | |
26 (defn bin [digits] | |
27 (fn [angles] | |
28 (->> angles | |
29 (flatten) | |
30 (map (juxt #(Math/sin %) #(Math/cos %))) | |
31 (flatten) | |
32 (mapv #(Math/round (* % (Math/pow 10 (dec digits)))))))) | |
33 | |
24 | 34 |
25 (def hand "Models/test-creature/hand.blend") | 35 (def hand "Models/test-creature/hand.blend") |
26 | 36 |
27 (defn worm-model [] | 37 (defn worm-model [] |
28 (load-blender-model "Models/worm/worm.blend")) | 38 (load-blender-model "Models/worm/worm.blend")) |
160 (vec | 170 (vec |
161 (for [x (range x0 (inc x1)) | 171 (for [x (range x0 (inc x1)) |
162 y (range y0 (inc y1))] | 172 y (range y0 (inc y1))] |
163 [x y]))) | 173 [x y]))) |
164 | 174 |
175 (def all-touch-coordinates | |
176 (concat | |
177 (rect-region [0 15] [7 22]) | |
178 (rect-region [8 0] [14 29]) | |
179 (rect-region [15 15] [22 22]))) | |
180 | |
165 (def worm-segment-bottom (rect-region [8 15] [14 22])) | 181 (def worm-segment-bottom (rect-region [8 15] [14 22])) |
166 | 182 |
167 (defn contact | 183 (defn contact |
168 "Determine how much contact a particular worm segment has with | 184 "Determine how much contact a particular worm segment has with |
169 other objects. Returns a value between 0 and 1, where 1 is full | 185 other objects. Returns a value between 0 and 1, where 1 is full |
219 (->> activity (fft) (take 20) (map #(Math/abs %)) | 235 (->> activity (fft) (take 20) (map #(Math/abs %)) |
220 (max-indexed) (first) (<= 2)))] | 236 (max-indexed) (first) (<= 2)))] |
221 (or (accept? (take 64 base-activity)) | 237 (or (accept? (take 64 base-activity)) |
222 (accept? (take 64 (drop 20 base-activity)))))))) | 238 (accept? (take 64 (drop 20 base-activity)))))))) |
223 | 239 |
224 | |
225 | |
226 (def worm-segment-bottom-tip (rect-region [15 15] [22 22])) | 240 (def worm-segment-bottom-tip (rect-region [15 15] [22 22])) |
227 | 241 |
228 (def worm-segment-top-tip (rect-region [0 15] [7 22])) | 242 (def worm-segment-top-tip (rect-region [0 15] [7 22])) |
229 | 243 |
230 (defn grand-circle? | 244 (defn grand-circle? |
236 head-touch (worm-touch 4)] | 250 head-touch (worm-touch 4)] |
237 (and (< 0.1 (contact worm-segment-bottom-tip tail-touch)) | 251 (and (< 0.1 (contact worm-segment-bottom-tip tail-touch)) |
238 (< 0.1 (contact worm-segment-top-tip head-touch)))))) | 252 (< 0.1 (contact worm-segment-top-tip head-touch)))))) |
239 | 253 |
240 | 254 |
255 (defn draped? | |
256 "Is the worm: | |
257 -- not flat (the floor is not a 'chair') | |
258 -- supported (not using its muscles to hold its position) | |
259 -- stable (not changing its position) | |
260 -- touching something (must register contact)" | |
261 [experiences] | |
262 (let [b2-hash (bin 2) | |
263 touch (:touch (peek experiences)) | |
264 total-contact | |
265 (reduce | |
266 + | |
267 (map #(contact all-touch-coordinates %) | |
268 (rest touch)))] | |
269 (println total-contact) | |
270 (and (not (resting? experiences)) | |
271 (every? | |
272 zero? | |
273 (-> experiences | |
274 (vector:last-n 25) | |
275 (#(map :muscle %)) | |
276 (flatten))) | |
277 (-> experiences | |
278 (vector:last-n 20) | |
279 (#(map (comp b2-hash flatten :proprioception) %)) | |
280 (set) | |
281 (count) (= 1)) | |
282 (< 0.03 total-contact)))) | |
283 | |
284 | |
241 (declare phi-space phi-scan debug-experience) | 285 (declare phi-space phi-scan debug-experience) |
242 | 286 |
243 | 287 |
244 | 288 |
245 (def standard-world-view | 289 (def standard-world-view |
251 (Quaternion. -0.11555642, 0.88188726, -0.2854942, -0.3569518)]) | 295 (Quaternion. -0.11555642, 0.88188726, -0.2854942, -0.3569518)]) |
252 | 296 |
253 (def degenerate-worm-view | 297 (def degenerate-worm-view |
254 [(Vector3f. -0.0708936, -8.570261, 2.6487997) | 298 [(Vector3f. -0.0708936, -8.570261, 2.6487997) |
255 (Quaternion. -2.318909E-4, 0.9985348, 0.053941682, 0.004291452)]) | 299 (Quaternion. -2.318909E-4, 0.9985348, 0.053941682, 0.004291452)]) |
300 | |
301 (defn summon-chair | |
302 "Create a chair in the world for the worm" | |
303 [world] | |
304 (let [chair (box 0.5 0.5 0.5 :position (Vector3f. 0 -5 -2) | |
305 :mass 350. :color ColorRGBA/Pink)] | |
306 (add-element world chair (.getRootNode world)))) | |
256 | 307 |
257 (defn worm-world-defaults [] | 308 (defn worm-world-defaults [] |
258 (let [direct-control (worm-direct-control worm-muscle-labels 40)] | 309 (let [direct-control (worm-direct-control worm-muscle-labels 40)] |
259 (merge direct-control | 310 (merge direct-control |
260 {:view worm-side-view | 311 {:view worm-side-view |
261 :record nil | 312 :record nil |
262 :experiences (atom []) | 313 :experiences (atom []) |
263 :experience-watch debug-experience | 314 :experience-watch debug-experience |
264 :worm worm | 315 :worm worm |
265 :end-frame nil}))) | 316 :end-frame nil |
317 :keybindings | |
318 (merge (:keybindings direct-control) | |
319 {"key-b" (fn [world pressed?] | |
320 (if pressed? (summon-chair world)))})}))) | |
266 | 321 |
267 (defn dir! [file] | 322 (defn dir! [file] |
268 (if-not (.exists file) | 323 (if-not (.exists file) |
269 (.mkdir file)) | 324 (.mkdir file)) |
270 file) | 325 file) |
289 (.addProcessor (.getViewPort world) pssm))) | 344 (.addProcessor (.getViewPort world) pssm))) |
290 | 345 |
291 (defn debug-experience | 346 (defn debug-experience |
292 [experiences text] | 347 [experiences text] |
293 (cond | 348 (cond |
349 (draped? experiences) (.setText text "Draped") | |
294 (grand-circle? experiences) (.setText text "Grand Circle") | 350 (grand-circle? experiences) (.setText text "Grand Circle") |
295 (curled? experiences) (.setText text "Curled") | 351 (curled? experiences) (.setText text "Curled") |
296 (wiggling? experiences) (.setText text "Wiggling") | 352 (wiggling? experiences) (.setText text "Wiggling") |
297 (resting? experiences) (.setText text "Resting") | 353 (resting? experiences) (.setText text "Resting") |
298 :else (.setText text "Unknown"))) | 354 :else (.setText text "Unknown"))) |
388 :motor-control | 444 :motor-control |
389 (motor-control-program worm-muscle-labels do-all-the-things) | 445 (motor-control-program worm-muscle-labels do-all-the-things) |
390 :experiences experiences}))) | 446 :experiences experiences}))) |
391 @experiences)) | 447 @experiences)) |
392 | 448 |
393 (defn bin [digits] | |
394 (fn [angles] | |
395 (->> angles | |
396 (flatten) | |
397 (map (juxt #(Math/sin %) #(Math/cos %))) | |
398 (flatten) | |
399 (mapv #(Math/round (* % (Math/pow 10 (dec digits)))))))) | |
400 | |
401 ;; k-nearest neighbors with spatial binning. Only returns a result if | 449 ;; k-nearest neighbors with spatial binning. Only returns a result if |
402 ;; the propriceptive data is within 10% of a previously recorded | 450 ;; the propriceptive data is within 10% of a previously recorded |
403 ;; result in all dimensions. | 451 ;; result in all dimensions. |
404 (defn gen-phi-scan [phi-space] | 452 (defn gen-phi-scan [phi-space] |
405 (let [bin-keys (map bin [3 2 1]) | 453 (let [bin-keys (map bin [3 2 1]) |
465 ;; tests | 513 ;; tests |
466 | 514 |
467 ;;(infer-nils [1 nil 1 1]) [1 1 1 1] | 515 ;;(infer-nils [1 nil 1 1]) [1 1 1 1] |
468 ;;(infer-nils [1 1 1 nil]) [1 1 1 0] | 516 ;;(infer-nils [1 1 1 nil]) [1 1 1 0] |
469 ;;(infer-nils [nil 2 1 1]) [2 2 1 1] | 517 ;;(infer-nils [nil 2 1 1]) [2 2 1 1] |
470 | 518 |
471 | 519 |
472 (defn empathy-demonstration [] | 520 (defn empathy-demonstration [] |
473 (let [proprio (atom ())] | 521 (let [proprio (atom ())] |
474 (fn | 522 (fn |
475 [experiences text] | 523 [experiences text] |
477 (swap! proprio (partial cons phi-indices)) | 525 (swap! proprio (partial cons phi-indices)) |
478 (let [exp-thread (longest-thread (take 300 @proprio)) | 526 (let [exp-thread (longest-thread (take 300 @proprio)) |
479 empathy (mapv phi-space (infer-nils exp-thread))] | 527 empathy (mapv phi-space (infer-nils exp-thread))] |
480 (println-repl (vector:last-n exp-thread 22)) | 528 (println-repl (vector:last-n exp-thread 22)) |
481 (cond | 529 (cond |
530 (draped? empathy) (.setText text "Draped") | |
482 (grand-circle? empathy) (.setText text "Grand Circle") | 531 (grand-circle? empathy) (.setText text "Grand Circle") |
483 (curled? empathy) (.setText text "Curled") | 532 (curled? empathy) (.setText text "Curled") |
484 (wiggling? empathy) (.setText text "Wiggling") | 533 (wiggling? empathy) (.setText text "Wiggling") |
485 (resting? empathy) (.setText text "Resting") | 534 (resting? empathy) (.setText text "Resting") |
486 :else (.setText text "Unknown"))))))) | 535 :else (.setText text "Unknown"))))))) |
494 (merge | 543 (merge |
495 (worm-world-defaults) | 544 (worm-world-defaults) |
496 {:experiences experiences}))) | 545 {:experiences experiences}))) |
497 @experiences)) | 546 @experiences)) |
498 (def phi-scan (gen-phi-scan phi-space))) | 547 (def phi-scan (gen-phi-scan phi-space))) |
548 | |
549 (defn empathy-experiment-0 [record] | |
550 (.start (worm-world :record record))) | |
551 | |
552 | |
499 | 553 |
500 (defn empathy-experiment-1 [record] | 554 (defn empathy-experiment-1 [record] |
501 (.start (worm-world :experience-watch (empathy-demonstration) | 555 (.start (worm-world :experience-watch (empathy-demonstration) |
502 :record record :worm worm*))) | 556 :record record :worm worm*))) |
503 | 557 |