Mercurial > cortex
comparison org/body.org @ 202:d5c597a7aed4
writing prose for body.org
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 08 Feb 2012 05:50:15 -0700 |
parents | 026f69582022 |
children | 0e5d5ee5a914 |
comparison
equal
deleted
inserted
replaced
201:1c915cc1118b | 202:d5c597a7aed4 |
---|---|
1 #+title: The BODY!!! | 1 #+title: Building a Body |
2 #+author: Robert McIntyre | 2 #+author: Robert McIntyre |
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 * Making a solid, connected body. | 8 |
9 #+name: joints | 9 * Design Constraints |
10 | |
11 I use [[www.blender.org/][blender]] to design bodies. The design of the bodies is | |
12 determined by the requirements of the AI that will use them. The | |
13 bodies must be easy for an AI to sense and control, and they must be | |
14 relatively simple for jMonkeyEngine to compute. | |
15 | |
16 ** Bag of Bones | |
17 | |
18 How to create such a body? One option I ultimately rejected is to use | |
19 blender's [[http://wiki.blender.org/index.php/Doc:2.6/Manual/Rigging/Armatures][armature]] system. The idea would have been to define a mesh | |
20 which describes the creature's entire body. To this you add an | |
21 (skeleton) which deforms this mesh. This technique is used extensively | |
22 to model humans and create realistic animations. It is hard to use for | |
23 my purposes because it is difficult to update the creature's Physics | |
24 Collision Mesh in tandem with its Geometric Mesh under the influence | |
25 of the armature. Withouth this the creature will not be able to grab | |
26 things in its environment, and it won't be able to tell where its | |
27 physical body is by using its eyes. Also, armatures do not specify | |
28 any rotational limits for a joint, making it hard to model elbows, | |
29 shoulders, etc. | |
30 | |
31 ** EVE | |
32 | |
33 Instead of using the human-like "deformable bag of bones" approach, I | |
34 decided to base my body plans on the robot EVE from the movie wall-E. | |
35 | |
36 #+caption: EVE from the movie WALL-E. This body plan turns out to be much better suited to my purposes than a more human-like one. | |
37 [[../images/Eve.jpg]] | |
38 | |
39 The main reason that I use eve-style bodies is so that there will be | |
40 correspondence between the AI's vision and the physical presence of | |
41 its body. | |
42 | |
43 * Solidifying the Body | |
44 | |
45 Here is a hand designed eve-style in blender. | |
46 | |
47 | |
48 #+attr_html: width="500" | |
49 [[../images/hand-screenshot0.png]] | |
50 | |
51 If we load it directly into jMonkeyEngine, we get this: | |
52 | |
53 #+name: test-0 | |
54 #+begin_src clojure | |
55 (ns cortex.test.body | |
56 (:use (cortex world util body)) | |
57 (:import (com.aurellem.capture Capture RatchetTimer) | |
58 (com.jme3.math Quaternion Vector3f) | |
59 java.io.File)) | |
60 | |
61 (def hand-path "Models/test-creature/hand.blend") | |
62 | |
63 (defn hand [] (load-blender-model hand-path)) | |
64 | |
65 (defn setup [world] | |
66 (let [cam (.getCamera world)] | |
67 (println-repl cam) | |
68 (.setLocation | |
69 cam (Vector3f. | |
70 -6.9015837, 8.644911, 5.6043186)) | |
71 (.setRotation | |
72 cam | |
73 (Quaternion. | |
74 0.14046453, 0.85894054, -0.34301838, 0.3533118))) | |
75 (light-up-everything world) | |
76 (.setTimer world (RatchetTimer. 60)) | |
77 world) | |
78 | |
79 (defn test-one [] | |
80 (world (hand) | |
81 standard-debug-controls | |
82 (comp | |
83 #(Capture/captureVideo | |
84 % (File. "/home/r/proj/cortex/render/body/1")) | |
85 setup) | |
86 no-op)) | |
87 #+end_src | |
88 | |
89 | |
90 #+begin_src clojure :results silent | |
91 (.start (cortex.test.body/test-one)) | |
92 #+end_src | |
93 | |
94 #+begin_html | |
95 <video controls="controls" width="755"> | |
96 <source src="../video/ghost-hand.ogg" type="video/ogg" | |
97 preload="none" poster="../images/aurellem-1280x480.png" /> | |
98 </video> | |
99 #+end_html | |
100 | |
101 You will notice that the hand has no physical presence -- it's a | |
102 hologram through witch everything passes. Therefore, the first thing | |
103 to do is to make it solid. Blender has physics simulation on par with | |
104 jMonkeyEngine (they both use bullet as their physics backend), but it | |
105 can be difficult to translate between the two systems, so for now I | |
106 specify the mass of each object in blender and construct the physics | |
107 shape based on the mesh in jMonkeyEngine. | |
108 | |
109 #+name: joints-1 | |
110 #+begin_src clojure | |
111 (defn physical! | |
112 "Iterate through the nodes in creature and make them real physical | |
113 objects in the simulation." | |
114 [#^Node creature] | |
115 (dorun | |
116 (map | |
117 (fn [geom] | |
118 (let [physics-control | |
119 (RigidBodyControl. | |
120 (HullCollisionShape. | |
121 (.getMesh geom)) | |
122 (if-let [mass (meta-data geom "mass")] | |
123 (do | |
124 (println-repl | |
125 "setting" (.getName geom) "mass to" (float mass)) | |
126 (float mass)) | |
127 (float 1)))] | |
128 (.addControl geom physics-control))) | |
129 (filter #(isa? (class %) Geometry ) | |
130 (node-seq creature))))) | |
131 #+end_src | |
132 | |
133 =(physical!)= iterates through a creature's node structure, creating | |
134 CollisionShapes for each geometry with the mass specified in that | |
135 geometry's meta-data. | |
136 | |
10 #+begin_src clojure | 137 #+begin_src clojure |
11 (ns cortex.body | 138 (in-ns 'cortex.test.body) |
12 "Assemble a physical creature using the definitions found in a | 139 |
13 specially prepared blender file. Creates rigid bodies and joints so | 140 (def normal-gravity |
14 that a creature can have a physical presense in the simulation." | 141 {"key-g" (fn [world _] |
15 {:author "Robert McIntyre"} | 142 (set-gravity world (Vector3f. 0 -9.81 0)))}) |
16 (:use (cortex world util sense)) | 143 |
17 (:use clojure.contrib.def) | 144 (defn floor [] |
18 (:import | 145 (box 10 3 10 :position (Vector3f. 0 -10 0) |
19 (com.jme3.math Vector3f Quaternion Vector2f Matrix3f) | 146 :color ColorRGBA/Gray :mass 0)) |
20 (com.jme3.bullet.joints | 147 |
21 SixDofJoint Point2PointJoint HingeJoint ConeJoint) | 148 (defn test-two [] |
22 com.jme3.bullet.control.RigidBodyControl | 149 (world (nodify |
23 com.jme3.collision.CollisionResults | 150 [(doto (hand) |
24 com.jme3.bounding.BoundingBox | 151 (physical!)) |
25 com.jme3.scene.Node | 152 (floor)]) |
26 com.jme3.scene.Geometry | 153 (merge standard-debug-controls normal-gravity) |
27 com.jme3.bullet.collision.shapes.HullCollisionShape)) | 154 (comp |
28 | 155 #(Capture/captureVideo |
156 % (File. "/home/r/proj/cortex/render/body/2")) | |
157 #(do (set-gravity % Vector3f/ZERO) %) | |
158 setup) | |
159 no-op)) | |
160 #+end_src | |
161 | |
162 #+begin_html | |
163 <video controls="controls" width="755"> | |
164 <source src="../video/crumbly-hand.ogg" type="video/ogg" | |
165 preload="none" poster="../images/aurellem-1280x480.png" /> | |
166 </video> | |
167 #+end_html | |
168 | |
169 Now that's some progress. | |
170 | |
171 | |
172 * Joints | |
173 | |
174 Obviously, an AI is not going to be doing much just lying in pieces on | |
175 the floor. So, the next step to making a proper body is to connect | |
176 those pieces together with joints. jMonkeyEngine has a large array of | |
177 joints available via bullet, such as Point2Point, Cone, Hinge, and a | |
178 generic Six Degree of Freedom joint, with or without spring | |
179 restitution. | |
180 | |
181 Although it should be possible to specify the joints using blender's | |
182 physics system, and then automatically import them with jMonkeyEngine, | |
183 the support isn't there yet, and there are a few problems with bullet | |
184 itself that need to be solved before it can happen. | |
185 | |
186 So, I will use the same system for specifying joints as I will do for | |
187 some senses. Each joint is specified by an empty node whose parent | |
188 has the name "joints". Their orientation and meta-data determine what | |
189 joint is created. | |
190 | |
191 [[../images/hand-screenshot1.png]] | |
192 | |
193 | |
194 | |
195 | |
196 #+name: joints-2 | |
197 #+begin_src clojure | |
29 (defn joint-targets | 198 (defn joint-targets |
30 "Return the two closest two objects to the joint object, ordered | 199 "Return the two closest two objects to the joint object, ordered |
31 from bottom to top according to the joint's rotation." | 200 from bottom to top according to the joint's rotation." |
32 [#^Node parts #^Node joint] | 201 [#^Node parts #^Node joint] |
33 (loop [radius (float 0.01)] | 202 (loop [radius (float 0.01)] |
181 ^{:arglists '([creature])} | 350 ^{:arglists '([creature])} |
182 joints | 351 joints |
183 (sense-nodes "joints") | 352 (sense-nodes "joints") |
184 "Return the children of the creature's \"joints\" node.") | 353 "Return the children of the creature's \"joints\" node.") |
185 | 354 |
186 (defn physical! | |
187 "Iterate through the nodes in creature and make them real physical | |
188 objects in the simulation." | |
189 [#^Node creature] | |
190 (dorun | |
191 (map | |
192 (fn [geom] | |
193 (let [physics-control | |
194 (RigidBodyControl. | |
195 (HullCollisionShape. | |
196 (.getMesh geom)) | |
197 (if-let [mass (meta-data geom "mass")] | |
198 (do | |
199 (println-repl | |
200 "setting" (.getName geom) "mass to" (float mass)) | |
201 (float mass)) | |
202 (float 1)))] | |
203 | |
204 (.addControl geom physics-control))) | |
205 (filter #(isa? (class %) Geometry ) | |
206 (node-seq creature))))) | |
207 | |
208 (defn joints! | 355 (defn joints! |
209 "Connect the solid parts of the creature with physical joints. The | 356 "Connect the solid parts of the creature with physical joints. The |
210 joints are taken from the \"joints\" node in the creature." | 357 joints are taken from the \"joints\" node in the creature." |
211 [#^Node creature] | 358 [#^Node creature] |
212 (dorun | 359 (dorun |
223 [#^Node creature] | 370 [#^Node creature] |
224 (physical! creature) | 371 (physical! creature) |
225 (joints! creature)) | 372 (joints! creature)) |
226 #+end_src | 373 #+end_src |
227 | 374 |
228 #+results: joints | 375 * Bookkeeping |
229 : #'cortex.body/body! | 376 |
230 | 377 #+name: body-0 |
231 #+results: proprioception | 378 #+begin_src clojure |
232 : #'cortex.body/proprioception-debug-window | 379 (ns cortex.body |
233 | 380 "Assemble a physical creature using the definitions found in a |
234 * Examples | 381 specially prepared blender file. Creates rigid bodies and joints so |
382 that a creature can have a physical presense in the simulation." | |
383 {:author "Robert McIntyre"} | |
384 (:use (cortex world util sense)) | |
385 (:use clojure.contrib.def) | |
386 (:import | |
387 (com.jme3.math Vector3f Quaternion Vector2f Matrix3f) | |
388 (com.jme3.bullet.joints | |
389 SixDofJoint Point2PointJoint HingeJoint ConeJoint) | |
390 com.jme3.bullet.control.RigidBodyControl | |
391 com.jme3.collision.CollisionResults | |
392 com.jme3.bounding.BoundingBox | |
393 com.jme3.scene.Node | |
394 com.jme3.scene.Geometry | |
395 com.jme3.bullet.collision.shapes.HullCollisionShape)) | |
396 #+end_src | |
397 | |
398 * Source | |
399 | |
400 * COMMENT Examples | |
235 | 401 |
236 #+name: test-body | 402 #+name: test-body |
237 #+begin_src clojure | 403 #+begin_src clojure |
238 (ns cortex.test.body | 404 (ns cortex.test.body |
239 (:use (cortex world util body)) | 405 (:use (cortex world util body)) |
965 #+begin_src clojure :tangle ../src/cortex/body.clj | 1131 #+begin_src clojure :tangle ../src/cortex/body.clj |
966 <<joints>> | 1132 <<joints>> |
967 #+end_src | 1133 #+end_src |
968 | 1134 |
969 #+begin_src clojure :tangle ../src/cortex/test/body.clj | 1135 #+begin_src clojure :tangle ../src/cortex/test/body.clj |
970 <<test-body>> | 1136 <<test-0>> |
971 #+end_src | 1137 #+end_src |
972 | 1138 |
973 | 1139 |
974 | 1140 |