changeset 479:a5480a06d5fe

first draft of proprioception complete.
author Robert McIntyre <rlm@mit.edu>
date Fri, 28 Mar 2014 23:16:32 -0400
parents 76d44e969289
children ad76b8b05517
files thesis/cortex.org thesis/images/proprio.png
diffstat 2 files changed, 149 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/thesis/cortex.org	Fri Mar 28 22:51:55 2014 -0400
     1.2 +++ b/thesis/cortex.org	Fri Mar 28 23:16:32 2014 -0400
     1.3 @@ -12,6 +12,8 @@
     1.4     #+caption: 
     1.5     #+name: name
     1.6     #+begin_listing clojure
     1.7 +   #+BEGIN_SRC clojure
     1.8 +   #+END_SRC
     1.9     #+end_listing
    1.10  
    1.11     #+caption: 
    1.12 @@ -2050,6 +2052,153 @@
    1.13  
    1.14  ** Proprioception is the sense that makes everything ``real''
    1.15  
    1.16 +   Close your eyes, and touch your nose with your right index finger.
    1.17 +   How did you do it? You could not see your hand, and neither your
    1.18 +   hand nor your nose could use the sense of touch to guide the path
    1.19 +   of your hand. There are no sound cues, and Taste and Smell
    1.20 +   certainly don't provide any help. You know where your hand is
    1.21 +   without your other senses because of Proprioception.
    1.22 +   
    1.23 +   Humans can sometimes loose this sense through viral infections or
    1.24 +   damage to the spinal cord or brain, and when they do, they loose
    1.25 +   the ability to control their own bodies without looking directly at
    1.26 +   the parts they want to move. In [[http://en.wikipedia.org/wiki/The_Man_Who_Mistook_His_Wife_for_a_Hat][The Man Who Mistook His Wife for a
    1.27 +   Hat]], a woman named Christina looses this sense and has to learn how
    1.28 +   to move by carefully watching her arms and legs. She describes
    1.29 +   proprioception as the "eyes of the body, the way the body sees
    1.30 +   itself".
    1.31 +   
    1.32 +   Proprioception in humans is mediated by [[http://en.wikipedia.org/wiki/Articular_capsule][joint capsules]], [[http://en.wikipedia.org/wiki/Muscle_spindle][muscle
    1.33 +   spindles]], and the [[http://en.wikipedia.org/wiki/Golgi_tendon_organ][Golgi tendon organs]]. These measure the relative
    1.34 +   positions of each body part by monitoring muscle strain and length.
    1.35 +   
    1.36 +   It's clear that this is a vital sense for fluid, graceful movement.
    1.37 +   It's also particularly easy to implement in jMonkeyEngine.
    1.38 +   
    1.39 +   My simulated proprioception calculates the relative angles of each
    1.40 +   joint from the rest position defined in the blender file. This
    1.41 +   simulates the muscle-spindles and joint capsules. I will deal with
    1.42 +   Golgi tendon organs, which calculate muscle strain, in the next
    1.43 +   section.
    1.44 +
    1.45 +*** Helper functions
    1.46 +
    1.47 +    =absolute-angle= calculates the angle between two vectors,
    1.48 +    relative to a third axis vector. This angle is the number of
    1.49 +    radians you have to move counterclockwise around the axis vector
    1.50 +    to get from the first to the second vector. It is not commutative
    1.51 +    like a normal dot-product angle is.
    1.52 +
    1.53 +    The purpose of these functions is to build a system of angle
    1.54 +    measurement that is biologically plausable.
    1.55 +
    1.56 +
    1.57 +    #+caption: Program to measure angles along a vector
    1.58 +    #+name: helpers
    1.59 +    #+begin_listing clojure
    1.60 +    #+BEGIN_SRC clojure
    1.61 +(defn right-handed?
    1.62 +  "true iff the three vectors form a right handed coordinate
    1.63 +   system. The three vectors do not have to be normalized or
    1.64 +   orthogonal."
    1.65 +  [vec1 vec2 vec3]
    1.66 +  (pos? (.dot (.cross vec1 vec2) vec3)))
    1.67 +
    1.68 +(defn absolute-angle
    1.69 +  "The angle between 'vec1 and 'vec2 around 'axis. In the range 
    1.70 +   [0 (* 2 Math/PI)]."
    1.71 +  [vec1 vec2 axis]
    1.72 +  (let [angle (.angleBetween vec1 vec2)]
    1.73 +    (if (right-handed? vec1 vec2 axis)
    1.74 +      angle (- (* 2 Math/PI) angle))))
    1.75 +    #+END_SRC
    1.76 +    #+end_listing
    1.77 +
    1.78 +
    1.79 +
    1.80 +    #+caption: 
    1.81 +    #+caption: 
    1.82 +    #+caption: 
    1.83 +    #+caption: 
    1.84 +    #+name: name
    1.85 +    #+begin_listing clojure
    1.86 +    #+BEGIN_SRC clojure
    1.87 +    #+END_SRC
    1.88 +    #+end_listing
    1.89 +
    1.90 +
    1.91 +*** Proprioception Kernel
    1.92 +    
    1.93 +    Given a joint, =proprioception-kernel= produces a function that
    1.94 +    calculates the Euler angles between the the objects the joint
    1.95 +    connects. The only tricky part here is making the angles relative
    1.96 +    to the joint's initial ``straightness''.
    1.97 +
    1.98 +    #+caption: Program to return biologially reasonable proprioceptive
    1.99 +    #+caption: data for each joint.
   1.100 +    #+name: proprioception
   1.101 +    #+begin_listing clojure
   1.102 +    #+BEGIN_SRC clojure
   1.103 +(defn proprioception-kernel
   1.104 +  "Returns a function which returns proprioceptive sensory data when
   1.105 +  called inside a running simulation."
   1.106 +  [#^Node parts #^Node joint]
   1.107 +  (let [[obj-a obj-b] (joint-targets parts joint)
   1.108 +        joint-rot (.getWorldRotation joint)
   1.109 +        x0 (.mult joint-rot Vector3f/UNIT_X)
   1.110 +        y0 (.mult joint-rot Vector3f/UNIT_Y)
   1.111 +        z0 (.mult joint-rot Vector3f/UNIT_Z)]
   1.112 +    (fn []
   1.113 +      (let [rot-a (.clone (.getWorldRotation obj-a))
   1.114 +            rot-b (.clone (.getWorldRotation obj-b))
   1.115 +            x (.mult rot-a x0)
   1.116 +            y (.mult rot-a y0)
   1.117 +            z (.mult rot-a z0)
   1.118 +
   1.119 +            X (.mult rot-b x0)
   1.120 +            Y (.mult rot-b y0)
   1.121 +            Z (.mult rot-b z0)
   1.122 +            heading  (Math/atan2 (.dot X z) (.dot X x))
   1.123 +            pitch  (Math/atan2 (.dot X y) (.dot X x))
   1.124 +
   1.125 +            ;; rotate x-vector back to origin
   1.126 +            reverse
   1.127 +            (doto (Quaternion.)
   1.128 +              (.fromAngleAxis
   1.129 +               (.angleBetween X x)
   1.130 +               (let [cross (.normalize (.cross X x))]
   1.131 +                 (if (= 0 (.length cross)) y cross))))
   1.132 +            roll (absolute-angle (.mult reverse Y) y x)]
   1.133 +        [heading pitch roll]))))
   1.134 +
   1.135 +(defn proprioception!
   1.136 +  "Endow the creature with the sense of proprioception. Returns a
   1.137 +   sequence of functions, one for each child of the \"joints\" node in
   1.138 +   the creature, which each report proprioceptive information about
   1.139 +   that joint."
   1.140 +  [#^Node creature]
   1.141 +  ;; extract the body's joints
   1.142 +  (let [senses (map (partial proprioception-kernel creature)
   1.143 +                    (joints creature))]
   1.144 +    (fn []
   1.145 +      (map #(%) senses))))
   1.146 +    #+END_SRC
   1.147 +    #+end_listing
   1.148 +
   1.149 +
   1.150 +    =proprioception!= maps =proprioception-kernel= across all the
   1.151 +    joints of the creature. It uses the same list of joints that
   1.152 +    =joints= uses. Proprioception is the easiest sense to implement in
   1.153 +    =CORTEX=, and it will play a crucial role when efficiently
   1.154 +    implementing empathy.
   1.155 +
   1.156 +    #+caption: In the upper right corner, the three proprioceptive
   1.157 +    #+caption: angle measurements are displayed. Red is yaw, Green is 
   1.158 +    #+caption: pitch, and White is roll.
   1.159 +    #+name: proprio
   1.160 +    #+ATTR_LaTeX: :width 11cm
   1.161 +    [[./images/proprio.png]]
   1.162 +
   1.163  ** Muscles are both effectors and sensors
   1.164  
   1.165  ** =CORTEX= brings complex creatures to life!
     2.1 Binary file thesis/images/proprio.png has changed