comparison org/touch.org @ 249:95a9f6f1cb82

added touch-cube and fixed some problems with touch which it flushed out
author Robert McIntyre <rlm@mit.edu>
date Mon, 13 Feb 2012 06:06:02 -0700
parents 267add63b168
children e9bce4f722b1
comparison
equal deleted inserted replaced
248:267add63b168 249:95a9f6f1cb82
381 (defn set-ray [#^Ray ray #^Matrix4f transform 381 (defn set-ray [#^Ray ray #^Matrix4f transform
382 #^Vector3f origin #^Vector3f tip] 382 #^Vector3f origin #^Vector3f tip]
383 ;; Doing everything locally recduces garbage collection by enough to 383 ;; Doing everything locally recduces garbage collection by enough to
384 ;; be worth it. 384 ;; be worth it.
385 (.mult transform origin (.getOrigin ray)) 385 (.mult transform origin (.getOrigin ray))
386
387 (.mult transform tip (.getDirection ray)) 386 (.mult transform tip (.getDirection ray))
388 (.subtractLocal (.getDirection ray) (.getOrigin ray))) 387 (.subtractLocal (.getDirection ray) (.getOrigin ray))
389 388 (.normalizeLocal (.getDirection ray)))
389
390 (import com.jme3.math.FastMath)
391
392
390 (defn touch-kernel 393 (defn touch-kernel
391 "Constructs a function which will return tactile sensory data from 394 "Constructs a function which will return tactile sensory data from
392 'geo when called from inside a running simulation" 395 'geo when called from inside a running simulation"
393 [#^Geometry geo] 396 [#^Geometry geo]
394 (if-let 397 (if-let
395 [profile (tactile-sensor-profile geo)] 398 [profile (tactile-sensor-profile geo)]
396 (let [ray-reference-origins (feeler-origins geo profile) 399 (let [ray-reference-origins (feeler-origins geo profile)
397 ray-reference-tips (feeler-tips geo profile) 400 ray-reference-tips (feeler-tips geo profile)
398 ray-length (tactile-scale geo) 401 ray-length (tactile-scale geo)
399 current-rays (map (fn [_] (Ray.)) ray-reference-origins) 402 current-rays (map (fn [_] (Ray.)) ray-reference-origins)
400 topology (touch-topology geo profile)] 403 topology (touch-topology geo profile)
404 correction (float (* ray-length -0.2))]
405
406 ;; slight tolerance for very close collisions.
407 (dorun
408 (map (fn [origin tip]
409 (.addLocal origin (.mult (.subtract tip origin)
410 correction)))
411 ray-reference-origins ray-reference-tips))
401 (dorun (map #(.setLimit % ray-length) current-rays)) 412 (dorun (map #(.setLimit % ray-length) current-rays))
402 (fn [node] 413 (fn [node]
403 (let [transform (.getWorldMatrix geo)] 414 (let [transform (.getWorldMatrix geo)]
404 (dorun 415 (dorun
405 (map (fn [ray ref-origin ref-tip] 416 (map (fn [ray ref-origin ref-tip]
413 (do 424 (do
414 (let [results (CollisionResults.)] 425 (let [results (CollisionResults.)]
415 (.collideWith node ray results) 426 (.collideWith node ray results)
416 (let [touch-objects 427 (let [touch-objects
417 (filter #(not (= geo (.getGeometry %))) 428 (filter #(not (= geo (.getGeometry %)))
418 results)] 429 results)
430 limit (.getLimit ray)]
419 [(if (empty? touch-objects) 431 [(if (empty? touch-objects)
420 (.getLimit ray) 432 limit
421 (.getDistance (first touch-objects))) 433 (let [response
422 (.getLimit ray)]))))))))))) 434 (apply min (map #(.getDistance %)
435 touch-objects))]
436 (FastMath/clamp
437 (float
438 (if (> response limit) 0.0
439 (+ response correction)))
440 (float 0.0)
441 limit)))
442 limit])))))))))))
423 443
424 (defn touch! 444 (defn touch!
425 "Endow the creature with the sense of touch. Returns a sequence of 445 "Endow the creature with the sense of touch. Returns a sequence of
426 functions, one for each body part with a tactile-sensor-proile, 446 functions, one for each body part with a tactile-sensor-proile,
427 each of which when called returns sensory data for that body part." 447 each of which when called returns sensory data for that body part."
431 (map touch-kernel 451 (map touch-kernel
432 (filter #(isa? (class %) Geometry) 452 (filter #(isa? (class %) Geometry)
433 (node-seq creature))))) 453 (node-seq creature)))))
434 #+end_src 454 #+end_src
435 455
456 #+results: kernel
457 : #'cortex.touch/touch!
458
436 * Visualizing Touch 459 * Visualizing Touch
460
461 Each feeler is represented in the image as a single pixel. The
462 grayscale value of each pixel represents how deep the feeler
463 represented by that pixel is inside another object. Black means that
464 nothing is touching the feeler, while white means that the feeler is
465 completely inside another object, which is presumably flush with the
466 surface of the triangle from which the feeler originates.
437 467
438 #+name: visualization 468 #+name: visualization
439 #+begin_src clojure 469 #+begin_src clojure
440 (in-ns 'cortex.touch) 470 (in-ns 'cortex.touch)
441 471
451 (view-sense 481 (view-sense
452 (fn [[coords sensor-data]] 482 (fn [[coords sensor-data]]
453 (let [image (points->image coords)] 483 (let [image (points->image coords)]
454 (dorun 484 (dorun
455 (for [i (range (count coords))] 485 (for [i (range (count coords))]
456 (.setRGB image ((coords i) 0) ((coords i) 1) 486 (do
457 (apply touch->gray (sensor-data i))))) image)))) 487 (if (= i 500) (println-repl (sensor-data i)))
458 #+end_src 488
489 (comment
490 (.setRGB image ((coords i) 0) ((coords i) 1)
491 (apply touch->gray (sensor-data i)))))))
492 image))))
493 #+end_src
494
495 #+results: visualization
496 : #'cortex.touch/view-touch
497
498 * COMMENT Basic Test of Touch
499
500 The worm's sense of touch is a bit complicated, so for this basic test
501 I'll use a new creature --- a simple cube which has touch sensors
502 evenly distributed along each of its sides.
503
504 #+begin_src clojure
505 (in-ns 'cortex.test.touch)
506
507 (defn touch-cube []
508 (load-blender-model "Models/test-touch/touch-cube.blend"))
509 #+end_src
510
511 #+begin_html
512 <br>
513 #+end_html
514
515 #+begin_html
516 <div class="figure">
517 <center>
518 <video controls="controls" width="500">
519 <source src="../video/touch-cube.ogg" type="video/ogg"
520 preload="none" poster="../images/aurellem-1280x480.png" />
521 </video>
522 </center>
523 <p>A simple creature with evenly distributed touch sensors.</p>
524 </div>
525 #+end_html
526
527 The tactile-sensor-profile image for this simple creature looks like
528 this:
529
530 #+attr_html: width=500
531 #+caption: The distribution of feelers along the touch-cube. The colors of the faces are irrelevant; only the white pixels specify feelers.
532 [[../images/touch-profile.png]]
533
534 #+begin_src clojure
535 (in-ns 'cortex.test.touch)
536
537 (defn test-basic-touch
538 ([] (test-basic-touch false))
539 ([record?]
540 (let [the-cube (doto (touch-cube) (body!))
541 touch (touch! the-cube)
542 touch-display (view-touch)]
543 (world (nodify [the-cube
544 (box 10 1 10 :position (Vector3f. 0 -10 0)
545 :color ColorRGBA/Gray :mass 0)])
546
547 standard-debug-controls
548
549 (fn [world]
550 (speed-up world)
551 (light-up-everything world))
552
553 (fn [world tpf]
554 (touch-display
555 (map #(% (.getRootNode world)) touch)))))))
556
557
558 #+end_src
559
459 * Adding Touch to the Worm 560 * Adding Touch to the Worm
460 561
461 #+name: test-touch 562 #+name: test-touch
462 #+begin_src clojure 563 #+begin_src clojure
463 (ns cortex.test.touch 564 (ns cortex.test.touch