Mercurial > cortex
comparison org/body.org @ 134:ac350a0ac6b0
proprioception refrence frame is wrong, trying to fix...
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 01 Feb 2012 02:44:07 -0700 |
parents | 2ed7e60d3821 |
children | 421cc43441ae |
comparison
equal
deleted
inserted
replaced
133:2ed7e60d3821 | 134:ac350a0ac6b0 |
---|---|
14 com.jme3.math.Vector3f | 14 com.jme3.math.Vector3f |
15 com.jme3.math.Quaternion | 15 com.jme3.math.Quaternion |
16 com.jme3.math.Vector2f | 16 com.jme3.math.Vector2f |
17 com.jme3.math.Matrix3f | 17 com.jme3.math.Matrix3f |
18 com.jme3.bullet.control.RigidBodyControl)) | 18 com.jme3.bullet.control.RigidBodyControl)) |
19 | |
20 (comment | |
21 (defn joint-proprioception | |
22 "Relative position information for a two-part system connected by a | |
23 joint. Gives the pitch, yaw, and roll of the 'B' object relative to | |
24 the 'A' object, as determined by the joint." | |
25 [joint] | |
26 (let [object-a (.getUserObject (.getBodyA joint)) | |
27 object-b (.getUserObject (.getBodyB joint)) | |
28 arm-a | |
29 (.normalize | |
30 (.subtract | |
31 (.localToWorld object-a (.getPivotA joint) nil) | |
32 (.getWorldTranslation object-a))) | |
33 | |
34 ;; this is probably wrong! | |
35 rotate-a | |
36 (doto (Matrix3f.) | |
37 (.fromStartEndVectors arm-a Vector3f/UNIT_X)) | |
38 | |
39 arm-b | |
40 (.mult | |
41 rotate-a | |
42 (.normalize | |
43 (.subtract | |
44 (.localToWorld object-b (.getPivotB joint) nil) | |
45 (.getWorldTranslation object-b)))) | |
46 pitch | |
47 (.angleBetween | |
48 (.normalize (Vector2f. (.getX arm-b) (.getY arm-b))) | |
49 (Vector2f. 1 0)) | |
50 yaw | |
51 (.angleBetween | |
52 (.normalize (Vector2f. (.getX arm-b) (.getZ arm-b))) | |
53 (Vector2f. 1 0)) | |
54 | |
55 roll | |
56 (project-quaternion | |
57 (.mult | |
58 (.getLocalRotation object-b) | |
59 (doto (Quaternion.) | |
60 (.fromRotationMatrix rotate-a))) | |
61 arm-b)] | |
62 ;;(println-repl (.getName object-a) (.getName object-b)) | |
63 [pitch yaw roll])) | |
64 ) | |
65 | |
66 (defn any-orthogonal | |
67 "Generate an arbitray (but stable) orthogonal vector to a given | |
68 vector." | |
69 [vector] | |
70 (let [x (.getX vector) | |
71 y (.getY vector) | |
72 z (.getZ vector)] | |
73 (cond | |
74 (not= x (float 0)) (Vector3f. (- z) 0 x) | |
75 (not= y (float 0)) (Vector3f. 0 (- z) y) | |
76 (not= z (float 0)) (Vector3f. 0 (- z) y) | |
77 true Vector3f/ZERO))) | |
78 | |
79 (comment | |
80 (defn project-quaternion | |
81 "From http://stackoverflow.com/questions/3684269/ | |
82 component-of-a-quaternion-rotation-around-an-axis. | |
83 | |
84 Determine the amount of rotation a quaternion will | |
85 cause about a given axis." | |
86 [#^Quaternion q #^Vector3f axis] | |
87 (let [basis-1 (any-orthogonal axis) | |
88 basis-2 (.cross axis basis-1) | |
89 rotated (.mult q basis-1) | |
90 alpha (.dot basis-1 (.project rotated basis-1)) | |
91 beta (.dot basis-2 (.project rotated basis-2))] | |
92 (Math/atan2 beta alpha))) | |
93 ) | |
94 | |
95 (defn right-handed? [vec1 vec2 vec3] | |
96 (< 0 (.dot (.cross vec1 vec2) vec3))) | |
97 | |
98 (defn absolute-angle [vec1 vec2 axis] | |
99 (let [angle (.angleBetween vec1 vec2)] | |
100 (if (right-handed? vec1 vec2 axis) | |
101 angle (- (* 2 Math/PI) angle)))) | |
102 | |
103 (defn angle-min [& angles] | |
104 (first | |
105 (sort-by | |
106 (fn [angle] | |
107 (let [in-circle (Math/abs (rem angle (* 2 Math/PI)))] | |
108 (min in-circle | |
109 (- (* Math/PI 2) in-circle)))) | |
110 angles))) | |
111 | |
112 (defn project-quaternion | |
113 "From http://stackoverflow.com/questions/3684269/ | |
114 component-of-a-quaternion-rotation-around-an-axis. | |
115 | |
116 Determine the amount of rotation a quaternion will | |
117 cause about a given axis." | |
118 [#^Quaternion q #^Vector3f axis] | |
119 (let [axis (.normalize axis) | |
120 basis-1 (.normalize (any-orthogonal axis)) | |
121 basis-2 (.cross axis basis-1) | |
122 rotated-1 (.mult q basis-1) | |
123 basis-1* (.normalize | |
124 (.add (.project rotated-1 basis-1) | |
125 (.project rotated-1 basis-2))) | |
126 rotated-2 (.mult q basis-2) | |
127 basis-2* (.normalize | |
128 (.add (.project rotated-2 basis-1) | |
129 (.project rotated-2 basis-2))) | |
130 angle-1 | |
131 (absolute-angle basis-1 basis-1* axis) | |
132 angle-2 | |
133 (absolute-angle basis-2 basis-2* axis) | |
134 | |
135 | |
136 angle (angle-min angle-1 angle-2) | |
137 ] | |
138 | |
139 | |
140 ;; be sure to get sign from cross product | |
141 (if false | |
142 (do | |
143 (println-repl "axis" axis) | |
144 (println-repl "basis-1" basis-1) | |
145 (println-repl "basis-2" basis-2) | |
146 (println-repl "rotated-1" rotated-1) | |
147 (println-repl "rotated-2" rotated-2) | |
148 (println-repl "basis-1*" basis-1*) | |
149 (println-repl "basis-2*" basis-2*) | |
150 (println-repl "angle-1" angle-1) | |
151 (println-repl "angle-2" angle-2) | |
152 | |
153 (println-repl "angle" angle) | |
154 (println-repl ""))) | |
155 angle)) | |
156 | |
157 | 19 |
158 (import com.jme3.scene.Node) | 20 (import com.jme3.scene.Node) |
159 | 21 |
160 (defn joint-proprioception [#^Node parts #^Node joint] | 22 (defn joint-proprioception [#^Node parts #^Node joint] |
161 (let [[obj-a obj-b] (cortex.silly/joint-targets parts joint) | 23 (let [[obj-a obj-b] (cortex.silly/joint-targets parts joint) |
185 ;;[yaw pitch roll] | 47 ;;[yaw pitch roll] |
186 [yaw roll pitch] | 48 [yaw roll pitch] |
187 )))) | 49 )))) |
188 | 50 |
189 | 51 |
190 (comment | |
191 | |
192 (defn joint-proprioception | |
193 [joint] | |
194 (let [object-a (.getUserObject (.getBodyA joint)) | |
195 object-b (.getUserObject (.getBodyB joint)) | |
196 rot-a (.clone (.getWorldRotation object-a)) | |
197 rot-b (.clone (.getWorldRotation object-b)) | |
198 ] | |
199 | |
200 (.mult rot-b (.inverse rot-a)) | |
201 | |
202 ;; object-a == hand | |
203 ;; object-b == finger | |
204 )) | |
205 ) | |
206 ;; (defn joint-proprioception* | |
207 ;; [joint] | |
208 ;; (let [object-a (.getUserObject (.getBodyA joint)) | |
209 ;; object-b (.getUserObject (.getBodyB joint)) | |
210 | |
211 ;; rotate-a (.clone (.getWorldRotation object-a)) | |
212 ;; rotate-b (.clone (.getWorldRotation object-b)) | |
213 | |
214 ;; rotate-rel (.mult rotate-b (.inverse rotate-a)) | |
215 ;; ] | |
216 ;; ((comp vec map) (partial project-quaternion rotate-rel) | |
217 ;; [Vector3f/UNIT_X | |
218 ;; Vector3f/UNIT_Y | |
219 ;; Vector3f/UNIT_Z]))) | |
220 | |
221 | |
222 (defn proprioception | 52 (defn proprioception |
223 "Create a function that provides proprioceptive information about an | 53 "Create a function that provides proprioceptive information about an |
224 entire body." | 54 entire body." |
225 [body] | 55 [#^Node creature] |
226 ;; extract the body's joints | 56 ;; extract the body's joints |
227 (let [joints | 57 (let [joints (cortex.silly/creature-joints creature) |
228 (distinct | 58 senses (map (partial joint-proprioception creature) joints)] |
229 (reduce | |
230 concat | |
231 (map #(.getJoints %) | |
232 (keep | |
233 #(.getControl % RigidBodyControl) | |
234 (node-seq body)))))] | |
235 (fn [] | 59 (fn [] |
236 (map joint-proprioception joints)))) | 60 (map #(%) senses)))) |
237 | 61 |
238 #+end_src | 62 #+end_src |
239 | 63 |
240 #+results: proprioception | 64 #+results: proprioception |
241 : #'cortex.body/proprioception | 65 : #'cortex.body/proprioception |