changeset 481:6e68720e1c13

add muscles. so STRONG right now.
author Robert McIntyre <rlm@mit.edu>
date Fri, 28 Mar 2014 23:30:39 -0400
parents ad76b8b05517
children 074eadc919fe
files thesis/cortex.org thesis/images/basic-muscle.png
diffstat 2 files changed, 145 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/thesis/cortex.org	Fri Mar 28 23:17:10 2014 -0400
     1.2 +++ b/thesis/cortex.org	Fri Mar 28 23:30:39 2014 -0400
     1.3 @@ -2184,7 +2184,151 @@
     1.4      #+ATTR_LaTeX: :width 11cm
     1.5      [[./images/proprio.png]]
     1.6  
     1.7 -** Muscles are both effectors and sensors
     1.8 +** COMMENT Muscles are both effectors and sensors
     1.9 +
    1.10 +   Surprisingly enough, terrestrial creatures only move by using
    1.11 +   torque applied about their joints. There's not a single straight
    1.12 +   line of force in the human body at all! (A straight line of force
    1.13 +   would correspond to some sort of jet or rocket propulsion.)
    1.14 +   
    1.15 +   In humans, muscles are composed of muscle fibers which can contract
    1.16 +   to exert force. The muscle fibers which compose a muscle are
    1.17 +   partitioned into discrete groups which are each controlled by a
    1.18 +   single alpha motor neuron. A single alpha motor neuron might
    1.19 +   control as little as three or as many as one thousand muscle
    1.20 +   fibers. When the alpha motor neuron is engaged by the spinal cord,
    1.21 +   it activates all of the muscle fibers to which it is attached. The
    1.22 +   spinal cord generally engages the alpha motor neurons which control
    1.23 +   few muscle fibers before the motor neurons which control many
    1.24 +   muscle fibers. This recruitment strategy allows for precise
    1.25 +   movements at low strength. The collection of all motor neurons that
    1.26 +   control a muscle is called the motor pool. The brain essentially
    1.27 +   says "activate 30% of the motor pool" and the spinal cord recruits
    1.28 +   motor neurons until 30% are activated. Since the distribution of
    1.29 +   power among motor neurons is unequal and recruitment goes from
    1.30 +   weakest to strongest, the first 30% of the motor pool might be 5%
    1.31 +   of the strength of the muscle.
    1.32 +   
    1.33 +   My simulated muscles follow a similar design: Each muscle is
    1.34 +   defined by a 1-D array of numbers (the "motor pool"). Each entry in
    1.35 +   the array represents a motor neuron which controls a number of
    1.36 +   muscle fibers equal to the value of the entry. Each muscle has a
    1.37 +   scalar strength factor which determines the total force the muscle
    1.38 +   can exert when all motor neurons are activated. The effector
    1.39 +   function for a muscle takes a number to index into the motor pool,
    1.40 +   and then "activates" all the motor neurons whose index is lower or
    1.41 +   equal to the number. Each motor-neuron will apply force in
    1.42 +   proportion to its value in the array. Lower values cause less
    1.43 +   force. The lower values can be put at the "beginning" of the 1-D
    1.44 +   array to simulate the layout of actual human muscles, which are
    1.45 +   capable of more precise movements when exerting less force. Or, the
    1.46 +   motor pool can simulate more exotic recruitment strategies which do
    1.47 +   not correspond to human muscles.
    1.48 +   
    1.49 +   This 1D array is defined in an image file for ease of
    1.50 +   creation/visualization. Here is an example muscle profile image.
    1.51 +
    1.52 +   #+caption: A muscle profile image that describes the strengths
    1.53 +   #+caption: of each motor neuron in a muscle. White is weakest 
    1.54 +   #+caption: and dark red is strongest. This particular pattern 
    1.55 +   #+caption: has weaker motor neurons at the beginning, just 
    1.56 +   #+caption: like human muscle.
    1.57 +   #+name: muscle-recruit
    1.58 +   #+ATTR_LaTeX: :width 7cm
    1.59 +   [[./images/basic-muscle.png]]
    1.60 +
    1.61 +*** Muscle meta-data
    1.62 +
    1.63 +    #+caption: Program to deal with loading muscle data from a blender
    1.64 +    #+caption: file's metadata.
    1.65 +    #+name: motor-pool
    1.66 +    #+begin_listing clojure
    1.67 +    #+BEGIN_SRC clojure
    1.68 +(defn muscle-profile-image
    1.69 +  "Get the muscle-profile image from the node's blender meta-data."
    1.70 +  [#^Node muscle]
    1.71 +  (if-let [image (meta-data muscle "muscle")]
    1.72 +    (load-image image)))
    1.73 +
    1.74 +(defn muscle-strength
    1.75 +  "Return the strength of this muscle, or 1 if it is not defined."
    1.76 +  [#^Node muscle]
    1.77 +  (if-let [strength (meta-data muscle "strength")]
    1.78 +    strength 1))
    1.79 +
    1.80 +(defn motor-pool
    1.81 +  "Return a vector where each entry is the strength of the \"motor
    1.82 +   neuron\" at that part in the muscle."
    1.83 +  [#^Node muscle]
    1.84 +  (let [profile (muscle-profile-image muscle)]
    1.85 +    (vec
    1.86 +     (let [width (.getWidth profile)]
    1.87 +       (for [x (range width)]
    1.88 +       (- 255
    1.89 +          (bit-and
    1.90 +           0x0000FF
    1.91 +           (.getRGB profile x 0))))))))
    1.92 +    #+END_SRC
    1.93 +    #+end_listing
    1.94 +
    1.95 +    Of note here is =motor-pool= which interprets the muscle-profile
    1.96 +    image in a way that allows me to use gradients between white and
    1.97 +    red, instead of shades of gray as I've been using for all the
    1.98 +    other senses. This is purely an aesthetic touch.
    1.99 +
   1.100 +*** Creating muscles
   1.101 +
   1.102 +    #+caption: This is the core movement functoion in =CORTEX=, which
   1.103 +    #+caption: implements muscles that report on their activation.
   1.104 +    #+name: muscle-kernel
   1.105 +    #+begin_listing clojure
   1.106 +    #+BEGIN_SRC clojure
   1.107 +(defn movement-kernel
   1.108 +  "Returns a function which when called with a integer value inside a
   1.109 +   running simulation will cause movement in the creature according
   1.110 +   to the muscle's position and strength profile. Each function
   1.111 +   returns the amount of force applied / max force."
   1.112 +  [#^Node creature #^Node muscle]
   1.113 +  (let [target (closest-node creature muscle)
   1.114 +        axis
   1.115 +        (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y)
   1.116 +        strength (muscle-strength muscle)
   1.117 +        
   1.118 +        pool (motor-pool muscle)
   1.119 +        pool-integral (reductions + pool)
   1.120 +        forces
   1.121 +        (vec (map  #(float (* strength (/ % (last pool-integral))))
   1.122 +              pool-integral))
   1.123 +        control (.getControl target RigidBodyControl)]
   1.124 +    ;;(println-repl (.getName target) axis)
   1.125 +    (fn [n]
   1.126 +      (let [pool-index (max 0 (min n (dec (count pool))))
   1.127 +            force (forces pool-index)]
   1.128 +        (.applyTorque control (.mult axis force))
   1.129 +        (float (/ force strength))))))
   1.130 +
   1.131 +(defn movement!
   1.132 +  "Endow the creature with the power of movement. Returns a sequence
   1.133 +   of functions, each of which accept an integer value and will
   1.134 +   activate their corresponding muscle."
   1.135 +  [#^Node creature]
   1.136 +    (for [muscle (muscles creature)]
   1.137 +      (movement-kernel creature muscle)))
   1.138 +    #+END_SRC
   1.139 +    #+end_listing
   1.140 +
   1.141 +
   1.142 +    =movement-kernel= creates a function that will move the nearest
   1.143 +    physical object to the muscle node. The muscle exerts a rotational
   1.144 +    force dependent on it's orientation to the object in the blender
   1.145 +    file. The function returned by =movement-kernel= is also a sense
   1.146 +    function: it returns the percent of the total muscle strength that
   1.147 +    is currently being employed. This is analogous to muscle tension
   1.148 +    in humans and completes the sense of proprioception begun in the
   1.149 +    last section.
   1.150 +
   1.151 +
   1.152 +
   1.153  
   1.154  ** =CORTEX= brings complex creatures to life!
   1.155  
     2.1 Binary file thesis/images/basic-muscle.png has changed