Mercurial > cortex
changeset 158:811127d79d24
refactored muscles
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 03 Feb 2012 06:33:37 -0700 |
parents | 84c67be00abe |
children | 75b6c2ebbf8e |
files | org/movement.org org/test-creature.org |
diffstat | 2 files changed, 101 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/org/movement.org Fri Feb 03 06:33:37 2012 -0700 1.3 @@ -0,0 +1,98 @@ 1.4 +#+title: Movement! 1.5 +#+author: Robert McIntyre 1.6 +#+email: rlm@mit.edu 1.7 +#+description: muscles for a simulated creature 1.8 +#+keywords: simulation, jMonkeyEngine3, clojure 1.9 +#+SETUPFILE: ../../aurellem/org/setup.org 1.10 +#+INCLUDE: ../../aurellem/org/level-0.org 1.11 + 1.12 +#+name: movement 1.13 +#+begin_src clojure 1.14 +(ns cortex.movement 1.15 + (:use (cortex world util sense body)) 1.16 + (:import jme3tools.converters.ImageToAwt) 1.17 + (:import java.awt.image.BufferedImage)) 1.18 + 1.19 +(cortex.import/mega-import-jme3) 1.20 + 1.21 + 1.22 + 1.23 + 1.24 +;; here's how motor-control/ proprioception will work: Each muscle is 1.25 +;; defined by a 1-D array of numbers (the "motor pool") each of which 1.26 +;; represent muscle fibers. A muscle also has a scalar :strength 1.27 +;; factor which determines how strong the muscle as a whole is. 1.28 +;; The effector function for a muscle takes a number < (count 1.29 +;; motor-pool) and that number is said to "activate" all the muscle 1.30 +;; fibers whose index is lower than the number. Each fiber will apply 1.31 +;; force in proportion to its value in the array. Lower values cause 1.32 +;; less force. The lower values can be put at the "beginning" of the 1.33 +;; 1-D array to simulate the layout of actual human muscles, which are 1.34 +;; capable of more percise movements when exerting less force. 1.35 + 1.36 +;; I don't know how to encode proprioception, so for now, just return 1.37 +;; a function for each joint that returns a triplet of floats which 1.38 +;; represent relative roll, pitch, and yaw. Write display code for 1.39 +;; this though. 1.40 + 1.41 +(defn muscle-fiber-values 1.42 + "get motor pool strengths" 1.43 + [#^BufferedImage image] 1.44 + (vec 1.45 + (let [width (.getWidth image)] 1.46 + (for [x (range width)] 1.47 + (- 255 1.48 + (bit-and 1.49 + 0x0000FF 1.50 + (.getRGB image x 0))))))) 1.51 + 1.52 + 1.53 +(defn creature-muscles 1.54 + "Return the children of the creature's \"muscles\" node." 1.55 + [#^Node creature] 1.56 + (if-let [muscle-node (.getChild creature "muscles")] 1.57 + (seq (.getChildren muscle-node)) 1.58 + (do (println-repl "could not find muscles node") []))) 1.59 + 1.60 +(defn single-muscle [#^Node parts #^Node muscle] 1.61 + (let [target (closest-node parts muscle) 1.62 + axis 1.63 + (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) 1.64 + strength (meta-data muscle "strength") 1.65 + image-name (read-string (meta-data muscle "muscle")) 1.66 + image 1.67 + (ImageToAwt/convert 1.68 + (.getImage (.loadTexture (asset-manager) image-name)) 1.69 + false false 0) 1.70 + fibers (muscle-fiber-values image) 1.71 + fiber-integral (reductions + fibers) 1.72 + force-index (vec 1.73 + (map 1.74 + #(float (* strength (/ % (last 1.75 + fiber-integral)))) 1.76 + fiber-integral)) 1.77 + control (.getControl target RigidBodyControl)] 1.78 + (fn [n] 1.79 + (let [pool-index (min n (count fibers))] 1.80 + (.applyTorque control (.mult axis (force-index n))))))) 1.81 + 1.82 + 1.83 +(defn enable-muscles 1.84 + "Must be called on a creature after RigidBodyControls have been 1.85 + created." 1.86 + [#^Node creature] 1.87 + (let [muscles (creature-muscles creature)] 1.88 + (for [muscle muscles] 1.89 + (single-muscle creature muscle)))) 1.90 + 1.91 + 1.92 +#+end_src 1.93 + 1.94 + 1.95 + 1.96 + 1.97 + 1.98 +* COMMENT code generation 1.99 +#+begin_src clojure :tangle ../src/cortex/movement.clj 1.100 +<<movement>> 1.101 +#+end_src
2.1 --- a/org/test-creature.org Fri Feb 03 06:21:39 2012 -0700 2.2 +++ b/org/test-creature.org Fri Feb 03 06:33:37 2012 -0700 2.3 @@ -38,7 +38,7 @@ 2.4 the connecting here in clojure code, using the names of the individual 2.5 components and trial and error. Later, I'll maybe make some sort of 2.6 creature-building modifications to blender that support whatever 2.7 -discreitized senses I'm going to make. 2.8 +discritized senses I'm going to make. 2.9 2.10 #+name: body-1 2.11 #+begin_src clojure 2.12 @@ -49,7 +49,8 @@ 2.13 ;; TODO remove this! 2.14 (require 'cortex.import) 2.15 (cortex.import/mega-import-jme3) 2.16 -(use '(cortex world util body hearing touch vision sense proprioception)) 2.17 +(use '(cortex world util body hearing touch vision sense 2.18 +proprioception movement)) 2.19 2.20 (rlm.rlm-commands/help) 2.21 (import java.awt.image.BufferedImage) 2.22 @@ -421,72 +422,6 @@ 2.23 2.24 2.25 2.26 -;; here's how motor-control/ proprioception will work: Each muscle is 2.27 -;; defined by a 1-D array of numbers (the "motor pool") each of which 2.28 -;; represent muscle fibers. A muscle also has a scalar :strength 2.29 -;; factor which determines how strong the muscle as a whole is. 2.30 -;; The effector function for a muscle takes a number < (count 2.31 -;; motor-pool) and that number is said to "activate" all the muscle 2.32 -;; fibers whose index is lower than the number. Each fiber will apply 2.33 -;; force in proportion to its value in the array. Lower values cause 2.34 -;; less force. The lower values can be put at the "beginning" of the 2.35 -;; 1-D array to simulate the layout of actual human muscles, which are 2.36 -;; capable of more percise movements when exerting less force. 2.37 - 2.38 -;; I don't know how to encode proprioception, so for now, just return 2.39 -;; a function for each joint that returns a triplet of floats which 2.40 -;; represent relative roll, pitch, and yaw. Write display code for 2.41 -;; this though. 2.42 - 2.43 -(defn muscle-fiber-values 2.44 - "get motor pool strengths" 2.45 - [#^BufferedImage image] 2.46 - (vec 2.47 - (let [width (.getWidth image)] 2.48 - (for [x (range width)] 2.49 - (- 255 2.50 - (bit-and 2.51 - 0x0000FF 2.52 - (.getRGB image x 0))))))) 2.53 - 2.54 - 2.55 -(defn creature-muscles 2.56 - "Return the children of the creature's \"muscles\" node." 2.57 - [#^Node creature] 2.58 - (if-let [muscle-node (.getChild creature "muscles")] 2.59 - (seq (.getChildren muscle-node)) 2.60 - (do (println-repl "could not find muscles node") []))) 2.61 - 2.62 -(defn single-muscle [#^Node parts #^Node muscle] 2.63 - (let [target (closest-node parts muscle) 2.64 - axis 2.65 - (.mult (.getWorldRotation muscle) Vector3f/UNIT_Y) 2.66 - strength (meta-data muscle "strength") 2.67 - image-name (read-string (meta-data muscle "muscle")) 2.68 - image 2.69 - (ImageToAwt/convert 2.70 - (.getImage (.loadTexture (asset-manager) image-name)) 2.71 - false false 0) 2.72 - fibers (muscle-fiber-values image) 2.73 - fiber-integral (reductions + fibers) 2.74 - force-index (vec 2.75 - (map 2.76 - #(float (* strength (/ % (last 2.77 - fiber-integral)))) 2.78 - fiber-integral)) 2.79 - control (.getControl target RigidBodyControl)] 2.80 - (fn [n] 2.81 - (let [pool-index (min n (count fibers))] 2.82 - (.applyTorque control (.mult axis (force-index n))))))) 2.83 - 2.84 - 2.85 -(defn enable-muscles 2.86 - "Must be called on a creature after RigidBodyControls have been 2.87 - created." 2.88 - [#^Node creature] 2.89 - (let [muscles (creature-muscles creature)] 2.90 - (for [muscle muscles] 2.91 - (single-muscle creature muscle)))) 2.92 2.93 (defn test-creature [thing] 2.94 (let [x-axis