# HG changeset patch # User Robert McIntyre # Date 1396063839 14400 # Node ID 6e68720e1c130c5be33397840e6a6d3385a30f76 # Parent ad76b8b05517a884cec50a9692588fcf317e1e28 add muscles. so STRONG right now. diff -r ad76b8b05517 -r 6e68720e1c13 thesis/cortex.org --- a/thesis/cortex.org Fri Mar 28 23:17:10 2014 -0400 +++ b/thesis/cortex.org Fri Mar 28 23:30:39 2014 -0400 @@ -2184,7 +2184,151 @@ #+ATTR_LaTeX: :width 11cm [[./images/proprio.png]] -** Muscles are both effectors and sensors +** COMMENT Muscles are both effectors and sensors + + Surprisingly enough, terrestrial creatures only move by using + torque applied about their joints. There's not a single straight + line of force in the human body at all! (A straight line of force + would correspond to some sort of jet or rocket propulsion.) + + In humans, muscles are composed of muscle fibers which can contract + to exert force. The muscle fibers which compose a muscle are + partitioned into discrete groups which are each controlled by a + single alpha motor neuron. A single alpha motor neuron might + control as little as three or as many as one thousand muscle + fibers. When the alpha motor neuron is engaged by the spinal cord, + it activates all of the muscle fibers to which it is attached. The + spinal cord generally engages the alpha motor neurons which control + few muscle fibers before the motor neurons which control many + muscle fibers. This recruitment strategy allows for precise + movements at low strength. The collection of all motor neurons that + control a muscle is called the motor pool. The brain essentially + says "activate 30% of the motor pool" and the spinal cord recruits + motor neurons until 30% are activated. Since the distribution of + power among motor neurons is unequal and recruitment goes from + weakest to strongest, the first 30% of the motor pool might be 5% + of the strength of the muscle. + + My simulated muscles follow a similar design: Each muscle is + defined by a 1-D array of numbers (the "motor pool"). Each entry in + the array represents a motor neuron which controls a number of + muscle fibers equal to the value of the entry. Each muscle has a + scalar strength factor which determines the total force the muscle + can exert when all motor neurons are activated. The effector + function for a muscle takes a number to index into the motor pool, + and then "activates" all the motor neurons whose index is lower or + equal to the number. Each motor-neuron will apply force in + proportion to its value in the array. Lower values cause less + force. The lower values can be put at the "beginning" of the 1-D + array to simulate the layout of actual human muscles, which are + capable of more precise movements when exerting less force. Or, the + motor pool can simulate more exotic recruitment strategies which do + not correspond to human muscles. + + This 1D array is defined in an image file for ease of + creation/visualization. Here is an example muscle profile image. + + #+caption: A muscle profile image that describes the strengths + #+caption: of each motor neuron in a muscle. White is weakest + #+caption: and dark red is strongest. This particular pattern + #+caption: has weaker motor neurons at the beginning, just + #+caption: like human muscle. + #+name: muscle-recruit + #+ATTR_LaTeX: :width 7cm + [[./images/basic-muscle.png]] + +*** Muscle meta-data + + #+caption: Program to deal with loading muscle data from a blender + #+caption: file's metadata. + #+name: motor-pool + #+begin_listing clojure + #+BEGIN_SRC clojure +(defn muscle-profile-image + "Get the muscle-profile image from the node's blender meta-data." + [#^Node muscle] + (if-let [image (meta-data muscle "muscle")] + (load-image image))) + +(defn muscle-strength + "Return the strength of this muscle, or 1 if it is not defined." + [#^Node muscle] + (if-let [strength (meta-data muscle "strength")] + strength 1)) + +(defn motor-pool + "Return a vector where each entry is the strength of the \"motor + neuron\" at that part in the muscle." + [#^Node muscle] + (let [profile (muscle-profile-image muscle)] + (vec + (let [width (.getWidth profile)] + (for [x (range width)] + (- 255 + (bit-and + 0x0000FF + (.getRGB profile x 0)))))))) + #+END_SRC + #+end_listing + + Of note here is =motor-pool= which interprets the muscle-profile + image in a way that allows me to use gradients between white and + red, instead of shades of gray as I've been using for all the + other senses. This is purely an aesthetic touch. + +*** Creating muscles + + #+caption: This is the core movement functoion in =CORTEX=, which + #+caption: implements muscles that report on their activation. + #+name: muscle-kernel + #+begin_listing clojure + #+BEGIN_SRC clojure +(defn movement-kernel + "Returns a function which when called with a integer value inside a + running simulation will cause movement in the creature according + to the muscle's position and strength profile. Each function + returns the amount of force applied / max force." + [#^Node creature #^Node muscle] + (let [target (closest-node creature muscle) + axis + (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) + strength (muscle-strength muscle) + + pool (motor-pool muscle) + pool-integral (reductions + pool) + forces + (vec (map #(float (* strength (/ % (last pool-integral)))) + pool-integral)) + control (.getControl target RigidBodyControl)] + ;;(println-repl (.getName target) axis) + (fn [n] + (let [pool-index (max 0 (min n (dec (count pool)))) + force (forces pool-index)] + (.applyTorque control (.mult axis force)) + (float (/ force strength)))))) + +(defn movement! + "Endow the creature with the power of movement. Returns a sequence + of functions, each of which accept an integer value and will + activate their corresponding muscle." + [#^Node creature] + (for [muscle (muscles creature)] + (movement-kernel creature muscle))) + #+END_SRC + #+end_listing + + + =movement-kernel= creates a function that will move the nearest + physical object to the muscle node. The muscle exerts a rotational + force dependent on it's orientation to the object in the blender + file. The function returned by =movement-kernel= is also a sense + function: it returns the percent of the total muscle strength that + is currently being employed. This is analogous to muscle tension + in humans and completes the sense of proprioception begun in the + last section. + + + ** =CORTEX= brings complex creatures to life! diff -r ad76b8b05517 -r 6e68720e1c13 thesis/images/basic-muscle.png Binary file thesis/images/basic-muscle.png has changed