annotate org/movement.org @ 187:6142e85f5825

extracted common elements of display code
author Robert McIntyre <rlm@mit.edu>
date Sat, 04 Feb 2012 09:42:19 -0700
parents 0f1c7921d967
children 66fbab414d45
rev   line source
rlm@158 1 #+title: Movement!
rlm@158 2 #+author: Robert McIntyre
rlm@158 3 #+email: rlm@mit.edu
rlm@158 4 #+description: muscles for a simulated creature
rlm@158 5 #+keywords: simulation, jMonkeyEngine3, clojure
rlm@158 6 #+SETUPFILE: ../../aurellem/org/setup.org
rlm@158 7 #+INCLUDE: ../../aurellem/org/level-0.org
rlm@158 8
rlm@180 9
rlm@180 10 Surprisingly enough, terristerial creatures only move by using torque
rlm@180 11 applied about their joints. There's not a single straight line of
rlm@180 12 force in the human body at all! (A straight line of force would
rlm@180 13 correspond to some sort of jet or rocket propulseion.)
rlm@180 14
rlm@180 15
rlm@180 16 Here's how motor-control/ proprioception will work: Each muscle is
rlm@180 17 defined by a 1-D array of numbers (the "motor pool") each of which
rlm@180 18 represent muscle fibers. A muscle also has a scalar :strength factor
rlm@180 19 which determines how strong the muscle as a whole is. The effector
rlm@180 20 function for a muscle takes a number < (count motor-pool) and that
rlm@180 21 number is said to "activate" all the muscle fibers whose index is
rlm@180 22 lower than the number. Each fiber will apply force in proportion to
rlm@180 23 its value in the array. Lower values cause less force. The lower
rlm@180 24 values can be put at the "beginning" of the 1-D array to simulate the
rlm@180 25 layout of actual human muscles, which are capable of more percise
rlm@180 26 movements when exerting less force.
rlm@180 27
rlm@158 28 #+name: movement
rlm@158 29 #+begin_src clojure
rlm@158 30 (ns cortex.movement
rlm@180 31 "Give simulated creatures defined in special blender files the power
rlm@180 32 to move around in a simulated environment."
rlm@180 33 {:author "Robert McIntyre"}
rlm@158 34 (:use (cortex world util sense body))
rlm@180 35 (:use clojure.contrib.def)
rlm@180 36 (:import java.awt.image.BufferedImage)
rlm@180 37 (:import com.jme3.scene.Node)
rlm@180 38 (:import com.jme3.math.Vector3f)
rlm@180 39 (:import com.jme3.bullet.control.RigidBodyControl))
rlm@158 40
rlm@180 41 (defn muscle-profile
rlm@180 42 "Return a vector where each entry is the strength of the \"motor
rlm@180 43 pool\" at that part in the muscle."
rlm@180 44 [#^BufferedImage profile]
rlm@158 45 (vec
rlm@180 46 (let [width (.getWidth profile)]
rlm@158 47 (for [x (range width)]
rlm@158 48 (- 255
rlm@158 49 (bit-and
rlm@158 50 0x0000FF
rlm@180 51 (.getRGB profile x 0)))))))
rlm@158 52
rlm@180 53 (defvar
rlm@180 54 ^{:arglists '([creature])}
rlm@180 55 muscles
rlm@180 56 (sense-nodes "muscles")
rlm@180 57 "Return the children of the creature's \"muscles\" node.")
rlm@158 58
rlm@180 59 (defn movement-fn
rlm@180 60 "Returns a function which when called with a integer value inside a
rlm@180 61 running simulation, will cause movement in the creature according
rlm@180 62 to the muscle's position and strength profile"
rlm@180 63 [#^Node parts #^Node muscle]
rlm@158 64 (let [target (closest-node parts muscle)
rlm@158 65 axis
rlm@158 66 (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y)
rlm@158 67 strength (meta-data muscle "strength")
rlm@158 68 image-name (read-string (meta-data muscle "muscle"))
rlm@180 69 image (load-image image-name)
rlm@180 70 fibers (muscle-profile image)
rlm@158 71 fiber-integral (reductions + fibers)
rlm@158 72 force-index (vec
rlm@158 73 (map
rlm@158 74 #(float (* strength (/ % (last
rlm@158 75 fiber-integral))))
rlm@158 76 fiber-integral))
rlm@158 77 control (.getControl target RigidBodyControl)]
rlm@158 78 (fn [n]
rlm@158 79 (let [pool-index (min n (count fibers))]
rlm@158 80 (.applyTorque control (.mult axis (force-index n)))))))
rlm@158 81
rlm@180 82 (defn movement!
rlm@180 83 "Endow the creature with the power of movement. Returns a sequence
rlm@180 84 of functions, each of which accept an integer value and will
rlm@180 85 activate their corresponding muscle."
rlm@158 86 [#^Node creature]
rlm@180 87 (for [muscle (muscles creature)]
rlm@180 88 (movement-fn creature muscle)))
rlm@158 89
rlm@158 90 #+end_src
rlm@158 91
rlm@158 92
rlm@158 93
rlm@158 94
rlm@158 95
rlm@158 96 * COMMENT code generation
rlm@158 97 #+begin_src clojure :tangle ../src/cortex/movement.clj
rlm@158 98 <<movement>>
rlm@158 99 #+end_src