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