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