Mercurial > cortex
comparison 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 |
comparison
equal
deleted
inserted
replaced
144:48f9cba082eb | 145:7a49b81ca1bf |
---|---|
61 [#^Node creature] | 61 [#^Node creature] |
62 (if-let [joint-node (.getChild creature "joints")] | 62 (if-let [joint-node (.getChild creature "joints")] |
63 (seq (.getChildren joint-node)) | 63 (seq (.getChildren joint-node)) |
64 (do (println-repl "could not find JOINTS node") []))) | 64 (do (println-repl "could not find JOINTS node") []))) |
65 | 65 |
66 (defn right-handed? [vec1 vec2 vec3] | |
67 (< 0 (.dot (.cross vec1 vec2) vec3))) | |
68 | |
69 (defn absolute-angle [vec1 vec2 axis] | |
70 (let [angle (.angleBetween vec1 vec2)] | |
71 (if (right-handed? vec1 vec2 axis) | |
72 angle (- (* 2 Math/PI) angle)))) | |
73 | |
74 | |
66 (defn joint-proprioception [#^Node parts #^Node joint] | 75 (defn joint-proprioception [#^Node parts #^Node joint] |
67 (let [[obj-a obj-b] (joint-targets parts joint) | 76 (let [[obj-a obj-b] (joint-targets parts joint) |
68 joint-rot (.getWorldRotation joint) | 77 joint-rot (.getWorldRotation joint) |
69 pre-inv-a (.inverse (.getWorldRotation obj-a)) | 78 x0 (.mult joint-rot Vector3f/UNIT_X) |
70 x (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_X)) | 79 y0 (.mult joint-rot Vector3f/UNIT_Y) |
71 y (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Y)) | 80 z0 (.mult joint-rot Vector3f/UNIT_Z)] |
72 z (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Z)) | 81 (println-repl "x:" x0) |
73 tmp-rot-a (.getWorldRotation obj-a)] | 82 (println-repl "y:" y0) |
74 (println-repl "x:" (.mult tmp-rot-a x)) | 83 (println-repl "z:" z0) |
75 (println-repl "y:" (.mult tmp-rot-a y)) | 84 (println-repl "init-a:" (.getWorldRotation obj-a)) |
76 (println-repl "z:" (.mult tmp-rot-a z)) | 85 (println-repl "init-b:" (.getWorldRotation obj-b)) |
77 (println-repl "rot-a" (.getWorldRotation obj-a)) | 86 |
78 (println-repl "rot-b" (.getWorldRotation obj-b)) | |
79 ;; this function will report proprioceptive information for the | |
80 ;; joint. | |
81 (fn [] | 87 (fn [] |
82 ;; x is the "twist" axis, y and z are the "bend" axes | 88 (let [rot-a (.clone (.getWorldRotation obj-a)) |
83 (let [rot-a (.getWorldRotation obj-a) | 89 rot-b (.clone (.getWorldRotation obj-b)) |
84 ;;inv-a (.inverse rot-a) | 90 x (.mult rot-a x0) |
85 rot-b (.getWorldRotation obj-b) | 91 y (.mult rot-a y0) |
86 ;;relative (.mult rot-b inv-a) | 92 z (.mult rot-a z0) |
87 basis (doto (Matrix3f.) | 93 |
88 (.setColumn 0 (.mult rot-a x)) | 94 X (.mult rot-b x0) |
89 (.setColumn 1 (.mult rot-a y)) | 95 Y (.mult rot-b y0) |
90 (.setColumn 2 (.mult rot-a z))) | 96 Z (.mult rot-b z0) |
91 rotation-about-joint | 97 heading (Math/atan2 (.dot X z) (.dot X x)) |
98 pitch (Math/atan2 (.dot X y) (.dot X x)) | |
99 | |
100 ;; rotate x-vector back to origin | |
101 reverse | |
92 (doto (Quaternion.) | 102 (doto (Quaternion.) |
93 (.fromRotationMatrix | 103 (.fromAngleAxis |
94 (.mult (.invert basis) | 104 (.angleBetween X x) |
95 (.toRotationMatrix rot-b)))) | 105 (let [cross (.normalize (.cross X x))] |
96 [yaw roll pitch] | 106 (if (= 0 (.length cross)) y cross)))) |
97 (seq (.toAngles rotation-about-joint nil))] | 107 roll (absolute-angle (.mult reverse Y) y x)] |
98 ;;return euler angles of the quaternion around the new basis | 108 |
99 [yaw roll pitch] | 109 [heading pitch roll])))) |
100 )))) | |
101 | |
102 | 110 |
103 (defn proprioception | 111 (defn proprioception |
104 "Create a function that provides proprioceptive information about an | 112 "Create a function that provides proprioceptive information about an |
105 entire body." | 113 entire body." |
106 [#^Node creature] | 114 [#^Node creature] |
159 atoms directions forces))) | 167 atoms directions forces))) |
160 | 168 |
161 world-loop* (fn [world tpf] | 169 world-loop* (fn [world tpf] |
162 (world-loop world tpf) | 170 (world-loop world tpf) |
163 (splice-loop))] | 171 (splice-loop))] |
164 | 172 [root-node |
165 [root-node | 173 keymap* |
166 keymap* | 174 intilization |
167 intilization | 175 world-loop*])) |
168 world-loop*])) | 176 |
169 | 177 (import java.awt.image.BufferedImage) |
170 | 178 |
179 (defn draw-sprite [image sprite x y color ] | |
180 (dorun | |
181 (for [[u v] sprite] | |
182 (.setRGB image (+ u x) (+ v y) color)))) | |
183 | |
184 (defn view-angle | |
185 "create a debug view of an angle" | |
186 [color] | |
187 (let [image (BufferedImage. 50 50 BufferedImage/TYPE_INT_RGB) | |
188 previous (atom [25 25]) | |
189 sprite [[0 0] [0 1] | |
190 [0 -1] [-1 0] [1 0]]] | |
191 (fn [angle] | |
192 (let [angle (float angle)] | |
193 (let [position | |
194 [(+ 25 (int (* 20 (Math/cos angle)))) | |
195 (+ 25 (int (* -20 (Math/sin angle))))]] | |
196 (draw-sprite image sprite (@previous 0) (@previous 1) 0x000000) | |
197 (draw-sprite image sprite (position 0) (position 1) color) | |
198 (reset! previous position)) | |
199 image)))) | |
200 | |
201 (defn proprioception-debug-window | |
202 [] | |
203 (let [heading (view-angle 0xFF0000) | |
204 pitch (view-angle 0x00FF00) | |
205 roll (view-angle 0xFFFFFF) | |
206 v-heading (view-image) | |
207 v-pitch (view-image) | |
208 v-roll (view-image) | |
209 ] | |
210 (fn [prop-data] | |
211 (dorun | |
212 (map | |
213 (fn [[h p r]] | |
214 (v-heading (heading h)) | |
215 (v-pitch (pitch p)) | |
216 (v-roll (roll r))) | |
217 prop-data))))) | |
218 | |
219 | |
171 #+end_src | 220 #+end_src |
172 | 221 |
173 #+results: proprioception | 222 #+results: proprioception |
174 : #'cortex.body/proprioception | 223 : #'cortex.body/proprioception-debug-window |
175 | 224 |
176 * Motor Control | 225 * Motor Control |
177 #+name: motor-control | 226 #+name: motor-control |
178 #+begin_src clojure | 227 #+begin_src clojure |
179 (in-ns 'cortex.body) | 228 (in-ns 'cortex.body) |
208 (:import | 257 (:import |
209 com.jme3.math.Vector3f | 258 com.jme3.math.Vector3f |
210 com.jme3.math.ColorRGBA | 259 com.jme3.math.ColorRGBA |
211 com.jme3.bullet.joints.Point2PointJoint | 260 com.jme3.bullet.joints.Point2PointJoint |
212 com.jme3.bullet.control.RigidBodyControl | 261 com.jme3.bullet.control.RigidBodyControl |
213 com.jme3.system.NanoTimer)) | 262 com.jme3.system.NanoTimer |
263 com.jme3.math.Quaternion)) | |
214 | 264 |
215 (defn worm-segments | 265 (defn worm-segments |
216 "Create multiple evenly spaced box segments. They're fabulous!" | 266 "Create multiple evenly spaced box segments. They're fabulous!" |
217 [segment-length num-segments interstitial-space radius] | 267 [segment-length num-segments interstitial-space radius] |
218 (letfn [(nth-segment | 268 (letfn [(nth-segment |
331 (enable-debug world) | 381 (enable-debug world) |
332 (.setTimer world (com.aurellem.capture.RatchetTimer. 60)) | 382 (.setTimer world (com.aurellem.capture.RatchetTimer. 60)) |
333 (set-gravity world Vector3f/ZERO) | 383 (set-gravity world Vector3f/ZERO) |
334 ) | 384 ) |
335 no-op))) | 385 no-op))) |
336 (import java.awt.image.BufferedImage) | |
337 | |
338 (defn draw-sprite [image sprite x y color ] | |
339 (dorun | |
340 (for [[u v] sprite] | |
341 (.setRGB image (+ u x) (+ v y) color)))) | |
342 | |
343 (defn view-angle | |
344 "create a debug view of an angle" | |
345 [color] | |
346 (let [image (BufferedImage. 50 50 BufferedImage/TYPE_INT_RGB) | |
347 previous (atom [25 25]) | |
348 sprite [[0 0] [0 1] | |
349 [0 -1] [-1 0] [1 0]]] | |
350 (fn [angle] | |
351 (let [angle (float angle)] | |
352 (let [position | |
353 [(+ 25 (int (* 20 (Math/cos angle)))) | |
354 (+ 25 (int (* 20(Math/sin angle))))]] | |
355 (draw-sprite image sprite (@previous 0) (@previous 1) 0x000000) | |
356 (draw-sprite image sprite (position 0) (position 1) color) | |
357 (reset! previous position)) | |
358 image)))) | |
359 | |
360 (defn proprioception-debug-window | |
361 [] | |
362 (let [yaw (view-angle 0xFF0000) | |
363 roll (view-angle 0x00FF00) | |
364 pitch (view-angle 0xFFFFFF) | |
365 v-yaw (view-image) | |
366 v-roll (view-image) | |
367 v-pitch (view-image) | |
368 ] | |
369 (fn [prop-data] | |
370 (dorun | |
371 (map | |
372 (fn [[y r p]] | |
373 (v-yaw (yaw y)) | |
374 (v-roll (roll r)) | |
375 (v-pitch (pitch p))) | |
376 prop-data))))) | |
377 (comment | 386 (comment |
378 | 387 |
379 (defn proprioception-debug-window | 388 (defn proprioception-debug-window |
380 [] | 389 [] |
381 (let [time (atom 0)] | 390 (let [time (atom 0)] |
404 roll. Pressing key-r/key-t should move the blue bar up and down and | 413 roll. Pressing key-r/key-t should move the blue bar up and down and |
405 change only the value of pitch. key-f/key-g moves it side to side | 414 change only the value of pitch. key-f/key-g moves it side to side |
406 and changes yaw. key-v/key-b will spin the blue segment clockwise | 415 and changes yaw. key-v/key-b will spin the blue segment clockwise |
407 and counterclockwise, and only affect roll." | 416 and counterclockwise, and only affect roll." |
408 [] | 417 [] |
409 (let [hand (box 1 0.2 0.2 :position (Vector3f. 0 2 0) | 418 (let [hand (box 0.2 1 0.2 :position (Vector3f. 0 0 0) |
410 :mass 0 :color ColorRGBA/Green :name "hand") | 419 :mass 0 :color ColorRGBA/Green :name "hand") |
411 finger (box 1 0.2 0.2 :position (Vector3f. 2.4 2 0) | 420 finger (box 0.2 1 0.2 :position (Vector3f. 0 2.4 0) |
412 :mass 1 :color ColorRGBA/Red :name "finger") | 421 :mass 1 :color ColorRGBA/Red :name "finger") |
413 joint-node (box 0.1 0.05 0.05 :color ColorRGBA/Yellow | 422 joint-node (box 0.1 0.05 0.05 :color ColorRGBA/Yellow |
414 :position (Vector3f. 1.2 2 0) | 423 :position (Vector3f. 0 1.2 0) |
424 :rotation (doto (Quaternion.) | |
425 (.fromAngleAxis | |
426 (/ Math/PI 2) | |
427 (Vector3f. 0 0 1))) | |
415 :physical? false) | 428 :physical? false) |
416 joint (join-at-point hand finger (Vector3f. 1.2 2 0 )) | 429 joint (join-at-point hand finger (Vector3f. 0 1.2 0 )) |
417 creature (nodify [hand finger joint-node]) | 430 creature (nodify [hand finger joint-node]) |
431 finger-control (.getControl finger RigidBodyControl) | |
432 hand-control (.getControl hand RigidBodyControl)] | |
433 | |
434 | |
435 (let | |
418 ;; ******************************************* | 436 ;; ******************************************* |
419 | 437 |
420 floor (box 10 10 10 :position (Vector3f. 0 -15 0) | 438 [floor (box 10 10 10 :position (Vector3f. 0 -15 0) |
421 :mass 0 :color ColorRGBA/Gray) | 439 :mass 0 :color ColorRGBA/Gray) |
422 | 440 |
423 root (nodify [creature floor]) | 441 root (nodify [creature floor]) |
424 prop (joint-proprioception creature joint-node) | 442 prop (joint-proprioception creature joint-node) |
425 prop-view (proprioception-debug-window) | 443 prop-view (proprioception-debug-window) |
426 finger-control (.getControl finger RigidBodyControl) | |
427 hand-control (.getControl hand RigidBodyControl) | |
428 | 444 |
429 controls | 445 controls |
430 (merge standard-debug-controls | 446 (merge standard-debug-controls |
431 {"key-o" | 447 {"key-o" |
432 (fn [_ _] (.setEnabled finger-control true)) | 448 (fn [_ _] (.setEnabled finger-control true)) |
469 ["key-y" "key-u" "key-h" "key-j" "key-n" "key-m"] | 485 ["key-y" "key-u" "key-h" "key-j" "key-n" "key-m"] |
470 [10 10 10 10 1 1] | 486 [10 10 10 10 1 1] |
471 (with-movement | 487 (with-movement |
472 finger | 488 finger |
473 ["key-r" "key-t" "key-f" "key-g" "key-v" "key-b"] | 489 ["key-r" "key-t" "key-f" "key-g" "key-v" "key-b"] |
474 [10 10 10 10 1 1] | 490 [1 1 10 10 10 10] |
475 [root | 491 [root |
476 controls | 492 controls |
477 (fn [world] | 493 (fn [world] |
478 (.setTimer world (com.aurellem.capture.RatchetTimer. 60)) | 494 (.setTimer world (com.aurellem.capture.RatchetTimer. 60)) |
479 (set-gravity world (Vector3f. 0 0 0)) | 495 (set-gravity world (Vector3f. 0 0 0)) |
480 (light-up-everything world)) | 496 (light-up-everything world)) |
481 (fn [_ _] (prop-view (list (prop))))]))))) | 497 (fn [_ _] (prop-view (list (prop))))])))))) |
482 | 498 |
483 #+end_src | 499 #+end_src |
484 | 500 |
485 #+results: test-body | 501 #+results: test-body |
486 : #'cortex.test.body/test-proprioception | 502 : #'cortex.test.body/test-proprioception |
906 (fn [world] | 922 (fn [world] |
907 (set-gravity world Vector3f/ZERO) | 923 (set-gravity world Vector3f/ZERO) |
908 (light-up-everything world) | 924 (light-up-everything world) |
909 (.setTimer world (NanoTimer.))) | 925 (.setTimer world (NanoTimer.))) |
910 (fn [_ _] | 926 (fn [_ _] |
911 (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0])))))) | 927 (dorun (motor-map [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 |
928 0])))))) | |
929 | |
930 (defn joint-proprioception [#^Node parts #^Node joint] | |
931 (let [[obj-a obj-b] (joint-targets parts joint) | |
932 joint-rot (.getWorldRotation joint) | |
933 pre-inv-a (.inverse (.getWorldRotation obj-a)) | |
934 x (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_X)) | |
935 y (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Y)) | |
936 z (.mult pre-inv-a (.mult joint-rot Vector3f/UNIT_Z)) | |
937 | |
938 x Vector3f/UNIT_Y | |
939 y Vector3f/UNIT_Z | |
940 z Vector3f/UNIT_X | |
941 | |
942 | |
943 tmp-rot-a (.getWorldRotation obj-a)] | |
944 (println-repl "x:" (.mult tmp-rot-a x)) | |
945 (println-repl "y:" (.mult tmp-rot-a y)) | |
946 (println-repl "z:" (.mult tmp-rot-a z)) | |
947 (println-repl "rot-a" (.getWorldRotation obj-a)) | |
948 (println-repl "rot-b" (.getWorldRotation obj-b)) | |
949 (println-repl "joint-rot" joint-rot) | |
950 ;; this function will report proprioceptive information for the | |
951 ;; joint. | |
952 (fn [] | |
953 ;; x is the "twist" axis, y and z are the "bend" axes | |
954 (let [rot-a (.getWorldRotation obj-a) | |
955 ;;inv-a (.inverse rot-a) | |
956 rot-b (.getWorldRotation obj-b) | |
957 ;;relative (.mult rot-b inv-a) | |
958 basis (doto (Matrix3f.) | |
959 (.setColumn 0 (.mult rot-a x)) | |
960 (.setColumn 1 (.mult rot-a y)) | |
961 (.setColumn 2 (.mult rot-a z))) | |
962 rotation-about-joint | |
963 (doto (Quaternion.) | |
964 (.fromRotationMatrix | |
965 (.mult (.invert basis) | |
966 (.toRotationMatrix rot-b)))) | |
967 [yaw roll pitch] | |
968 (seq (.toAngles rotation-about-joint nil))] | |
969 ;;return euler angles of the quaternion around the new basis | |
970 [yaw roll pitch])))) | |
971 | |
912 #+end_src | 972 #+end_src |
913 | 973 |
914 | 974 |
915 | 975 |
916 | 976 |