Mercurial > cortex
comparison thesis/cortex.org @ 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 |
comparison
equal
deleted
inserted
replaced
480:ad76b8b05517 | 481:6e68720e1c13 |
---|---|
2182 #+caption: pitch, and White is roll. | 2182 #+caption: pitch, and White is roll. |
2183 #+name: proprio | 2183 #+name: proprio |
2184 #+ATTR_LaTeX: :width 11cm | 2184 #+ATTR_LaTeX: :width 11cm |
2185 [[./images/proprio.png]] | 2185 [[./images/proprio.png]] |
2186 | 2186 |
2187 ** Muscles are both effectors and sensors | 2187 ** COMMENT Muscles are both effectors and sensors |
2188 | |
2189 Surprisingly enough, terrestrial creatures only move by using | |
2190 torque applied about their joints. There's not a single straight | |
2191 line of force in the human body at all! (A straight line of force | |
2192 would correspond to some sort of jet or rocket propulsion.) | |
2193 | |
2194 In humans, muscles are composed of muscle fibers which can contract | |
2195 to exert force. The muscle fibers which compose a muscle are | |
2196 partitioned into discrete groups which are each controlled by a | |
2197 single alpha motor neuron. A single alpha motor neuron might | |
2198 control as little as three or as many as one thousand muscle | |
2199 fibers. When the alpha motor neuron is engaged by the spinal cord, | |
2200 it activates all of the muscle fibers to which it is attached. The | |
2201 spinal cord generally engages the alpha motor neurons which control | |
2202 few muscle fibers before the motor neurons which control many | |
2203 muscle fibers. This recruitment strategy allows for precise | |
2204 movements at low strength. The collection of all motor neurons that | |
2205 control a muscle is called the motor pool. The brain essentially | |
2206 says "activate 30% of the motor pool" and the spinal cord recruits | |
2207 motor neurons until 30% are activated. Since the distribution of | |
2208 power among motor neurons is unequal and recruitment goes from | |
2209 weakest to strongest, the first 30% of the motor pool might be 5% | |
2210 of the strength of the muscle. | |
2211 | |
2212 My simulated muscles follow a similar design: Each muscle is | |
2213 defined by a 1-D array of numbers (the "motor pool"). Each entry in | |
2214 the array represents a motor neuron which controls a number of | |
2215 muscle fibers equal to the value of the entry. Each muscle has a | |
2216 scalar strength factor which determines the total force the muscle | |
2217 can exert when all motor neurons are activated. The effector | |
2218 function for a muscle takes a number to index into the motor pool, | |
2219 and then "activates" all the motor neurons whose index is lower or | |
2220 equal to the number. Each motor-neuron will apply force in | |
2221 proportion to its value in the array. Lower values cause less | |
2222 force. The lower values can be put at the "beginning" of the 1-D | |
2223 array to simulate the layout of actual human muscles, which are | |
2224 capable of more precise movements when exerting less force. Or, the | |
2225 motor pool can simulate more exotic recruitment strategies which do | |
2226 not correspond to human muscles. | |
2227 | |
2228 This 1D array is defined in an image file for ease of | |
2229 creation/visualization. Here is an example muscle profile image. | |
2230 | |
2231 #+caption: A muscle profile image that describes the strengths | |
2232 #+caption: of each motor neuron in a muscle. White is weakest | |
2233 #+caption: and dark red is strongest. This particular pattern | |
2234 #+caption: has weaker motor neurons at the beginning, just | |
2235 #+caption: like human muscle. | |
2236 #+name: muscle-recruit | |
2237 #+ATTR_LaTeX: :width 7cm | |
2238 [[./images/basic-muscle.png]] | |
2239 | |
2240 *** Muscle meta-data | |
2241 | |
2242 #+caption: Program to deal with loading muscle data from a blender | |
2243 #+caption: file's metadata. | |
2244 #+name: motor-pool | |
2245 #+begin_listing clojure | |
2246 #+BEGIN_SRC clojure | |
2247 (defn muscle-profile-image | |
2248 "Get the muscle-profile image from the node's blender meta-data." | |
2249 [#^Node muscle] | |
2250 (if-let [image (meta-data muscle "muscle")] | |
2251 (load-image image))) | |
2252 | |
2253 (defn muscle-strength | |
2254 "Return the strength of this muscle, or 1 if it is not defined." | |
2255 [#^Node muscle] | |
2256 (if-let [strength (meta-data muscle "strength")] | |
2257 strength 1)) | |
2258 | |
2259 (defn motor-pool | |
2260 "Return a vector where each entry is the strength of the \"motor | |
2261 neuron\" at that part in the muscle." | |
2262 [#^Node muscle] | |
2263 (let [profile (muscle-profile-image muscle)] | |
2264 (vec | |
2265 (let [width (.getWidth profile)] | |
2266 (for [x (range width)] | |
2267 (- 255 | |
2268 (bit-and | |
2269 0x0000FF | |
2270 (.getRGB profile x 0)))))))) | |
2271 #+END_SRC | |
2272 #+end_listing | |
2273 | |
2274 Of note here is =motor-pool= which interprets the muscle-profile | |
2275 image in a way that allows me to use gradients between white and | |
2276 red, instead of shades of gray as I've been using for all the | |
2277 other senses. This is purely an aesthetic touch. | |
2278 | |
2279 *** Creating muscles | |
2280 | |
2281 #+caption: This is the core movement functoion in =CORTEX=, which | |
2282 #+caption: implements muscles that report on their activation. | |
2283 #+name: muscle-kernel | |
2284 #+begin_listing clojure | |
2285 #+BEGIN_SRC clojure | |
2286 (defn movement-kernel | |
2287 "Returns a function which when called with a integer value inside a | |
2288 running simulation will cause movement in the creature according | |
2289 to the muscle's position and strength profile. Each function | |
2290 returns the amount of force applied / max force." | |
2291 [#^Node creature #^Node muscle] | |
2292 (let [target (closest-node creature muscle) | |
2293 axis | |
2294 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) | |
2295 strength (muscle-strength muscle) | |
2296 | |
2297 pool (motor-pool muscle) | |
2298 pool-integral (reductions + pool) | |
2299 forces | |
2300 (vec (map #(float (* strength (/ % (last pool-integral)))) | |
2301 pool-integral)) | |
2302 control (.getControl target RigidBodyControl)] | |
2303 ;;(println-repl (.getName target) axis) | |
2304 (fn [n] | |
2305 (let [pool-index (max 0 (min n (dec (count pool)))) | |
2306 force (forces pool-index)] | |
2307 (.applyTorque control (.mult axis force)) | |
2308 (float (/ force strength)))))) | |
2309 | |
2310 (defn movement! | |
2311 "Endow the creature with the power of movement. Returns a sequence | |
2312 of functions, each of which accept an integer value and will | |
2313 activate their corresponding muscle." | |
2314 [#^Node creature] | |
2315 (for [muscle (muscles creature)] | |
2316 (movement-kernel creature muscle))) | |
2317 #+END_SRC | |
2318 #+end_listing | |
2319 | |
2320 | |
2321 =movement-kernel= creates a function that will move the nearest | |
2322 physical object to the muscle node. The muscle exerts a rotational | |
2323 force dependent on it's orientation to the object in the blender | |
2324 file. The function returned by =movement-kernel= is also a sense | |
2325 function: it returns the percent of the total muscle strength that | |
2326 is currently being employed. This is analogous to muscle tension | |
2327 in humans and completes the sense of proprioception begun in the | |
2328 last section. | |
2329 | |
2330 | |
2331 | |
2188 | 2332 |
2189 ** =CORTEX= brings complex creatures to life! | 2333 ** =CORTEX= brings complex creatures to life! |
2190 | 2334 |
2191 ** =CORTEX= enables many possiblities for further research | 2335 ** =CORTEX= enables many possiblities for further research |
2192 | 2336 |