Mercurial > cortex
changeset 63:7f2653ad3199
cleaning
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 29 Nov 2011 02:46:46 -0700 |
parents | 2b9d81017cb7 |
children | ab1fee4280c3 |
files | org/body.org |
diffstat | 1 files changed, 205 insertions(+), 217 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/org/body.org Mon Nov 28 21:28:46 2011 -0700 1.2 +++ b/org/body.org Tue Nov 29 02:46:46 2011 -0700 1.3 @@ -5,7 +5,7 @@ 1.4 #+SETUPFILE: ../../aurellem/org/setup.org 1.5 #+INCLUDE: ../../aurellem/org/level-0.org 1.6 1.7 -* Body 1.8 +* COMMENT Body 1.9 1.10 #+srcname: body-main 1.11 #+begin_src clojure 1.12 @@ -16,35 +16,21 @@ 1.13 (cortex.import/mega-import-jme3) 1.14 (rlm.rlm-commands/help) 1.15 1.16 -(defn load-blender-model 1.17 +(defn load-blender-model 1.18 + "Load a .blend file using an asset folder relative path." 1.19 [^String model] 1.20 (.loadModel 1.21 (doto (asset-manager) 1.22 (.registerLoader BlenderModelLoader (into-array String ["blend"]))) 1.23 model)) 1.24 1.25 -(defn skel [node] 1.26 - (doto 1.27 - (.getSkeleton 1.28 - (.getControl node SkeletonControl)) 1.29 - ;; this is necessary to force the skeleton to have accurate world 1.30 - ;; transforms before it is rendered to the screen. 1.31 - (.resetAndUpdate))) 1.32 - 1.33 - 1.34 -(defn green-x-ray [] 1.35 - (doto (Material. (asset-manager) 1.36 - "Common/MatDefs/Misc/Unshaded.j3md") 1.37 - (.setColor "Color" ColorRGBA/Green) 1.38 - (-> (.getAdditionalRenderState) 1.39 - (.setDepthTest false)))) 1.40 - 1.41 - 1.42 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.43 1.44 ;;;;;;;;;;;; eve-style bodies ;;;;;;;; 1.45 1.46 -(defn worm [segment-length num-segments interstitial-space radius] 1.47 +(defn worm-segments 1.48 + "Create multiple evenly spaced box segments. They're fabulous!" 1.49 + [segment-length num-segments interstitial-space radius] 1.50 (letfn [(nth-segment 1.51 [n] 1.52 (box segment-length radius radius :mass 0.1 1.53 @@ -55,14 +41,20 @@ 1.54 :color (ColorRGBA/randomColor)))] 1.55 (map nth-segment (range num-segments)))) 1.56 1.57 - 1.58 (defn connect-at-midpoint 1.59 + "Connect two physics objects with a Point2Point joint constraint at 1.60 + the point equidistant from both objects' centers." 1.61 [segmentA segmentB] 1.62 (let [centerA (.getWorldTranslation segmentA) 1.63 centerB (.getWorldTranslation segmentB) 1.64 midpoint (.mult (.add centerA centerB) (float 0.5)) 1.65 pivotA (.subtract midpoint centerA) 1.66 pivotB (.subtract midpoint centerB) 1.67 + 1.68 + ;; A side-effect of creating a joint registers 1.69 + ;; it with both physics objects which in turn 1.70 + ;; will register the joint with the physics system 1.71 + ;; when the simulation is started. 1.72 joint (Point2PointJoint. 1.73 (.getControl segmentA RigidBodyControl) 1.74 (.getControl segmentB RigidBodyControl) 1.75 @@ -71,146 +63,34 @@ 1.76 segmentB)) 1.77 1.78 (defn point-worm [] 1.79 - (let [segments (worm 0.2 5 0.1 0.1)] 1.80 + (let [segments (worm-segments 0.2 5 0.1 0.1)] 1.81 (dorun (map (partial apply connect-at-midpoint) 1.82 (partition 2 1 segments))) 1.83 - (nodify "worm" segments))) 1.84 + (nodify "worm" segments))) 1.85 1.86 -(defn test-worm [] 1.87 - (.start 1.88 - (world 1.89 - (doto (Node.) 1.90 - ;;(.attachChild (point-worm)) 1.91 - (.attachChild (load-blender-model 1.92 - "Models/anim2/joint-worm.blend")) 1.93 - 1.94 - (.attachChild (box 10 1 10 1.95 - :position (Vector3f. 0 -2 0) :mass 0 1.96 - :color (ColorRGBA/Gray)))) 1.97 - { 1.98 - "key-space" (fire-cannon-ball) 1.99 - } 1.100 - (fn [world] 1.101 - (enable-debug world) 1.102 - (light-up-everything world) 1.103 - ;;(.setTimer world (NanoTimer.)) 1.104 - ) 1.105 - no-op))) 1.106 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.107 +;;;;;;;;; Proprioception ;;;;;;;;;;;;; 1.108 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.109 1.110 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.111 +(declare 1.112 + ;; generate an arbitray (but stable) orthogonal vector 1.113 + ;; to a given vector. 1.114 + some-orthogonal 1.115 1.116 + ;; determine the amount of rotation a quaternion will 1.117 + ;; cause about a given axis 1.118 + project-quaternion 1.119 1.120 -;;;;;;;;; Mortor Control ;;;;;;;;;;;;; 1.121 + ;; proprioception for a single joint 1.122 + joint-proprioception 1.123 + 1.124 + ;; create a function that provides proprioceptive information 1.125 + ;; about an entire body. 1.126 + proprioception) 1.127 1.128 - 1.129 -;; surprisingly ehough, terristerial creatures only move by using 1.130 -;; torque applied to their joints. There's not a single straight line 1.131 -;; of force in the human body at all! (a straight line of force would 1.132 -;; correspond to some sort of jet or rocket propulseion) 1.133 - 1.134 -(defn torque-controls [control] 1.135 - (let [torques 1.136 - (concat 1.137 - (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) 1.138 - (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) 1.139 - [Vector3f/UNIT_X])] 1.140 - (map (fn [torque-axis] 1.141 - (fn [torque] 1.142 - (.applyTorque 1.143 - control 1.144 - (.mult (.mult (.getPhysicsRotation control) 1.145 - torque-axis) 1.146 - (float 1.147 - (* (.getMass control) torque)))))) 1.148 - torques))) 1.149 - 1.150 -(defn motor-map 1.151 - "Take a creature and generate a function that will enable fine 1.152 - grained control over all the creature's limbs." 1.153 - [#^Node creature] 1.154 - (let [controls (keep #(.getControl % RigidBodyControl) 1.155 - (node-seq creature)) 1.156 - limb-controls (reduce concat (map torque-controls controls)) 1.157 - body-control (partial map #(%1 %2) limb-controls)] 1.158 - body-control)) 1.159 - 1.160 -(defn test-motor-map 1.161 - "see how torque works." 1.162 - [] 1.163 - (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) 1.164 - :mass 1 :color ColorRGBA/Green) 1.165 - motor-map (motor-map finger)] 1.166 - (world 1.167 - (nodify [finger 1.168 - (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 1.169 - :color ColorRGBA/Gray)]) 1.170 - standard-debug-controls 1.171 - (fn [world] 1.172 - (set-gravity world Vector3f/ZERO) 1.173 - (light-up-everything world) 1.174 - (.setTimer world (NanoTimer.))) 1.175 - (fn [_ _] 1.176 - (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0])))))) 1.177 - 1.178 -(defn test-torque 1.179 - "see how torque works." 1.180 - [] 1.181 - (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) 1.182 - :mass 1 :color ColorRGBA/Green) 1.183 - move-left? (atom false) 1.184 - move-right? (atom false) 1.185 - control (.getControl finger RigidBodyControl)] 1.186 - (world 1.187 - (nodify [finger 1.188 - (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 1.189 - :color ColorRGBA/Gray)]) 1.190 - (merge standard-debug-controls 1.191 - {"key-k" (fn [_ pressed?] (reset! move-left? pressed?)) 1.192 - "key-l" (fn [_ pressed?] (reset! move-right? pressed?))}) 1.193 - (fn [world] 1.194 - (set-gravity world Vector3f/ZERO) 1.195 - (light-up-everything world) 1.196 - (.setTimer world (NanoTimer.))) 1.197 - (fn [_ _] 1.198 - (if @move-left? 1.199 - (.applyTorque control 1.200 - (.mult (.getPhysicsRotation control) 1.201 - (Vector3f. -3 20 0)))) 1.202 - (if @move-right? 1.203 - (.applyTorque control (Vector3f. 0 0 1))))))) 1.204 - 1.205 -(defn worm-pattern [time] 1.206 - [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.207 - 1.208 - 0 0 0 0 0 0 0 0 0 0 0 1.209 - 1.210 - (* 20 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))) 1.211 - 1.212 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.213 - 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.214 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.215 - 1.216 - ]) 1.217 - 1.218 -;;;;;;;;;;;;;;;;;; Proprioception ;;;;;;;;;;;;;;;;;;;;;;;; 1.219 - 1.220 -;; this is not used as just getting the rotation would be simpler. 1.221 -(defn proprioception-senses 1.222 - "given a control , create a sequence of thunks that will report the 1.223 - rotation of the control's object along the same axes as the motor-control map." 1.224 - [control] 1.225 - (let [torques 1.226 - (concat 1.227 - (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) 1.228 - (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) 1.229 - [Vector3f/UNIT_X])] 1.230 - (map (fn [torque-axis] 1.231 - (fn [] 1.232 - (.getPhysicsRotation control))) 1.233 - torques))) 1.234 - 1.235 -(defn orthogonal-vect 1.236 - "Return a vector orthogonal to the current one" 1.237 +(defn some-orthogonal 1.238 + "Generate an arbitray (but stable) orthogonal vector to a given 1.239 + vector." 1.240 [vector] 1.241 (let [x (.getX vector) 1.242 y (.getY vector) 1.243 @@ -221,10 +101,13 @@ 1.244 (not= z (float 0)) (Vector3f. 0 (- z) y) 1.245 true Vector3f/ZERO))) 1.246 1.247 -;; from 1.248 -;; http://stackoverflow.com/questions/3684269/ \\ 1.249 -;; component-of-a-quaternion-rotation-around-an-axis 1.250 -(defn rot-about-axis [#^Quaternion q #^Vector3f axis] 1.251 +(defn project-quaternion 1.252 + "From http://stackoverflow.com/questions/3684269/ 1.253 + component-of-a-quaternion-rotation-around-an-axis. 1.254 + 1.255 + Determine the amount of rotation a quaternion will 1.256 + cause about a given axis." 1.257 + [#^Quaternion q #^Vector3f axis] 1.258 (let [basis-1 (orthogonal-vect axis) 1.259 basis-2 (.cross axis basis-1) 1.260 rotated (.mult q basis-1) 1.261 @@ -232,15 +115,11 @@ 1.262 beta (.dot basis-2 (.project rotated basis-2))] 1.263 (Math/atan2 beta alpha))) 1.264 1.265 - 1.266 -(defn check-rot [a] 1.267 - (rot-about-axis 1.268 - (doto (Quaternion.) 1.269 - (.fromAngleAxis 1.270 - (float a) 1.271 - (Vector3f. 1 0 0))) (Vector3f. 1 0 0))) 1.272 - 1.273 -(defn relative-positions [joint] 1.274 +(defn joint-proprioception 1.275 + "Relative position information for a two-part system connected by a 1.276 + joint. Gives the pitch, yaw, and roll of the 'B' object relative to 1.277 + the 'A' object, as determined by the joint." 1.278 + [joint] 1.279 (let [object-a (.getUserObject (.getBodyA joint)) 1.280 object-b (.getUserObject (.getBodyB joint)) 1.281 arm-a 1.282 @@ -273,80 +152,105 @@ 1.283 (.getLocalRotation object-b) 1.284 (doto (Quaternion.) 1.285 (.fromRotationMatrix rotate-a))) 1.286 - arm-b) 1.287 - ] 1.288 - 1.289 - 1.290 - 1.291 - ;;(println-repl 1.292 - ;; "arm-b is " arm-b) 1.293 - ;;(println-repl 1.294 - ;; "pivot-b is " (.getPivotB joint)) 1.295 - ;;(println-repl 1.296 - ;; (format "pitch: %1.2f\nyaw: %1.2f\nroll: %1.2f\n" 1.297 - ;; pitch yaw roll)) 1.298 + arm-b)] 1.299 [pitch yaw roll])) 1.300 1.301 - 1.302 - 1.303 - 1.304 +(defn proprioception 1.305 + "Create a function that provides proprioceptive information about an 1.306 + entire body." 1.307 + [body] 1.308 + ;; extract the body's joints 1.309 + (let [joints 1.310 + (distinct 1.311 + (reduce 1.312 + concat 1.313 + (map #(.getJoints %) 1.314 + (keep 1.315 + #(.getControl % RigidBodyControl) 1.316 + (node-seq body)))))] 1.317 + (fn [] 1.318 + (map joint-proprioception joints)))) 1.319 1.320 - 1.321 + 1.322 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.323 +;;;;;;;;; Mortor Control ;;;;;;;;;;;;; 1.324 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.325 + 1.326 + 1.327 +;; surprisingly enough, terristerial creatures only move by using 1.328 +;; torque applied about their joints. There's not a single straight 1.329 +;; line of force in the human body at all! (A straight line of force 1.330 +;; would correspond to some sort of jet or rocket propulseion.) 1.331 + 1.332 +(defn vector-motor-control 1.333 + "Create a function that accepts a sequence of Vector3f objects that 1.334 + describe the torque to be applied to each part of the body." 1.335 + [body] 1.336 + (let [nodes (node-seq body) 1.337 + controls (keep #(.getControl % RigidBodyControl) nodes)] 1.338 + (fn [torques] 1.339 + (map #(.applyTorque %1 %2) 1.340 + controls torques)))) 1.341 + 1.342 +;; note -- might want to add a lower dimensional, discrete version of 1.343 +;; this if it proves usefull from a x-modal clustering perspective. 1.344 + 1.345 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.346 + 1.347 + 1.348 + 1.349 +(defn worm-pattern [time] 1.350 + [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.351 + 1.352 + 0 0 0 0 0 0 0 0 0 0 0 1.353 + 1.354 + (* 20 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))) 1.355 + 1.356 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.357 + 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.358 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.359 + 1.360 + ]) 1.361 + 1.362 +(defn worm-pattern [time] 1.363 + (let [angle (* Math/PI (/ 4 20)) 1.364 + direction (Vector3f. 0 (Math/sin angle) (Math/cos angle))] 1.365 + [Vector3f/ZERO 1.366 + (.mult 1.367 + direction 1.368 + (float (* 2 (Math/sin (* Math/PI 2 (/ (rem time 300 ) 300)))))) 1.369 + Vector3f/ZERO 1.370 + Vector3f/ZERO 1.371 + Vector3f/ZERO])) 1.372 1.373 (defn test-worm-control 1.374 [] 1.375 (let [worm (point-worm) 1.376 time (atom 0) 1.377 - worm-motor-map (motor-map worm) 1.378 - ;;body-map (proprioception worm) 1.379 - debug-segments 1.380 - (map 1.381 - #(doto 1.382 - (make-shape 1.383 - (assoc base-shape 1.384 - :name "debug-line" 1.385 - :physical? false 1.386 - :shape 1.387 - (com.jme3.scene.shape.Line. 1.388 - (.add (.getWorldTranslation %) 1.389 - (Vector3f. -0.2 0 0 )) 1.390 - (.add (.getWorldTranslation %) 1.391 - (Vector3f. 0.2 0 0))))) 1.392 - (.setMaterial (green-x-ray))) 1.393 - (drop 1 (node-seq worm)))] 1.394 + worm-motor-map (vector-motor-control worm)] 1.395 (world 1.396 (nodify [worm 1.397 (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 1.398 :color ColorRGBA/Gray)]) 1.399 standard-debug-controls 1.400 (fn [world] 1.401 - (.attachChild (.getRootNode world) (nodify debug-segments)) 1.402 (enable-debug world) 1.403 (light-up-everything world) 1.404 - (com.aurellem.capture.Capture/captureVideo 1.405 - world 1.406 - (file-str "/home/r/proj/cortex/tmp/moving-worm"))) 1.407 + (comment 1.408 + (com.aurellem.capture.Capture/captureVideo 1.409 + world 1.410 + (file-str "/home/r/proj/cortex/tmp/moving-worm"))) 1.411 + ) 1.412 1.413 (fn [_ _] 1.414 - (dorun 1.415 - (map 1.416 - (fn [worm-segment 1.417 - debug-segment] 1.418 - (.rotate 1.419 - debug-segment 1.420 - (Quaternion. (float 0) (float 0.05) (float 0) (float 1)))) 1.421 - (drop 1 (node-seq worm)) 1.422 - debug-segments)) 1.423 (swap! time inc) 1.424 - ;;(println-repl (with-out-str (clojure.pprint/pprint (doall (body-map))))) 1.425 - (Thread/sleep 200) 1.426 + ;;(Thread/sleep 200) 1.427 (dorun (worm-motor-map 1.428 (worm-pattern @time))))))) 1.429 1.430 1.431 1.432 1.433 - 1.434 (defn test-prop 1.435 "see how torque works." 1.436 [] 1.437 @@ -428,7 +332,7 @@ 1.438 #+end_src 1.439 1.440 1.441 -* COMMENT failed-clojure-code 1.442 +* COMMENT code-limbo 1.443 #+begin_src clojure 1.444 ;;(.loadModel 1.445 ;; (doto (asset-manager) 1.446 @@ -759,6 +663,90 @@ 1.447 (reduce concat (map relative-positions (list (first joints))))))) 1.448 1.449 1.450 +(defn skel [node] 1.451 + (doto 1.452 + (.getSkeleton 1.453 + (.getControl node SkeletonControl)) 1.454 + ;; this is necessary to force the skeleton to have accurate world 1.455 + ;; transforms before it is rendered to the screen. 1.456 + (.resetAndUpdate))) 1.457 + 1.458 +(defn green-x-ray [] 1.459 + (doto (Material. (asset-manager) 1.460 + "Common/MatDefs/Misc/Unshaded.j3md") 1.461 + (.setColor "Color" ColorRGBA/Green) 1.462 + (-> (.getAdditionalRenderState) 1.463 + (.setDepthTest false)))) 1.464 + 1.465 +(defn test-worm [] 1.466 + (.start 1.467 + (world 1.468 + (doto (Node.) 1.469 + ;;(.attachChild (point-worm)) 1.470 + (.attachChild (load-blender-model 1.471 + "Models/anim2/joint-worm.blend")) 1.472 + 1.473 + (.attachChild (box 10 1 10 1.474 + :position (Vector3f. 0 -2 0) :mass 0 1.475 + :color (ColorRGBA/Gray)))) 1.476 + { 1.477 + "key-space" (fire-cannon-ball) 1.478 + } 1.479 + (fn [world] 1.480 + (enable-debug world) 1.481 + (light-up-everything world) 1.482 + ;;(.setTimer world (NanoTimer.)) 1.483 + ) 1.484 + no-op))) 1.485 + 1.486 + 1.487 + 1.488 +;; defunct movement stuff 1.489 +(defn torque-controls [control] 1.490 + (let [torques 1.491 + (concat 1.492 + (map #(Vector3f. 0 (Math/sin %) (Math/cos %)) 1.493 + (range 0 (* Math/PI 2) (/ (* Math/PI 2) 20))) 1.494 + [Vector3f/UNIT_X])] 1.495 + (map (fn [torque-axis] 1.496 + (fn [torque] 1.497 + (.applyTorque 1.498 + control 1.499 + (.mult (.mult (.getPhysicsRotation control) 1.500 + torque-axis) 1.501 + (float 1.502 + (* (.getMass control) torque)))))) 1.503 + torques))) 1.504 + 1.505 +(defn motor-map 1.506 + "Take a creature and generate a function that will enable fine 1.507 + grained control over all the creature's limbs." 1.508 + [#^Node creature] 1.509 + (let [controls (keep #(.getControl % RigidBodyControl) 1.510 + (node-seq creature)) 1.511 + limb-controls (reduce concat (map torque-controls controls)) 1.512 + body-control (partial map #(%1 %2) limb-controls)] 1.513 + body-control)) 1.514 + 1.515 +(defn test-motor-map 1.516 + "see how torque works." 1.517 + [] 1.518 + (let [finger (box 3 0.5 0.5 :position (Vector3f. 0 2 0) 1.519 + :mass 1 :color ColorRGBA/Green) 1.520 + motor-map (motor-map finger)] 1.521 + (world 1.522 + (nodify [finger 1.523 + (box 10 0.5 10 :position (Vector3f. 0 -5 0) :mass 0 1.524 + :color ColorRGBA/Gray)]) 1.525 + standard-debug-controls 1.526 + (fn [world] 1.527 + (set-gravity world Vector3f/ZERO) 1.528 + (light-up-everything world) 1.529 + (.setTimer world (NanoTimer.))) 1.530 + (fn [_ _] 1.531 + (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0])))))) 1.532 + 1.533 + 1.534 #+end_src 1.535 1.536