Mercurial > cortex
changeset 64:ab1fee4280c3
divided body into test suite and core functions
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 30 Nov 2011 20:42:07 -0700 |
parents | 7f2653ad3199 |
children | 4b5f00110d8c |
files | org/body.org |
diffstat | 1 files changed, 113 insertions(+), 117 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/org/body.org Tue Nov 29 02:46:46 2011 -0700 1.2 +++ b/org/body.org Wed Nov 30 20:42:07 2011 -0700 1.3 @@ -5,90 +5,21 @@ 1.4 #+SETUPFILE: ../../aurellem/org/setup.org 1.5 #+INCLUDE: ../../aurellem/org/level-0.org 1.6 1.7 -* COMMENT Body 1.8 1.9 -#+srcname: body-main 1.10 + 1.11 +* Proprioception 1.12 +#+srcname: proprioception 1.13 #+begin_src clojure 1.14 (ns cortex.body 1.15 - (use (cortex world util import))) 1.16 + (:use (cortex world util)) 1.17 + (:import 1.18 + com.jme3.math.Vector3f 1.19 + com.jme3.math.Quaternion 1.20 + com.jme3.math.Vector2f 1.21 + com.jme3.math.Matrix3f 1.22 + com.jme3.bullet.control.RigidBodyControl)) 1.23 1.24 -(use 'clojure.contrib.def) 1.25 -(cortex.import/mega-import-jme3) 1.26 -(rlm.rlm-commands/help) 1.27 - 1.28 -(defn load-blender-model 1.29 - "Load a .blend file using an asset folder relative path." 1.30 - [^String model] 1.31 - (.loadModel 1.32 - (doto (asset-manager) 1.33 - (.registerLoader BlenderModelLoader (into-array String ["blend"]))) 1.34 - model)) 1.35 - 1.36 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.37 - 1.38 -;;;;;;;;;;;; eve-style bodies ;;;;;;;; 1.39 - 1.40 -(defn worm-segments 1.41 - "Create multiple evenly spaced box segments. They're fabulous!" 1.42 - [segment-length num-segments interstitial-space radius] 1.43 - (letfn [(nth-segment 1.44 - [n] 1.45 - (box segment-length radius radius :mass 0.1 1.46 - :position 1.47 - (Vector3f. 1.48 - (* 2 n (+ interstitial-space segment-length)) 0 0) 1.49 - :name (str "worm-segment" n) 1.50 - :color (ColorRGBA/randomColor)))] 1.51 - (map nth-segment (range num-segments)))) 1.52 - 1.53 -(defn connect-at-midpoint 1.54 - "Connect two physics objects with a Point2Point joint constraint at 1.55 - the point equidistant from both objects' centers." 1.56 - [segmentA segmentB] 1.57 - (let [centerA (.getWorldTranslation segmentA) 1.58 - centerB (.getWorldTranslation segmentB) 1.59 - midpoint (.mult (.add centerA centerB) (float 0.5)) 1.60 - pivotA (.subtract midpoint centerA) 1.61 - pivotB (.subtract midpoint centerB) 1.62 - 1.63 - ;; A side-effect of creating a joint registers 1.64 - ;; it with both physics objects which in turn 1.65 - ;; will register the joint with the physics system 1.66 - ;; when the simulation is started. 1.67 - joint (Point2PointJoint. 1.68 - (.getControl segmentA RigidBodyControl) 1.69 - (.getControl segmentB RigidBodyControl) 1.70 - pivotA 1.71 - pivotB)] 1.72 - segmentB)) 1.73 - 1.74 -(defn point-worm [] 1.75 - (let [segments (worm-segments 0.2 5 0.1 0.1)] 1.76 - (dorun (map (partial apply connect-at-midpoint) 1.77 - (partition 2 1 segments))) 1.78 - (nodify "worm" segments))) 1.79 - 1.80 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.81 -;;;;;;;;; Proprioception ;;;;;;;;;;;;; 1.82 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.83 - 1.84 -(declare 1.85 - ;; generate an arbitray (but stable) orthogonal vector 1.86 - ;; to a given vector. 1.87 - some-orthogonal 1.88 - 1.89 - ;; determine the amount of rotation a quaternion will 1.90 - ;; cause about a given axis 1.91 - project-quaternion 1.92 - 1.93 - ;; proprioception for a single joint 1.94 - joint-proprioception 1.95 - 1.96 - ;; create a function that provides proprioceptive information 1.97 - ;; about an entire body. 1.98 - proprioception) 1.99 - 1.100 -(defn some-orthogonal 1.101 +(defn any-orthogonal 1.102 "Generate an arbitray (but stable) orthogonal vector to a given 1.103 vector." 1.104 [vector] 1.105 @@ -108,7 +39,7 @@ 1.106 Determine the amount of rotation a quaternion will 1.107 cause about a given axis." 1.108 [#^Quaternion q #^Vector3f axis] 1.109 - (let [basis-1 (orthogonal-vect axis) 1.110 + (let [basis-1 (any-orthogonal axis) 1.111 basis-2 (.cross axis basis-1) 1.112 rotated (.mult q basis-1) 1.113 alpha (.dot basis-1 (.project rotated basis-1)) 1.114 @@ -147,7 +78,7 @@ 1.115 (Vector2f. 1 0)) 1.116 1.117 roll 1.118 - (rot-about-axis 1.119 + (project-quaternion 1.120 (.mult 1.121 (.getLocalRotation object-b) 1.122 (doto (Quaternion.) 1.123 @@ -171,11 +102,11 @@ 1.124 (fn [] 1.125 (map joint-proprioception joints)))) 1.126 1.127 +#+end_src 1.128 1.129 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.130 -;;;;;;;;; Mortor Control ;;;;;;;;;;;;; 1.131 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.132 - 1.133 +#+srcname: motor-control 1.134 +#+begin_src clojure 1.135 +(in-ns 'cortex.body) 1.136 1.137 ;; surprisingly enough, terristerial creatures only move by using 1.138 ;; torque applied about their joints. There's not a single straight 1.139 @@ -191,29 +122,73 @@ 1.140 (fn [torques] 1.141 (map #(.applyTorque %1 %2) 1.142 controls torques)))) 1.143 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.144 +#+end_src 1.145 + 1.146 +## note -- might want to add a lower dimensional, discrete version of 1.147 +## this if it proves useful from a x-modal clustering perspective. 1.148 1.149 -;; note -- might want to add a lower dimensional, discrete version of 1.150 -;; this if it proves usefull from a x-modal clustering perspective. 1.151 +* Examples 1.152 1.153 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.154 +#+srcname: test-body 1.155 +#+begin_src clojure 1.156 +(ns test.body 1.157 + (:use (cortex world util body)) 1.158 + (:import 1.159 + com.jme3.math.Vector3f 1.160 + com.jme3.math.ColorRGBA 1.161 + com.jme3.bullet.joints.Point2PointJoint 1.162 + com.jme3.bullet.control.RigidBodyControl 1.163 + com.jme3.system.NanoTimer)) 1.164 1.165 +(defn worm-segments 1.166 + "Create multiple evenly spaced box segments. They're fabulous!" 1.167 + [segment-length num-segments interstitial-space radius] 1.168 + (letfn [(nth-segment 1.169 + [n] 1.170 + (box segment-length radius radius :mass 0.1 1.171 + :position 1.172 + (Vector3f. 1.173 + (* 2 n (+ interstitial-space segment-length)) 0 0) 1.174 + :name (str "worm-segment" n) 1.175 + :color (ColorRGBA/randomColor)))] 1.176 + (map nth-segment (range num-segments)))) 1.177 1.178 +(defn connect-at-midpoint 1.179 + "Connect two physics objects with a Point2Point joint constraint at 1.180 + the point equidistant from both objects' centers." 1.181 + [segmentA segmentB] 1.182 + (let [centerA (.getWorldTranslation segmentA) 1.183 + centerB (.getWorldTranslation segmentB) 1.184 + midpoint (.mult (.add centerA centerB) (float 0.5)) 1.185 + pivotA (.subtract midpoint centerA) 1.186 + pivotB (.subtract midpoint centerB) 1.187 + 1.188 + ;; A side-effect of creating a joint registers 1.189 + ;; it with both physics objects which in turn 1.190 + ;; will register the joint with the physics system 1.191 + ;; when the simulation is started. 1.192 + joint (Point2PointJoint. 1.193 + (.getControl segmentA RigidBodyControl) 1.194 + (.getControl segmentB RigidBodyControl) 1.195 + pivotA 1.196 + pivotB)] 1.197 + segmentB)) 1.198 1.199 -(defn worm-pattern [time] 1.200 - [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.201 +(defn eve-worm 1.202 + "Create a worm body bound by invisible joint constraints." 1.203 + [] 1.204 + (let [segments (worm-segments 0.2 5 0.1 0.1)] 1.205 + (dorun (map (partial apply connect-at-midpoint) 1.206 + (partition 2 1 segments))) 1.207 + (nodify "worm" segments))) 1.208 1.209 - 0 0 0 0 0 0 0 0 0 0 0 1.210 - 1.211 - (* 20 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))) 1.212 - 1.213 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.214 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.215 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.216 - 1.217 - ]) 1.218 - 1.219 -(defn worm-pattern [time] 1.220 - (let [angle (* Math/PI (/ 4 20)) 1.221 +(defn worm-pattern 1.222 + "This is a simple, mindless motor control pattern that drives the 1.223 + second segment of the worm's body at an offset angle with 1.224 + sinusoidally varying strength." 1.225 + [time] 1.226 + (let [angle (* Math/PI (/ 9 20)) 1.227 direction (Vector3f. 0 (Math/sin angle) (Math/cos angle))] 1.228 [Vector3f/ZERO 1.229 (.mult 1.230 @@ -223,9 +198,11 @@ 1.231 Vector3f/ZERO 1.232 Vector3f/ZERO])) 1.233 1.234 -(defn test-worm-control 1.235 +(defn test-motor-control 1.236 + "You should see a multi-segmented worm-like object fall onto the 1.237 + table and begin writhing and moving." 1.238 [] 1.239 - (let [worm (point-worm) 1.240 + (let [worm (eve-worm) 1.241 time (atom 0) 1.242 worm-motor-map (vector-motor-control worm)] 1.243 (world 1.244 @@ -244,15 +221,16 @@ 1.245 1.246 (fn [_ _] 1.247 (swap! time inc) 1.248 - ;;(Thread/sleep 200) 1.249 + (Thread/sleep 20) 1.250 (dorun (worm-motor-map 1.251 (worm-pattern @time))))))) 1.252 1.253 - 1.254 - 1.255 - 1.256 -(defn test-prop 1.257 - "see how torque works." 1.258 +(defn test-proprioception 1.259 + "You should see two foating bars, and a printout of pitch, yaw, and 1.260 + roll. Pressing key-r/key-t should move the blue bar up and down and 1.261 + change only the value of pitch. key-f/key-g moves it side to side 1.262 + and changes yaw. key-v/key-b will spin the blue segment clockwise 1.263 + and counterclockwise, and only affect roll." 1.264 [] 1.265 (let [hand (box 1 0.2 0.2 :position (Vector3f. 0 2 0) 1.266 :mass 0 :color ColorRGBA/Green) 1.267 @@ -276,8 +254,7 @@ 1.268 (Vector3f. 1.2 0 0) 1.269 (Vector3f. -1.2 0 0 )) 1.270 (.setCollisionBetweenLinkedBodys false)) 1.271 - time (atom 0) 1.272 - ] 1.273 + time (atom 0)] 1.274 (world 1.275 (nodify [hand finger floor]) 1.276 (merge standard-debug-controls 1.277 @@ -327,9 +304,12 @@ 1.278 (comp 1.279 println-repl 1.280 #(format "pitch: %1.2f\nyaw: %1.2f\nroll: %1.2f\n" %1 %2 %3)) 1.281 - (relative-positions joint)))))))) 1.282 + (joint-proprioception joint)))))))) 1.283 +#+end_src 1.284 1.285 -#+end_src 1.286 +#+results: test-body 1.287 +: #'test.body/test-proprioception 1.288 + 1.289 1.290 1.291 * COMMENT code-limbo 1.292 @@ -339,6 +319,16 @@ 1.293 ;; (.registerLoader BlenderModelLoader (into-array String ["blend"]))) 1.294 ;; "Models/person/person.blend") 1.295 1.296 + 1.297 +(defn load-blender-model 1.298 + "Load a .blend file using an asset folder relative path." 1.299 + [^String model] 1.300 + (.loadModel 1.301 + (doto (asset-manager) 1.302 + (.registerLoader BlenderModelLoader (into-array String ["blend"]))) 1.303 + model)) 1.304 + 1.305 + 1.306 (defn view-model [^String model] 1.307 (view 1.308 (.loadModel 1.309 @@ -757,7 +747,13 @@ 1.310 1.311 * COMMENT generate Source. 1.312 #+begin_src clojure :tangle ../src/cortex/body.clj 1.313 -<<body-main>> 1.314 +<<proprioception>> 1.315 +<<motor-control>> 1.316 #+end_src 1.317 + 1.318 +#+begin_src clojure :tangle ../src/test/body.clj 1.319 +<<test-body>> 1.320 +#+end_src 1.321 + 1.322 + 1.323 1.324 -