diff 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
line wrap: on
line diff
     1.1 --- a/org/body.org	Tue Feb 07 07:13:45 2012 -0700
     1.2 +++ b/org/body.org	Wed Feb 08 05:50:15 2012 -0700
     1.3 @@ -1,31 +1,200 @@
     1.4 -#+title: The BODY!!!
     1.5 +#+title: Building a Body
     1.6  #+author: Robert McIntyre
     1.7  #+email: rlm@mit.edu
     1.8  #+description: Simulating a body (movement, touch, propioception) in jMonkeyEngine3.
     1.9  #+SETUPFILE: ../../aurellem/org/setup.org
    1.10  #+INCLUDE: ../../aurellem/org/level-0.org
    1.11  
    1.12 -* Making a solid, connected body.
    1.13 -#+name: joints
    1.14 +
    1.15 +* Design Constraints
    1.16 +
    1.17 +I use [[www.blender.org/][blender]] to design bodies.  The design of the bodies is
    1.18 +determined by the requirements of the AI that will use them. The
    1.19 +bodies must be easy for an AI to sense and control, and they must be
    1.20 +relatively simple for jMonkeyEngine to compute.  
    1.21 +
    1.22 +** Bag of Bones
    1.23 +
    1.24 +How to create such a body? One option I ultimately rejected is to use
    1.25 +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
    1.26 +which describes the creature's entire body. To this you add an
    1.27 +(skeleton) which deforms this mesh. This technique is used extensively
    1.28 +to model humans and create realistic animations. It is hard to use for
    1.29 +my purposes because it is difficult to update the creature's Physics
    1.30 +Collision Mesh in tandem with its Geometric Mesh under the influence
    1.31 +of the armature. Withouth this the creature will not be able to grab
    1.32 +things in its environment, and it won't be able to tell where its
    1.33 +physical body is by using its eyes. Also, armatures do not specify
    1.34 +any rotational limits for a joint, making it hard to model elbows,
    1.35 +shoulders, etc.
    1.36 +
    1.37 +** EVE
    1.38 +
    1.39 +Instead of using the human-like "deformable bag of bones" approach, I
    1.40 +decided to base my body plans on the robot EVE from the movie wall-E. 
    1.41 +
    1.42 +#+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.
    1.43 +[[../images/Eve.jpg]]
    1.44 +
    1.45 +The main reason that I use eve-style bodies is so that there will be
    1.46 +correspondence between the AI's vision and the physical presence of
    1.47 +its body. 
    1.48 +
    1.49 +* Solidifying the Body
    1.50 +
    1.51 +Here is a hand designed eve-style in blender.
    1.52 +
    1.53 +
    1.54 +#+attr_html: width="500"
    1.55 +[[../images/hand-screenshot0.png]]
    1.56 +
    1.57 +If we load it directly into jMonkeyEngine, we get this:
    1.58 +
    1.59 +#+name: test-0
    1.60 +#+begin_src clojure
    1.61 +(ns cortex.test.body
    1.62 +  (:use (cortex world util body))
    1.63 +  (:import (com.aurellem.capture Capture RatchetTimer)
    1.64 +           (com.jme3.math Quaternion Vector3f)
    1.65 +           java.io.File))
    1.66 +
    1.67 +(def hand-path "Models/test-creature/hand.blend")
    1.68 +
    1.69 +(defn hand [] (load-blender-model hand-path))
    1.70 +
    1.71 +(defn setup [world]
    1.72 +  (let [cam (.getCamera world)]
    1.73 +    (println-repl cam)
    1.74 +    (.setLocation
    1.75 +     cam (Vector3f. 
    1.76 +          -6.9015837, 8.644911, 5.6043186))
    1.77 +    (.setRotation
    1.78 +     cam
    1.79 +     (Quaternion.
    1.80 +      0.14046453, 0.85894054, -0.34301838, 0.3533118)))
    1.81 +  (light-up-everything world)
    1.82 +  (.setTimer world (RatchetTimer. 60))
    1.83 +  world)
    1.84 +
    1.85 +(defn test-one []
    1.86 +  (world (hand)
    1.87 +         standard-debug-controls
    1.88 +         (comp
    1.89 +          #(Capture/captureVideo
    1.90 +            % (File. "/home/r/proj/cortex/render/body/1"))
    1.91 +          setup)
    1.92 +         no-op))
    1.93 +#+end_src
    1.94 +
    1.95 +
    1.96 +#+begin_src clojure :results silent
    1.97 +(.start (cortex.test.body/test-one))
    1.98 +#+end_src
    1.99 +
   1.100 +#+begin_html
   1.101 +<video controls="controls" width="755">
   1.102 +  <source src="../video/ghost-hand.ogg" type="video/ogg"
   1.103 +	  preload="none" poster="../images/aurellem-1280x480.png" />
   1.104 +</video>
   1.105 +#+end_html
   1.106 +
   1.107 +You will notice that the hand has no physical presence -- it's a
   1.108 +hologram through witch everything passes.  Therefore, the first thing
   1.109 +to do is to make it solid.  Blender has physics simulation on par with
   1.110 +jMonkeyEngine (they both use bullet as their physics backend), but it
   1.111 +can be difficult to translate between the two systems, so for now I
   1.112 +specify the mass of each object in blender and construct the physics
   1.113 +shape based on the mesh in jMonkeyEngine.
   1.114 +
   1.115 +#+name: joints-1
   1.116 +#+begin_src clojure
   1.117 +(defn physical!
   1.118 +  "Iterate through the nodes in creature and make them real physical
   1.119 +   objects in the simulation."
   1.120 +  [#^Node creature]
   1.121 +  (dorun
   1.122 +   (map
   1.123 +    (fn [geom]
   1.124 +      (let [physics-control
   1.125 +            (RigidBodyControl.
   1.126 +             (HullCollisionShape.
   1.127 +              (.getMesh geom))
   1.128 +             (if-let [mass (meta-data geom "mass")]
   1.129 +               (do
   1.130 +                 (println-repl
   1.131 +                  "setting" (.getName geom) "mass to" (float mass))
   1.132 +                 (float mass))
   1.133 +               (float 1)))]
   1.134 +        (.addControl geom physics-control)))
   1.135 +    (filter #(isa? (class %) Geometry )
   1.136 +            (node-seq creature)))))
   1.137 +#+end_src
   1.138 +
   1.139 +=(physical!)= iterates through a creature's node structure, creating
   1.140 +CollisionShapes for each geometry with the mass specified in that
   1.141 +geometry's meta-data.
   1.142 +
   1.143  #+begin_src clojure 
   1.144 -(ns cortex.body
   1.145 -  "Assemble a physical creature using the definitions found in a
   1.146 -   specially prepared blender file. Creates rigid bodies and joints so
   1.147 -   that a creature can have a physical presense in the simulation."
   1.148 -  {:author "Robert McIntyre"}
   1.149 -  (:use (cortex world util sense))
   1.150 -  (:use clojure.contrib.def)
   1.151 -  (:import
   1.152 -   (com.jme3.math Vector3f Quaternion Vector2f Matrix3f)
   1.153 -   (com.jme3.bullet.joints
   1.154 -    SixDofJoint Point2PointJoint HingeJoint ConeJoint)
   1.155 -   com.jme3.bullet.control.RigidBodyControl
   1.156 -   com.jme3.collision.CollisionResults
   1.157 -   com.jme3.bounding.BoundingBox
   1.158 -   com.jme3.scene.Node
   1.159 -   com.jme3.scene.Geometry
   1.160 -   com.jme3.bullet.collision.shapes.HullCollisionShape))
   1.161 +(in-ns 'cortex.test.body)
   1.162  
   1.163 +(def normal-gravity 
   1.164 +  {"key-g" (fn [world _]
   1.165 +             (set-gravity world (Vector3f. 0 -9.81 0)))})
   1.166 +
   1.167 +(defn floor [] 
   1.168 +  (box 10 3 10 :position (Vector3f. 0 -10 0)
   1.169 +       :color ColorRGBA/Gray :mass 0))
   1.170 +
   1.171 +(defn test-two []
   1.172 +  (world (nodify
   1.173 +          [(doto (hand)
   1.174 +             (physical!))
   1.175 +          (floor)])
   1.176 +         (merge standard-debug-controls normal-gravity)
   1.177 +         (comp
   1.178 +          #(Capture/captureVideo
   1.179 +            % (File. "/home/r/proj/cortex/render/body/2"))
   1.180 +          #(do (set-gravity % Vector3f/ZERO) %)
   1.181 +          setup)
   1.182 +         no-op))
   1.183 +#+end_src
   1.184 +
   1.185 +#+begin_html
   1.186 +<video controls="controls" width="755">
   1.187 +  <source src="../video/crumbly-hand.ogg" type="video/ogg"
   1.188 +	  preload="none" poster="../images/aurellem-1280x480.png" />
   1.189 +</video>
   1.190 +#+end_html
   1.191 +
   1.192 +Now that's some progress.
   1.193 +
   1.194 +
   1.195 +* Joints
   1.196 +
   1.197 +Obviously, an AI is not going to be doing much just lying in pieces on
   1.198 +the floor.  So, the next step to making a proper body is to connect
   1.199 +those pieces together with joints.  jMonkeyEngine has a large array of
   1.200 +joints available via bullet, such as Point2Point, Cone, Hinge, and a
   1.201 +generic Six Degree of Freedom joint, with or without spring
   1.202 +restitution.
   1.203 +
   1.204 +Although it should be possible to specify the joints using blender's
   1.205 +physics system, and then automatically import them with jMonkeyEngine,
   1.206 +the support isn't there yet, and there are a few problems with bullet
   1.207 +itself that need to be solved before it can happen. 
   1.208 +
   1.209 +So, I will use the same system for specifying joints as I will do for
   1.210 +some senses.  Each joint is specified by an empty node whose parent
   1.211 +has the name "joints". Their orientation and meta-data determine what
   1.212 +joint is created.
   1.213 +
   1.214 +[[../images/hand-screenshot1.png]]
   1.215 +
   1.216 +
   1.217 +
   1.218 +
   1.219 +#+name: joints-2
   1.220 +#+begin_src clojure 
   1.221  (defn joint-targets
   1.222    "Return the two closest two objects to the joint object, ordered
   1.223    from bottom to top according to the joint's rotation."
   1.224 @@ -183,28 +352,6 @@
   1.225    (sense-nodes "joints")
   1.226    "Return the children of the creature's \"joints\" node.")
   1.227  
   1.228 -(defn physical!
   1.229 -  "Iterate through the nodes in creature and make them real physical
   1.230 -   objects in the simulation."
   1.231 -  [#^Node creature]
   1.232 -  (dorun
   1.233 -   (map
   1.234 -    (fn [geom]
   1.235 -      (let [physics-control
   1.236 -            (RigidBodyControl.
   1.237 -             (HullCollisionShape.
   1.238 -              (.getMesh geom))
   1.239 -             (if-let [mass (meta-data geom "mass")]
   1.240 -               (do
   1.241 -                 (println-repl
   1.242 -                  "setting" (.getName geom) "mass to" (float mass))
   1.243 -                 (float mass))
   1.244 -               (float 1)))]
   1.245 -               
   1.246 -        (.addControl geom physics-control)))
   1.247 -    (filter #(isa? (class %) Geometry )
   1.248 -            (node-seq creature)))))
   1.249 -
   1.250  (defn joints!
   1.251    "Connect the solid parts of the creature with physical joints. The
   1.252     joints are taken from the \"joints\" node in the creature."
   1.253 @@ -225,13 +372,32 @@
   1.254    (joints! creature))
   1.255  #+end_src
   1.256  
   1.257 -#+results: joints
   1.258 -: #'cortex.body/body!
   1.259 +* Bookkeeping
   1.260  
   1.261 -#+results: proprioception
   1.262 -: #'cortex.body/proprioception-debug-window
   1.263 +#+name: body-0
   1.264 +#+begin_src clojure
   1.265 +(ns cortex.body
   1.266 +  "Assemble a physical creature using the definitions found in a
   1.267 +   specially prepared blender file. Creates rigid bodies and joints so
   1.268 +   that a creature can have a physical presense in the simulation."
   1.269 +  {:author "Robert McIntyre"}
   1.270 +  (:use (cortex world util sense))
   1.271 +  (:use clojure.contrib.def)
   1.272 +  (:import
   1.273 +   (com.jme3.math Vector3f Quaternion Vector2f Matrix3f)
   1.274 +   (com.jme3.bullet.joints
   1.275 +    SixDofJoint Point2PointJoint HingeJoint ConeJoint)
   1.276 +   com.jme3.bullet.control.RigidBodyControl
   1.277 +   com.jme3.collision.CollisionResults
   1.278 +   com.jme3.bounding.BoundingBox
   1.279 +   com.jme3.scene.Node
   1.280 +   com.jme3.scene.Geometry
   1.281 +   com.jme3.bullet.collision.shapes.HullCollisionShape))
   1.282 +#+end_src
   1.283  
   1.284 -* Examples
   1.285 +* Source 
   1.286 +
   1.287 +* COMMENT Examples
   1.288  
   1.289  #+name: test-body
   1.290  #+begin_src clojure
   1.291 @@ -967,7 +1133,7 @@
   1.292  #+end_src
   1.293  
   1.294  #+begin_src clojure :tangle ../src/cortex/test/body.clj
   1.295 -<<test-body>>
   1.296 +<<test-0>>
   1.297  #+end_src  
   1.298  
   1.299