Mercurial > cortex
diff org/body.org @ 145:7a49b81ca1bf
finally got proprioception working to my satisfaction
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 02 Feb 2012 12:49:11 -0700 |
parents | 48f9cba082eb |
children | e1232043656a |
line wrap: on
line diff
1.1 --- a/org/body.org Thu Feb 02 03:17:11 2012 -0700 1.2 +++ b/org/body.org Thu Feb 02 12:49:11 2012 -0700 1.3 @@ -63,42 +63,50 @@ 1.4 (seq (.getChildren joint-node)) 1.5 (do (println-repl "could not find JOINTS node") []))) 1.6 1.7 +(defn right-handed? [vec1 vec2 vec3] 1.8 + (< 0 (.dot (.cross vec1 vec2) vec3))) 1.9 + 1.10 +(defn absolute-angle [vec1 vec2 axis] 1.11 + (let [angle (.angleBetween vec1 vec2)] 1.12 + (if (right-handed? vec1 vec2 axis) 1.13 + angle (- (* 2 Math/PI) angle)))) 1.14 + 1.15 + 1.16 (defn joint-proprioception [#^Node parts #^Node joint] 1.17 (let [[obj-a obj-b] (joint-targets parts joint) 1.18 joint-rot (.getWorldRotation joint) 1.19 - pre-inv-a (.inverse (.getWorldRotation obj-a)) 1.20 - x (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_X)) 1.21 - y (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Y)) 1.22 - z (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Z)) 1.23 - tmp-rot-a (.getWorldRotation obj-a)] 1.24 - (println-repl "x:" (.mult tmp-rot-a x)) 1.25 - (println-repl "y:" (.mult tmp-rot-a y)) 1.26 - (println-repl "z:" (.mult tmp-rot-a z)) 1.27 - (println-repl "rot-a" (.getWorldRotation obj-a)) 1.28 - (println-repl "rot-b" (.getWorldRotation obj-b)) 1.29 - ;; this function will report proprioceptive information for the 1.30 - ;; joint. 1.31 + x0 (.mult joint-rot Vector3f/UNIT_X) 1.32 + y0 (.mult joint-rot Vector3f/UNIT_Y) 1.33 + z0 (.mult joint-rot Vector3f/UNIT_Z)] 1.34 + (println-repl "x:" x0) 1.35 + (println-repl "y:" y0) 1.36 + (println-repl "z:" z0) 1.37 + (println-repl "init-a:" (.getWorldRotation obj-a)) 1.38 + (println-repl "init-b:" (.getWorldRotation obj-b)) 1.39 + 1.40 (fn [] 1.41 - ;; x is the "twist" axis, y and z are the "bend" axes 1.42 - (let [rot-a (.getWorldRotation obj-a) 1.43 - ;;inv-a (.inverse rot-a) 1.44 - rot-b (.getWorldRotation obj-b) 1.45 - ;;relative (.mult rot-b inv-a) 1.46 - basis (doto (Matrix3f.) 1.47 - (.setColumn 0 (.mult rot-a x)) 1.48 - (.setColumn 1 (.mult rot-a y)) 1.49 - (.setColumn 2 (.mult rot-a z))) 1.50 - rotation-about-joint 1.51 + (let [rot-a (.clone (.getWorldRotation obj-a)) 1.52 + rot-b (.clone (.getWorldRotation obj-b)) 1.53 + x (.mult rot-a x0) 1.54 + y (.mult rot-a y0) 1.55 + z (.mult rot-a z0) 1.56 + 1.57 + X (.mult rot-b x0) 1.58 + Y (.mult rot-b y0) 1.59 + Z (.mult rot-b z0) 1.60 + heading (Math/atan2 (.dot X z) (.dot X x)) 1.61 + pitch (Math/atan2 (.dot X y) (.dot X x)) 1.62 + 1.63 + ;; rotate x-vector back to origin 1.64 + reverse 1.65 (doto (Quaternion.) 1.66 - (.fromRotationMatrix 1.67 - (.mult (.invert basis) 1.68 - (.toRotationMatrix rot-b)))) 1.69 - [yaw roll pitch] 1.70 - (seq (.toAngles rotation-about-joint nil))] 1.71 - ;;return euler angles of the quaternion around the new basis 1.72 - [yaw roll pitch] 1.73 - )))) 1.74 - 1.75 + (.fromAngleAxis 1.76 + (.angleBetween X x) 1.77 + (let [cross (.normalize (.cross X x))] 1.78 + (if (= 0 (.length cross)) y cross)))) 1.79 + roll (absolute-angle (.mult reverse Y) y x)] 1.80 + 1.81 + [heading pitch roll])))) 1.82 1.83 (defn proprioception 1.84 "Create a function that provides proprioceptive information about an 1.85 @@ -161,17 +169,58 @@ 1.86 world-loop* (fn [world tpf] 1.87 (world-loop world tpf) 1.88 (splice-loop))] 1.89 + [root-node 1.90 + keymap* 1.91 + intilization 1.92 + world-loop*])) 1.93 1.94 - [root-node 1.95 - keymap* 1.96 - intilization 1.97 - world-loop*])) 1.98 +(import java.awt.image.BufferedImage) 1.99 1.100 - 1.101 +(defn draw-sprite [image sprite x y color ] 1.102 + (dorun 1.103 + (for [[u v] sprite] 1.104 + (.setRGB image (+ u x) (+ v y) color)))) 1.105 + 1.106 +(defn view-angle 1.107 + "create a debug view of an angle" 1.108 + [color] 1.109 + (let [image (BufferedImage. 50 50 BufferedImage/TYPE_INT_RGB) 1.110 + previous (atom [25 25]) 1.111 + sprite [[0 0] [0 1] 1.112 + [0 -1] [-1 0] [1 0]]] 1.113 + (fn [angle] 1.114 + (let [angle (float angle)] 1.115 + (let [position 1.116 + [(+ 25 (int (* 20 (Math/cos angle)))) 1.117 + (+ 25 (int (* -20 (Math/sin angle))))]] 1.118 + (draw-sprite image sprite (@previous 0) (@previous 1) 0x000000) 1.119 + (draw-sprite image sprite (position 0) (position 1) color) 1.120 + (reset! previous position)) 1.121 + image)))) 1.122 + 1.123 +(defn proprioception-debug-window 1.124 + [] 1.125 + (let [heading (view-angle 0xFF0000) 1.126 + pitch (view-angle 0x00FF00) 1.127 + roll (view-angle 0xFFFFFF) 1.128 + v-heading (view-image) 1.129 + v-pitch (view-image) 1.130 + v-roll (view-image) 1.131 + ] 1.132 + (fn [prop-data] 1.133 + (dorun 1.134 + (map 1.135 + (fn [[h p r]] 1.136 + (v-heading (heading h)) 1.137 + (v-pitch (pitch p)) 1.138 + (v-roll (roll r))) 1.139 + prop-data))))) 1.140 + 1.141 + 1.142 #+end_src 1.143 1.144 #+results: proprioception 1.145 -: #'cortex.body/proprioception 1.146 +: #'cortex.body/proprioception-debug-window 1.147 1.148 * Motor Control 1.149 #+name: motor-control 1.150 @@ -210,7 +259,8 @@ 1.151 com.jme3.math.ColorRGBA 1.152 com.jme3.bullet.joints.Point2PointJoint 1.153 com.jme3.bullet.control.RigidBodyControl 1.154 - com.jme3.system.NanoTimer)) 1.155 + com.jme3.system.NanoTimer 1.156 + com.jme3.math.Quaternion)) 1.157 1.158 (defn worm-segments 1.159 "Create multiple evenly spaced box segments. They're fabulous!" 1.160 @@ -333,47 +383,6 @@ 1.161 (set-gravity world Vector3f/ZERO) 1.162 ) 1.163 no-op))) 1.164 -(import java.awt.image.BufferedImage) 1.165 - 1.166 -(defn draw-sprite [image sprite x y color ] 1.167 - (dorun 1.168 - (for [[u v] sprite] 1.169 - (.setRGB image (+ u x) (+ v y) color)))) 1.170 - 1.171 -(defn view-angle 1.172 - "create a debug view of an angle" 1.173 - [color] 1.174 - (let [image (BufferedImage. 50 50 BufferedImage/TYPE_INT_RGB) 1.175 - previous (atom [25 25]) 1.176 - sprite [[0 0] [0 1] 1.177 - [0 -1] [-1 0] [1 0]]] 1.178 - (fn [angle] 1.179 - (let [angle (float angle)] 1.180 - (let [position 1.181 - [(+ 25 (int (* 20 (Math/cos angle)))) 1.182 - (+ 25 (int (* 20(Math/sin angle))))]] 1.183 - (draw-sprite image sprite (@previous 0) (@previous 1) 0x000000) 1.184 - (draw-sprite image sprite (position 0) (position 1) color) 1.185 - (reset! previous position)) 1.186 - image)))) 1.187 - 1.188 -(defn proprioception-debug-window 1.189 - [] 1.190 - (let [yaw (view-angle 0xFF0000) 1.191 - roll (view-angle 0x00FF00) 1.192 - pitch (view-angle 0xFFFFFF) 1.193 - v-yaw (view-image) 1.194 - v-roll (view-image) 1.195 - v-pitch (view-image) 1.196 - ] 1.197 - (fn [prop-data] 1.198 - (dorun 1.199 - (map 1.200 - (fn [[y r p]] 1.201 - (v-yaw (yaw y)) 1.202 - (v-roll (roll r)) 1.203 - (v-pitch (pitch p))) 1.204 - prop-data))))) 1.205 (comment 1.206 1.207 (defn proprioception-debug-window 1.208 @@ -406,25 +415,32 @@ 1.209 and changes yaw. key-v/key-b will spin the blue segment clockwise 1.210 and counterclockwise, and only affect roll." 1.211 [] 1.212 - (let [hand (box 1 0.2 0.2 :position (Vector3f. 0 2 0) 1.213 + (let [hand (box 0.2 1 0.2 :position (Vector3f. 0 0 0) 1.214 :mass 0 :color ColorRGBA/Green :name "hand") 1.215 - finger (box 1 0.2 0.2 :position (Vector3f. 2.4 2 0) 1.216 + finger (box 0.2 1 0.2 :position (Vector3f. 0 2.4 0) 1.217 :mass 1 :color ColorRGBA/Red :name "finger") 1.218 joint-node (box 0.1 0.05 0.05 :color ColorRGBA/Yellow 1.219 - :position (Vector3f. 1.2 2 0) 1.220 + :position (Vector3f. 0 1.2 0) 1.221 + :rotation (doto (Quaternion.) 1.222 + (.fromAngleAxis 1.223 + (/ Math/PI 2) 1.224 + (Vector3f. 0 0 1))) 1.225 :physical? false) 1.226 - joint (join-at-point hand finger (Vector3f. 1.2 2 0 )) 1.227 + joint (join-at-point hand finger (Vector3f. 0 1.2 0 )) 1.228 creature (nodify [hand finger joint-node]) 1.229 + finger-control (.getControl finger RigidBodyControl) 1.230 + hand-control (.getControl hand RigidBodyControl)] 1.231 + 1.232 + 1.233 + (let 1.234 ;; ******************************************* 1.235 1.236 - floor (box 10 10 10 :position (Vector3f. 0 -15 0) 1.237 + [floor (box 10 10 10 :position (Vector3f. 0 -15 0) 1.238 :mass 0 :color ColorRGBA/Gray) 1.239 1.240 root (nodify [creature floor]) 1.241 prop (joint-proprioception creature joint-node) 1.242 prop-view (proprioception-debug-window) 1.243 - finger-control (.getControl finger RigidBodyControl) 1.244 - hand-control (.getControl hand RigidBodyControl) 1.245 1.246 controls 1.247 (merge standard-debug-controls 1.248 @@ -471,14 +487,14 @@ 1.249 (with-movement 1.250 finger 1.251 ["key-r" "key-t" "key-f" "key-g" "key-v" "key-b"] 1.252 - [10 10 10 10 1 1] 1.253 + [1 1 10 10 10 10] 1.254 [root 1.255 controls 1.256 (fn [world] 1.257 (.setTimer world (com.aurellem.capture.RatchetTimer. 60)) 1.258 (set-gravity world (Vector3f. 0 0 0)) 1.259 (light-up-everything world)) 1.260 - (fn [_ _] (prop-view (list (prop))))]))))) 1.261 + (fn [_ _] (prop-view (list (prop))))])))))) 1.262 1.263 #+end_src 1.264 1.265 @@ -908,7 +924,51 @@ 1.266 (light-up-everything world) 1.267 (.setTimer world (NanoTimer.))) 1.268 (fn [_ _] 1.269 - (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.270 + (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1.271 + 0])))))) 1.272 + 1.273 +(defn joint-proprioception [#^Node parts #^Node joint] 1.274 + (let [[obj-a obj-b] (joint-targets parts joint) 1.275 + joint-rot (.getWorldRotation joint) 1.276 + pre-inv-a (.inverse (.getWorldRotation obj-a)) 1.277 + x (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_X)) 1.278 + y (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Y)) 1.279 + z (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Z)) 1.280 + 1.281 + x Vector3f/UNIT_Y 1.282 + y Vector3f/UNIT_Z 1.283 + z Vector3f/UNIT_X 1.284 + 1.285 + 1.286 + tmp-rot-a (.getWorldRotation obj-a)] 1.287 + (println-repl "x:" (.mult tmp-rot-a x)) 1.288 + (println-repl "y:" (.mult tmp-rot-a y)) 1.289 + (println-repl "z:" (.mult tmp-rot-a z)) 1.290 + (println-repl "rot-a" (.getWorldRotation obj-a)) 1.291 + (println-repl "rot-b" (.getWorldRotation obj-b)) 1.292 + (println-repl "joint-rot" joint-rot) 1.293 + ;; this function will report proprioceptive information for the 1.294 + ;; joint. 1.295 + (fn [] 1.296 + ;; x is the "twist" axis, y and z are the "bend" axes 1.297 + (let [rot-a (.getWorldRotation obj-a) 1.298 + ;;inv-a (.inverse rot-a) 1.299 + rot-b (.getWorldRotation obj-b) 1.300 + ;;relative (.mult rot-b inv-a) 1.301 + basis (doto (Matrix3f.) 1.302 + (.setColumn 0 (.mult rot-a x)) 1.303 + (.setColumn 1 (.mult rot-a y)) 1.304 + (.setColumn 2 (.mult rot-a z))) 1.305 + rotation-about-joint 1.306 + (doto (Quaternion.) 1.307 + (.fromRotationMatrix 1.308 + (.mult (.invert basis) 1.309 + (.toRotationMatrix rot-b)))) 1.310 + [yaw roll pitch] 1.311 + (seq (.toAngles rotation-about-joint nil))] 1.312 + ;;return euler angles of the quaternion around the new basis 1.313 + [yaw roll pitch])))) 1.314 + 1.315 #+end_src 1.316 1.317