Mercurial > cortex
comparison org/body.org @ 175:0b9ae09eaec3
renamed functions in body
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 04 Feb 2012 06:47:07 -0700 |
parents | 33278bf028e7 |
children | 026f69582022 |
comparison
equal
deleted
inserted
replaced
174:136349ac6972 | 175:0b9ae09eaec3 |
---|---|
3 #+email: rlm@mit.edu | 3 #+email: rlm@mit.edu |
4 #+description: Simulating a body (movement, touch, propioception) in jMonkeyEngine3. | 4 #+description: Simulating a body (movement, touch, propioception) in jMonkeyEngine3. |
5 #+SETUPFILE: ../../aurellem/org/setup.org | 5 #+SETUPFILE: ../../aurellem/org/setup.org |
6 #+INCLUDE: ../../aurellem/org/level-0.org | 6 #+INCLUDE: ../../aurellem/org/level-0.org |
7 | 7 |
8 * Proprioception | 8 * Making a solid, connected body. |
9 #+name: proprioception | 9 #+name: joints |
10 #+begin_src clojure | 10 #+begin_src clojure |
11 (ns cortex.body | 11 (ns cortex.body |
12 (:use (cortex world util sense)) | 12 (:use (cortex world util sense)) |
13 (:import | 13 (:import |
14 com.jme3.math.Vector3f | 14 com.jme3.math.Vector3f |
18 com.jme3.bullet.control.RigidBodyControl | 18 com.jme3.bullet.control.RigidBodyControl |
19 com.jme3.collision.CollisionResults | 19 com.jme3.collision.CollisionResults |
20 com.jme3.bounding.BoundingBox | 20 com.jme3.bounding.BoundingBox |
21 com.jme3.scene.Node)) | 21 com.jme3.scene.Node)) |
22 | 22 |
23 (use 'clojure.contrib.def) | |
23 (cortex.import/mega-import-jme3) | 24 (cortex.import/mega-import-jme3) |
24 | |
25 (defn jme-to-blender | |
26 "Convert from JME coordinates to Blender coordinates" | |
27 [#^Vector3f in] | |
28 (Vector3f. (.getX in) | |
29 (- (.getZ in)) | |
30 (.getY in))) | |
31 | |
32 (defn blender-to-jme | |
33 "Convert from Blender coordinates to JME coordinates" | |
34 [#^Vector3f in] | |
35 (Vector3f. (.getX in) | |
36 (.getZ in) | |
37 (- (.getY in)))) | |
38 | |
39 | 25 |
40 (defn joint-targets | 26 (defn joint-targets |
41 "Return the two closest two objects to the joint object, ordered | 27 "Return the two closest two objects to the joint object, ordered |
42 from bottom to top according to the joint's rotation." | 28 from bottom to top according to the joint's rotation." |
43 [#^Node parts #^Node joint] | 29 [#^Node parts #^Node joint] |
63 (.dot (Vector3f. 1 1 1) | 49 (.dot (Vector3f. 1 1 1) |
64 v)) | 50 v)) |
65 (take 2 targets)) | 51 (take 2 targets)) |
66 (recur (float (* radius 2)))))))) | 52 (recur (float (* radius 2)))))))) |
67 | 53 |
68 (defn creature-joints | |
69 "Return the children of the creature's \"joints\" node." | |
70 [#^Node creature] | |
71 (if-let [joint-node (.getChild creature "joints")] | |
72 (seq (.getChildren joint-node)) | |
73 (do (println-repl "could not find JOINTS node") []))) | |
74 | |
75 (defmulti joint-dispatch | 54 (defmulti joint-dispatch |
76 "Translate blender pseudo-joints into real JME joints." | 55 "Translate blender pseudo-joints into real JME joints." |
77 (fn [constraints & _] | 56 (fn [constraints & _] |
78 (:type constraints))) | 57 (:type constraints))) |
79 | 58 |
156 (.setLimit (float limit-xz) | 135 (.setLimit (float limit-xz) |
157 (float limit-xy) | 136 (float limit-xy) |
158 (float twist))))) | 137 (float twist))))) |
159 | 138 |
160 (defn connect | 139 (defn connect |
161 "here are some examples: | 140 "Create a joint between 'obj-a and 'obj-b at the location of |
141 'joint. The type of joint is determined by the metadata on 'joint. | |
142 | |
143 Here are some examples: | |
162 {:type :point} | 144 {:type :point} |
163 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)} | 145 {:type :hinge :limit [0 (/ Math/PI 2)] :axis (Vector3f. 0 1 0)} |
164 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints) | 146 (:axis defaults to (Vector3f. 1 0 0) if not provided for hinge joints) |
165 | 147 |
166 {:type :cone :limit-xz 0] | 148 {:type :cone :limit-xz 0] |
190 control-a control-b | 172 control-a control-b |
191 pivot-a pivot-b | 173 pivot-a pivot-b |
192 joint-rotation)) | 174 joint-rotation)) |
193 (println-repl "could not find joint meta-data!")))) | 175 (println-repl "could not find joint meta-data!")))) |
194 | 176 |
195 | 177 (defvar |
196 | 178 ^{:arglists '([creature])} |
197 | 179 joints |
198 (defn assemble-creature [#^Node pieces joints] | 180 (sense-nodes "joints") |
181 "Return the children of the creature's \"joints\" node.") | |
182 | |
183 (defn physical! | |
184 "Iterate through the nodes in creature and make them real physical | |
185 objects in the simulation." | |
186 [#^Node creature] | |
199 (dorun | 187 (dorun |
200 (map | 188 (map |
201 (fn [geom] | 189 (fn [geom] |
202 (let [physics-control | 190 (let [physics-control |
203 (RigidBodyControl. | 191 (RigidBodyControl. |
210 (float mass)) | 198 (float mass)) |
211 (float 1)))] | 199 (float 1)))] |
212 | 200 |
213 (.addControl geom physics-control))) | 201 (.addControl geom physics-control))) |
214 (filter #(isa? (class %) Geometry ) | 202 (filter #(isa? (class %) Geometry ) |
215 (node-seq pieces)))) | 203 (node-seq creature))))) |
204 | |
205 (defn joints! | |
206 "Connect the solid parts of the creature with physical joints. The | |
207 joints are taken from the \"joints\" node in the creature." | |
208 [#^Node creature] | |
216 (dorun | 209 (dorun |
217 (map | 210 (map |
218 (fn [joint] | 211 (fn [joint] |
219 (let [[obj-a obj-b] (joint-targets pieces joint)] | 212 (let [[obj-a obj-b] (joint-targets creature joint)] |
220 (connect obj-a obj-b joint))) | 213 (connect obj-a obj-b joint))) |
221 joints)) | 214 (joints creature)))) |
222 pieces) | 215 |
223 | 216 (defn body! |
224 | 217 "Endow the creature with a physical body connected with joints. The |
225 ;; TODO implement a function that adds joints in the style of the | 218 particulars of the joints and the masses of each pody part are |
226 ;; other sense functions | 219 determined in blender." |
227 | 220 [#^Node creature] |
228 | 221 (physical! creature) |
229 | 222 (joints! creature)) |
230 (import java.awt.image.BufferedImage) | 223 |
231 | 224 |
232 (defn draw-sprite [image sprite x y color ] | |
233 (dorun | |
234 (for [[u v] sprite] | |
235 (.setRGB image (+ u x) (+ v y) color)))) | |
236 | |
237 (defn view-angle | |
238 "create a debug view of an angle" | |
239 [color] | |
240 (let [image (BufferedImage. 50 50 BufferedImage/TYPE_INT_RGB) | |
241 previous (atom [25 25]) | |
242 sprite [[0 0] [0 1] | |
243 [0 -1] [-1 0] [1 0]]] | |
244 (fn [angle] | |
245 (let [angle (float angle)] | |
246 (let [position | |
247 [(+ 25 (int (* 20 (Math/cos angle)))) | |
248 (+ 25 (int (* -20 (Math/sin angle))))]] | |
249 (draw-sprite image sprite (@previous 0) (@previous 1) 0x000000) | |
250 (draw-sprite image sprite (position 0) (position 1) color) | |
251 (reset! previous position)) | |
252 image)))) | |
253 | |
254 (defn proprioception-debug-window | |
255 [] | |
256 (let [heading (view-angle 0xFF0000) | |
257 pitch (view-angle 0x00FF00) | |
258 roll (view-angle 0xFFFFFF) | |
259 v-heading (view-image) | |
260 v-pitch (view-image) | |
261 v-roll (view-image) | |
262 ] | |
263 (fn [prop-data] | |
264 (dorun | |
265 (map | |
266 (fn [[h p r]] | |
267 (v-heading (heading h)) | |
268 (v-pitch (pitch p)) | |
269 (v-roll (roll r))) | |
270 prop-data))))) | |
271 | 225 |
272 | 226 |
273 #+end_src | 227 #+end_src |
228 | |
229 #+results: joints | |
230 : #'cortex.body/body! | |
274 | 231 |
275 #+results: proprioception | 232 #+results: proprioception |
276 : #'cortex.body/proprioception-debug-window | 233 : #'cortex.body/proprioception-debug-window |
277 | |
278 * Motor Control | |
279 #+name: motor-control | |
280 #+begin_src clojure | |
281 (in-ns 'cortex.body) | |
282 | |
283 ;; surprisingly enough, terristerial creatures only move by using | |
284 ;; torque applied about their joints. There's not a single straight | |
285 ;; line of force in the human body at all! (A straight line of force | |
286 ;; would correspond to some sort of jet or rocket propulseion.) | |
287 | |
288 (defn vector-motor-control | |
289 "Create a function that accepts a sequence of Vector3f objects that | |
290 describe the torque to be applied to each part of the body." | |
291 [body] | |
292 (let [nodes (node-seq body) | |
293 controls (keep #(.getControl % RigidBodyControl) nodes)] | |
294 (fn [torques] | |
295 (map #(.applyTorque %1 %2) | |
296 controls torques)))) | |
297 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
298 #+end_src | |
299 | |
300 ## note -- might want to add a lower dimensional, discrete version of | |
301 ## this if it proves useful from a x-modal clustering perspective. | |
302 | 234 |
303 * Examples | 235 * Examples |
304 | 236 |
305 #+name: test-body | 237 #+name: test-body |
306 #+begin_src clojure | 238 #+begin_src clojure |
1030 | 962 |
1031 | 963 |
1032 | 964 |
1033 * COMMENT generate Source | 965 * COMMENT generate Source |
1034 #+begin_src clojure :tangle ../src/cortex/body.clj | 966 #+begin_src clojure :tangle ../src/cortex/body.clj |
1035 <<proprioception>> | 967 <<joints>> |
1036 <<motor-control>> | |
1037 #+end_src | 968 #+end_src |
1038 | 969 |
1039 #+begin_src clojure :tangle ../src/cortex/test/body.clj | 970 #+begin_src clojure :tangle ../src/cortex/test/body.clj |
1040 <<test-body>> | 971 <<test-body>> |
1041 #+end_src | 972 #+end_src |