rlm@73
|
1 #+title: First attempt at a creature!
|
rlm@73
|
2 #+author: Robert McIntyre
|
rlm@73
|
3 #+email: rlm@mit.edu
|
rlm@73
|
4 #+description:
|
rlm@73
|
5 #+keywords: simulation, jMonkeyEngine3, clojure
|
rlm@73
|
6 #+SETUPFILE: ../../aurellem/org/setup.org
|
rlm@73
|
7 #+INCLUDE: ../../aurellem/org/level-0.org
|
rlm@73
|
8
|
rlm@73
|
9 * Intro
|
rlm@73
|
10 So far, I've made the following senses --
|
rlm@73
|
11 - Vision
|
rlm@73
|
12 - Hearing
|
rlm@73
|
13 - Touch
|
rlm@73
|
14 - Proprioception
|
rlm@73
|
15
|
rlm@73
|
16 And one effector:
|
rlm@73
|
17 - Movement
|
rlm@73
|
18
|
rlm@73
|
19 However, the code so far has only enabled these senses, but has not
|
rlm@73
|
20 actually implemented them. For example, there is still a lot of work
|
rlm@73
|
21 to be done for vision. I need to be able to create an /eyeball/ in
|
rlm@73
|
22 simulation that can be moved around and see the world from different
|
rlm@73
|
23 angles. I also need to determine weather to use log-polar or cartesian
|
rlm@73
|
24 for the visual input, and I need to determine how/wether to
|
rlm@73
|
25 disceritise the visual input.
|
rlm@73
|
26
|
rlm@73
|
27 I also want to be able to visualize both the sensors and the
|
rlm@73
|
28 effectors in pretty pictures. This semi-retarted creature will by my
|
rlm@73
|
29 first attempt at bringing everything together.
|
rlm@73
|
30
|
rlm@73
|
31 * The creature's body
|
rlm@73
|
32
|
rlm@73
|
33 Still going to do an eve-like body in blender, but due to problems
|
rlm@73
|
34 importing the joints, etc into jMonkeyEngine3, I',m going to do all
|
rlm@73
|
35 the connecting here in clojure code, using the names of the individual
|
rlm@73
|
36 components and trial and error. Later, I'll maybe make some sort of
|
rlm@73
|
37 creature-building modifications to blender that support whatever
|
rlm@73
|
38 discreitized senses I'm going to make.
|
rlm@73
|
39
|
rlm@73
|
40 #+name: body-1
|
rlm@73
|
41 #+begin_src clojure
|
rlm@73
|
42 (ns cortex.silly
|
rlm@73
|
43 "let's play!"
|
rlm@73
|
44 {:author "Robert McIntyre"})
|
rlm@73
|
45
|
rlm@73
|
46 ;; TODO remove this!
|
rlm@73
|
47 (require 'cortex.import)
|
rlm@73
|
48 (cortex.import/mega-import-jme3)
|
rlm@73
|
49 (use '(cortex world util body hearing touch vision))
|
rlm@73
|
50
|
rlm@73
|
51 (use '[clojure.contrib [seq :only [find-first]]])
|
rlm@73
|
52
|
rlm@73
|
53
|
rlm@73
|
54 (rlm.rlm-commands/help)
|
rlm@73
|
55
|
rlm@73
|
56 (defn load-blender-model
|
rlm@73
|
57 "Load a .blend file using an asset folder relative path."
|
rlm@73
|
58 [^String model]
|
rlm@73
|
59 (.loadModel
|
rlm@73
|
60 (doto (asset-manager)
|
rlm@73
|
61 (.registerLoader BlenderModelLoader (into-array String ["blend"])))
|
rlm@73
|
62 model))
|
rlm@73
|
63
|
rlm@74
|
64 (defn meta-data [blender-node key]
|
rlm@74
|
65 (if-let [data (.getUserData blender-node "properties")]
|
rlm@74
|
66 (.findValue data key)
|
rlm@74
|
67 nil))
|
rlm@73
|
68
|
rlm@74
|
69 (defn hand2 []
|
rlm@74
|
70 (load-blender-model "Models/creature1/try-again.blend"))
|
rlm@74
|
71
|
rlm@74
|
72 (defn hand []
|
rlm@74
|
73 (load-blender-model "Models/creature1/one.blend"))
|
rlm@74
|
74
|
rlm@74
|
75
|
rlm@73
|
76
|
rlm@74
|
77 (def hand-names
|
rlm@74
|
78 #{
|
rlm@74
|
79 "middle-1"
|
rlm@74
|
80 "middle-2"
|
rlm@74
|
81 "middle-3"
|
rlm@74
|
82 "palm"
|
rlm@74
|
83 "pinky-1"
|
rlm@74
|
84 "pinky-2"
|
rlm@74
|
85 "pinky-3"
|
rlm@74
|
86 "pointer-1"
|
rlm@74
|
87 "pointer-2"
|
rlm@74
|
88 "pointer-3"
|
rlm@74
|
89 "ring-1"
|
rlm@74
|
90 "ring-2"
|
rlm@74
|
91 "ring-3"
|
rlm@74
|
92 "thumb-1"
|
rlm@74
|
93 "thumb-2"})
|
rlm@74
|
94
|
rlm@74
|
95 (defn hand-pieces []
|
rlm@74
|
96 (filter
|
rlm@74
|
97 (comp hand-names #(apply str (drop-last (.getName %)))) (node-seq (hand))))
|
rlm@74
|
98
|
rlm@74
|
99 (defn hand-joints []
|
rlm@74
|
100 (map #(.getWorldTranslation %)
|
rlm@74
|
101 (filter #(re-matches #"joint\.\d\d\d" (.getName %))
|
rlm@74
|
102 (node-seq (hand)))))
|
rlm@74
|
103
|
rlm@74
|
104 (defn worm-pieces []
|
rlm@74
|
105 (filter
|
rlm@74
|
106 (comp #{"worm-2" "worm-1"}
|
rlm@74
|
107 #(apply str (drop-last (.getName %))))
|
rlm@74
|
108 (node-seq (hand2))))
|
rlm@74
|
109
|
rlm@74
|
110 (defn worm-joints []
|
rlm@74
|
111 [Vector3f/ZERO])
|
rlm@74
|
112
|
rlm@74
|
113
|
rlm@74
|
114
|
rlm@74
|
115 (defn find-joint
|
rlm@74
|
116 [#^Node parts #^Vector3f joint-position]
|
rlm@74
|
117 (loop [radius (float 0.01)]
|
rlm@74
|
118 (let [results (CollisionResults.)]
|
rlm@74
|
119 (.collideWith
|
rlm@74
|
120 parts
|
rlm@74
|
121 (BoundingBox. joint-position radius radius radius)
|
rlm@74
|
122 results)
|
rlm@74
|
123 (let [targets
|
rlm@74
|
124 (distinct
|
rlm@74
|
125 (map #(.getGeometry %) results))]
|
rlm@74
|
126 (if (>= (count targets) 2)
|
rlm@74
|
127 (take 2 targets)
|
rlm@74
|
128 (recur (float (* radius 2))))))))
|
rlm@74
|
129
|
rlm@74
|
130
|
rlm@74
|
131
|
rlm@74
|
132 (defn connect-at-point
|
rlm@74
|
133 [obj-a obj-b point]
|
rlm@74
|
134 (let [center-a (.getWorldTranslation obj-a)
|
rlm@74
|
135 center-b (.getWorldTranslation obj-b)
|
rlm@74
|
136 pivot-a (.subtract point center-a)
|
rlm@74
|
137 pivot-b (.subtract point center-b)
|
rlm@74
|
138 ;; A side-effect of creating a joint registers
|
rlm@74
|
139 ;; it with both physics objects which in turn
|
rlm@74
|
140 ;; will register the joint with the physics system
|
rlm@74
|
141 ;; when the simulation is started.
|
rlm@74
|
142 joint (Point2PointJoint.
|
rlm@74
|
143 (.getControl obj-a RigidBodyControl)
|
rlm@74
|
144 (.getControl obj-b RigidBodyControl)
|
rlm@74
|
145 pivot-a
|
rlm@74
|
146 pivot-b)]
|
rlm@74
|
147 obj-a))
|
rlm@74
|
148
|
rlm@74
|
149
|
rlm@74
|
150 (defn physical-hand [#^Node pieces joints]
|
rlm@74
|
151 ;; Make each piece a physical entity in the simulation.
|
rlm@74
|
152 (dorun
|
rlm@74
|
153 (map
|
rlm@74
|
154 (fn [geom]
|
rlm@74
|
155 (let [physics-control
|
rlm@74
|
156 (RigidBodyControl.
|
rlm@74
|
157 (HullCollisionShape.
|
rlm@74
|
158 (.getMesh geom))
|
rlm@74
|
159 ;; TODO: fix this.
|
rlm@74
|
160 (float 1.0))]
|
rlm@74
|
161 (.addControl geom physics-control)))
|
rlm@74
|
162 (filter #(isa? (class %) Geometry )
|
rlm@74
|
163 (node-seq pieces))))
|
rlm@74
|
164 (dorun
|
rlm@74
|
165 (map
|
rlm@74
|
166 (fn [joint-position]
|
rlm@74
|
167 (let [[geom-a geom-b] (find-joint pieces joint-position)]
|
rlm@74
|
168 (connect-at-point geom-a geom-b joint-position)))
|
rlm@74
|
169 joints))
|
rlm@74
|
170 pieces)
|
rlm@74
|
171
|
rlm@74
|
172
|
rlm@74
|
173 (defn the-hand! [] (physical-hand (hand) (hand-joints)))
|
rlm@74
|
174
|
rlm@74
|
175
|
rlm@74
|
176 (defn test-hand []
|
rlm@74
|
177 (world
|
rlm@74
|
178 (nodify [(the-hand!)
|
rlm@75
|
179 (box 10 1 10 :position (Vector3f. 0 -10 0)
|
rlm@74
|
180 :color ColorRGBA/Gray
|
rlm@74
|
181 :mass 0)])
|
rlm@74
|
182 standard-debug-controls
|
rlm@75
|
183 enable-debug
|
rlm@75
|
184 (fn [_ _]
|
rlm@75
|
185 (Thread/sleep 100))))
|
rlm@74
|
186
|
rlm@74
|
187
|
rlm@74
|
188
|
rlm@74
|
189
|
rlm@74
|
190
|
rlm@73
|
191
|
rlm@73
|
192
|
rlm@73
|
193 #+end_src
|
rlm@73
|
194
|
rlm@75
|
195 #+results: body-1
|
rlm@75
|
196 : #'cortex.silly/test-hand
|
rlm@75
|
197
|
rlm@73
|
198
|
rlm@73
|
199
|
rlm@73
|
200 * COMMENT generate source
|
rlm@73
|
201 #+begin_src clojure :tangle ../src/cortex/silly.clj
|
rlm@73
|
202 <<body-1>>
|
rlm@73
|
203 #+end_src
|
rlm@73
|
204
|