#for hosing meta-layer expiriment @use PhysicalControl. @use Shape. @use Stationary. @use Link. @use MultiBody. @use NeuralNetwork5. @define BRAITENBERG_MAX_VELOCITY 3. @define DECAY 0.000025. @define ACCEL 5. @define ARM_ACCEL 0.1 . @define MAGNET_RANGE 4. @define KINDS 2. @define NCOUNT 50. @define NARMS 2. PhysicalControl : BraitenbergControl2 { % This class is used for building simple Braitenberg vehicle % simulations. To create a Braitenberg vehicle simulation, % subclass BraitenbergControl and use the init method to % create OBJECT(BraitenbergLight) and % OBJECT(BraitenbergVehicle) objects. + variables: floor (object). floorShape (object). cloudTexture (object). + to init: self enable-lighting. self enable-smooth-drawing. floorShape = new Shape. floorShape init-with-cube size (400, .2, 400). floor = new Stationary. floor register with-shape floorShape at-location (0, 0, 0). floor catch-shadows. self point-camera at (0, 0, 0) from (6, 6, 24). self enable-shadows. self enable-reflections. self enable-fast-physics. self set-fast-physics-iterations to 30. #40 is default cloudTexture = (new Image load from "images/clouds.png"). self set-background-color to (.4, .6, .9). self set-background-texture-image to cloudTexture. #super enable-outline. #super init. } MultiBody : BraitenbergVehicle2 (aka BraitenbergVehicles2) { % This object is used in conjunction with OBJECT(BraitenbergControl) to % create simple Braitenberg vehicles. + variables: bodyShape (object). wheelShape (object). sensorShape (object). armShape(object). lightShape(object). bodyLink (object). buildPointers (list). brain (object). Meta(int). wheels (list). sensors (list). lights(list). arms(list). type(int). kiddy(object). carried(list). carriedShape(list). carriedSize(list). resize(list). lifts(list). peakIn(double). peakOut(double). pubescent(int). voice (object). ear (object). #+ to destroy: #temp(object). #print"destroying braitenbergvehicle2". #free sensorShape. #free wheelShape. #free bodyShape. #free armShape. #free lightShape. #if kiddy: free kiddy. #if carried: free carried. #if bodyLink: free bodyLink. #if buildPointers: free buildPointers. #if brain: free brain. #foreach temp in wheels: free temp. #foreach temp in sensors: free temp. #foreach temp in lights: free temp. #foreach temp in arms: free temp. #print"destroying braitenbergvehicle2". #super destroy. #free super. #self free-all-connected-objects. #free self. + to init: super init. bodyShape = new Shape. bodyShape init-with-cube size (4.0, .75, 3.0). wheelShape = new Shape. wheelShape init-with-polygon-disk radius .6 sides 40 height .1. sensorShape = new Shape. sensorShape init-with-polygon-cone radius .2 sides 10 height .5. armShape = new Shape. armShape init-with-cube size (0.1, 1.0, 0.1). lightShape = new Shape. lightShape init-with-sphere radius 0.3. peakOut = 0. #self move to (0, 1.0, 0). #self set-texture-scale to 1.5. super enable-self-collisions. #self setup-collision-handlers. self disable-auto-free. # brain management + to init-and-start-brain of size(int) with-meta met(int) hose h(int): #if brain: free brain. Meta = met. brain = new NeuralNetwork4. brain init-with neuron-count size. #brain init-random-structure with-connectivity-percent 100.0 with-autapses 0. brain init-fully-connected-structure with-autapses 1. #self add-dependency on brain. brain randomize-weights between -1.0. if Meta:{ brain init-meta-with neuron-count size hose h. } if wheels:{ wheels set-brain to brain. } else { print " No wheels in init and start brain ". } if arms: arms set-brain to brain. if sensors: sensors set-brain to brain. if lights: lights set-brain to brain. return brain. + to start-brain of b(object): nully(object). #carried = nully. #kiddy = nully. #print " Starting new brain of $b ". #if brain: free brain. brain = b. #brain re-states. #print " Starting new brain2 of $brain ". if wheels: wheels set-brain to brain. if sensors:{ sensors set-brain to brain. #print " in start brain of manipulator sensors are $sensors ". } #if lights: lights set-brain to brain. if arms: arms set-brain to brain. #self setup-collision-handlers. #free(nully). return self. + to set-brain of b(object): #if brain: free brain. brain = b. + to get-brain: return brain. + section "Adding Wheels, Lights, Arms, Sensors to a Vehicle" + to add-body with seg(object) of-type t(int): leftWheel, rightWheel (object). fleftWheel, frightWheel (object). bleftSensor, brightSensor(object). leftSensor, rightSensor(object). aft, sns, i(int). print "adding body". aft = NCOUNT - NARMS. sns = 0. bodyLink = seg. #new Segment. #bodyLink set-shape to bodyShape. bodyLink set-mu to -1.0. bodyLink set-eT to .8. bodyLink set-color-integer to t. bodyLink set-density to 20.0. if t == 3:{ leftWheel = (self add-wheel at (-1.0, 0, -1.6)). fleftWheel = (self add-wheel at (1.0, 0, -1.6)). rightWheel = (self add-wheel at (-1.0, 0, 1.6)). frightWheel = (self add-wheel at (1.0, 0, 1.6)). leftWheel set-natural-velocity to 0.0 . rightWheel set-natural-velocity to 0.0 . fleftWheel set-natural-velocity to 0.0 . frightWheel set-natural-velocity to 0.0 . leftWheel set-start to aft. fleftWheel set-start to aft. aft -= 1. rightWheel set-start to aft. frightWheel set-start to aft. aft -= 1. # frightWheel set-last. rightSensor = (self add-sensor at (2.0, .4, 1.65) of-kind 1 with-normal (1, 0, 0)). leftSensor = (self add-sensor at (2.0, .4, -1.65) of-kind 1 with-normal (1, 0, 0)). leftSensor set-start to sns. sns += KINDS. rightSensor set-start to sns. sns += KINDS. #leftSensor set-bias to (15.0). ##rightSensor set-last. brightSensor = (self add-sensor at (-2.0, .4, 1.65) of-kind 1 with-normal (1, 0, 0)). bleftSensor = (self add-sensor at (-2.0, .4, -1.65) of-kind 1 with-normal (1, 0, 0)). bleftSensor set-start to sns. sns += KINDS. brightSensor set-start to sns. sns += KINDS. #bleftSensor set-bias to (15.0). bleftSensor set-direction to (0, -1, 0). brightSensor set-direction to (0, -1, 0). brightSensor set-last. pubescent = 1. } else :{ pubescent = 0. } self set-root to bodyLink. for i = 0, i < NARMS, i++:{ buildPointers{i} = bodyLink. } print "adding body 2". + to add-voice at location (vector): v, jnt (object). v = new BraitenbergVoice. jnt = new RevoluteJoint. v set-joint to jnt. jnt link parent bodyLink to-child v with-normal (0, 0, 1) with-parent-point location with-child-point (0, 0, 0). v set-eT to .8. v set-texture to 0. v set-joint to jnt. jnt set-strength-limit to (jnt get-strength-hard-limit). voice = v. return v. + to add-ear at location(vector): e, jnt (object). e = new BraitenbergEar. jnt = new RevoluteJoint. e set-joint to jnt. jnt link parent bodyLink to-child e with-normal (0, 0, 1) with-parent-point location with-child-point (0, 0, 0). e set-eT to .8. e set-texture to 0. e set-joint to jnt. jnt set-strength-limit to (jnt get-strength-hard-limit). ear = e. return e. + to add-wheel at location (vector): % Adds a wheel at location on the vehicle. This method returns % the wheel which is created, a OBJECT(BraitenbergWheel). You'll % use the returned object to connect it to the vehicle's sensors. wheel, jnt (object). wheel = new BraitenbergWheel2. wheel set-shape to wheelShape. jnt = new RevoluteJoint. wheel set-joint to jnt. wheel rotate around-axis (1,0,0) by 1.57 . jnt set-relative-rotation around-axis (1, 0, 0) by 1.57. jnt link parent bodyLink to-child wheel with-normal (0, 0, 1) with-parent-point location with-child-point (0, 0, 0). wheel set-eT to .8. wheel set-texture to 0. wheel set-joint to jnt. jnt set-strength-limit to (jnt get-strength-hard-limit). #jnt enable-automatic-joint-scaling. wheel set-color to (.6, .6, .6). wheel set-mu to 100000. #self add-dependency on jnt. #self add-dependency on wheel. push wheel onto wheels. #wheel enable-joint-scaling. return wheel. + to add-sensor at location (vector) of-kind t (int) with-normal norm (vector): % Adds a sensor at location on the vehicle. This method returns % the sensor which is created, a OBJECT(BraitenbergSensor). You'll % use the returned object to connect it to the vehicle's wheels. sensor, joint (object). sensor = new BraitenbergSensor2. #print "add sensor of manipulator just build sensor $sensor". sensor add-kind of t. sensor set-shape to sensorShape. sensor rotate around-axis (0,0,1) by 1.57 . joint = new RevoluteJoint. joint set-relative-rotation around-axis (0, 0, 1) by -1.57. joint link parent bodyLink to-child sensor with-normal norm with-parent-point location with-child-point (0, 0, 0). #joint enable-automatic-joint-scaling. joint set-joint-velocity to 5.0 . joint set-double-spring with-strength 300 with-max 0.01 with-min -0.01. #self add-dependency on joint. #self add-dependency on sensor. joint set-joint-velocity to 5.0 . sensor set-color to (0, 0, 0). sensor set-joint to joint. #sensor enable-joint-scaling. push sensor onto sensors. return sensor. + to add-kind-sensors of x(int): sensors add-kind of x. + to add-light at location (vector) of-kind t (int): light, jnt(object). light = new BraitenbergLight2. light set-shape to lightShape. light set-color-integer to t. self set-kind to t. jnt = new RevoluteJoint. jnt link parent bodyLink to-child light with-normal (1, 0, 0) with-parent-point location with-child-point (0, 0, 0). #jnt enable-automatic-joint-scaling. #self add-dependency on jnt. #self add-dependency on light. push light onto lights. + to add-new-arm: fake(object). buildPointers{|buildPointers|} = bodyLink. #carried{|carried|} = fake. + to add-arm-segment of seg (object) to-limb limb(int) at-parent-location location (vector) with-child-location childPoint (vector) with-normal norm (vector) with-rotation rot(vector): % Adds a wheel at location on the vehicle. This method returns % the wheel which is created, a OBJECT(BraitenbergWheel). You'll % use the returned object to connect it to the vehicle's sensors. jnt (object). jnt = new RevoluteJoint. #seg set-joint to jnt. #seg rotate around-axis (1,0,0) by 1.57 . jnt set-relative-rotation around-axis rot by 1.57. jnt link parent (buildPointers{limb}) to-child seg with-normal norm with-parent-point location with-child-point childPoint. seg set-joint to jnt. jnt set-strength-limit to (jnt get-strength-hard-limit). #jnt enable-automatic-joint-scaling. #jnt set-joint-limit-vectors min (0, 0, 1 ) max (0, 0, 2 ). #jnt set-joint-limits min 1.0 max -1.0. #self add-dependency on jnt. #self add-dependency on seg. print "in add arm segment the limb number is $limb". buildPointers{limb} = seg. #the statement below is too crude push seg onto arms. return seg. + to set-type to t(int): type = t. lights set-color-integer to t. + to set-all-kinds to t(int): tmp(object). type = t. if bodyLink: bodyLink set-color-integer to t. if lights: lights set-color-integer to t. foreach tmp in arms: tmp set-color-integer to t. foreach tmp in wheels: tmp set-color-integer to t. foreach tmp in sensors: tmp set-color-integer to t. #free(tmp). + to get-type: return type. + to set-all-parent: tmp(object). if bodyLink: bodyLink set-parent of self. if lights: lights set-parent of self. if voice: voice set-parent of self. if ear: ear set-parent of self. foreach tmp in arms: tmp set-parent of self. foreach tmp in wheels: tmp set-parent of self. foreach tmp in sensors: tmp set-parent of self. + to integrate-outboard-sensor obj sensr (object): push sensr onto sensors. + to control at-time t(float): tamp(object). element(object). elementSize(vector). s(list). vals(list). val(double). i(int). j(int). start(int). slide(int). #print"$brain". slide = 0. if (ear):{ slide = ( ear get-start ). val = ( ear get-word ). brain perturb-neuron-state at slide to val. #print "ear feeding to $slide X $val". } if (brain && sensors):{ foreach tamp in sensors:{ start = (tamp get-start). vals = (tamp get-strengths). for i = 0, i < |vals| , i++:{ val = (vals{i}) * 100. slide = start + i. #print "sensors feeding to $slide X $val". if start:{ # print "sensors feeding to $slide X $val". brain perturb-neuron-state at slide to val. } } } } slide += 1. foreach element in carried:{ if (element can-respond to "get-size"):{ elementSize = (element get-size). # print "carried $element size $elementSize slide $slide". val = (elementSize::x). brain perturb-neuron-state at slide++ to val. val = (elementSize::y). brain perturb-neuron-state at slide++ to val. val = (elementSize::z). brain perturb-neuron-state at slide++ to val. } } #print "check 2 $brain". brain update-state. if Meta:{ brain update-meta-state. } if voice:{ slide = (voice get-start). val = (brain get-neuron-state at slide). voice set-word to val. print "voice start $slide of val $val". } foreach tamp in arms:{ start = (tamp get-start). slide = start. #reuse in other direction val = (brain get-neuron-state at start). val = val * ARM_ACCEL. if (tamp can-respond to "activate"): tamp activate with-input val. if (|val| > peakOut): peakOut = |val|. print "$start outputarmX $val". } foreach tamp in wheels:{ start = (tamp get-start). val = (brain get-neuron-state at start). val = val * ACCEL. tamp activate with-input val. if (|val| > peakOut): peakOut = |val|. print "$start outputwheelX $val". } for i = 0, i < (NARMS), i++:{ val = (brain get-neuron-state at slide++). if (val >= 0):{ if arms && !pubescent:{ if arms{i}:{ self magnet-to-nearest arm i. } } lifts{i} = 1. } else:{ lifts{i} = 0. } } foreach element in carried:{ for i = 0, i < 3, i+=1:{ s{0}=1. s{1}=1. s{2}=1. val = (brain get-neuron-state at slide). if (val > 0):{ s{i} = 1.001. } else if (val < 0):{ s{i} = .99. } slide += 1. } if (element can-respond to "scale"):{ element scale by (s{0}, s{1}, s{2}). } } brain decay-by ratio DECAY. if Meta:{ brain decay-meta-by ratio DECAY. } + to magnet-to-nearest arm z(int): tip(object). top(object). seg(object). nearseg(object). pointA(vector). pointB(vector). diff(vector). dist(double). neardist(double). halfVector(vector). neardist = MAGNET_RANGE. #print " magnet of arm $z in list $arms ". tip = arms{((z) * 3) + 2}.#- - 1 |arms| pointA = tip get-tip-loc. top = tip get-tip. foreach seg in all Segment:{ if ((seg get-color-integer) == 1):{ pointB = seg get-location. diff = pointA - pointB. dist = |diff|. if dist < neardist:{ neardist = dist. nearseg = seg. halfVector = ( (diff / 2)). #pointB + # print "nearest dist $neardist". } } } if halfVector:{ #nearseg move to halfVector. nearseg set-velocity to (halfVector * .5 ). #tip set-velocity to (halfVector * -0.5). } + to center: currentLocation (vector). currentLocation = (self get-location). self move to ( 1 , (currentLocation::y), 1). + to get-arms: return arms. + to get-wheels: return wheels. + to get-sensors: return sensors. + to get-body: return bodyLink. + to set-child to kid(object): kiddy = kid. + to get-child: #kiddy child. return kiddy. + to set-carried index i(int) to car(object): temp(object). temp = new Object. while (|carried| <= i):{ push temp onto carried. push temp onto carriedShape. } carried{i} = car. temp = car get-shape. carriedShape{i} = temp. + to get-carried of n(int): return carried{n}. + to get-buildPointer for-limb limb(int): return (buildPointers{limb}). + to get-lifts at n(int): if |lifts| < n:{ return lifts{n}. } else { return 0. } + to get-number-buildPointers: return (|buildPointers|). + to set-buildPointer for-limb limb(int) to seg(object): buildPointers{limb} = seg. + to get-fitness: fitness(double). armlist(list). tmp(object). otmp(object). otmptype(string). i(int). dif(double). near(double). otmpvect(vector). # fitness = 0. near = 1000. if kiddy:{ fitness += 1000. #bonus armlist = (kiddy get-arms). tmp = (kiddy get-body). dif = |(tmp get-size) - (bodyLink get-size)|. fitness -= dif. otmp = (buildPointers{|buildPointers| - 1}). dif = |(tmp get-location) - (otmp get-location)|. fitness -= dif. for i=0, i < |armlist|, i++:{ fitness += 333. if (arms{i}):{ dif = (|((arms{i}) get-size) - ((armlist{i}) get-size)| * |((arms{i}) get-size) - ((armlist{i}) get-size)|). fitness -= dif. } } } else if carried:{ fitness += 1000. } else { foreach tmp in (all Segment):{ if ((tmp get-color-integer) == 1):{ otmp = (buildPointers{|buildPointers| - 1}). #print "other temp $otmp". otmpvect = (otmp get-location). dif = |otmpvect - (tmp get-location)|. #print "diff $dif". if dif < near:{ near = dif. #print "min diff $near". } } } fitness += (250 - near). #print "min diff $near". } return fitness. } Link : Segment (aka Segments) { + variables: cap(object). #the cap is what is connected to the tjoint when it isn't carrying tipjoint(object). #tipjoint is the joint for the cap joint(object). joints(list). #implement soon hull(object). brain(object). #pointer to brain start(int). #start of sensors input space or start of output vector space on brain last(int). #signify that it is the last segment to use the brain therefor should reset states color(int). size(vector). startPosition(vector). parent(object). tiploc (vector). #male connector point socketloc (vector). #female ... #+ to destroy: #if hull: free hull. #if joints: free joints. #if brain: free brain. #if tipjoint: free tipjoint. #if cap: free cap. #super destroy. #self free-all-connected-objects. #free self. + to init: # super init. #joint enable-automatic-joint-scaling. self disable-auto-free. self setup-collision-handlers. + to iterate: super iterate. + to set-density to den(float): hull set-density to den. + to return-to-start: self move to startPosition. + to set-start-position: startPosition = self get-location. + to set-brain to b(object): #if brain: free brain. #print "$self is setting brain to $b". brain = b. + to set-parent of rent(object): parent = rent. + to get-parent: return parent. + to set-start to d(int): start = d. + to get-start: return start. + to get-size: return size. + to get-shape: return hull. + to set-shape to s(object) of sz(vector): hull = s. size = sz. tiploc = (0, (size::y / 2), 0). socketloc = (0, - (size::y / 2), 0). super set-shape to s. + to scale by scale (vector): #size = size * scale. size = ((size::x * scale::x), (size::y * scale::y),(size::z * scale::z)). tiploc = (0, (size::y / 2), 0). socketloc = (0, - (size::y / 2), 0). hull scale by scale. + to set-joint to j(object): joint = j. #joint enable-automatic-joint-scaling. + to set-last: last = 1. + to get-point-on-shape on-vector theVector (vector): #This method is experimental. #Starting from inside the shape at the center, this function goes in the direction of theVector until it hits the edge of the shape. The resulting point is returned. #This allows you to compute link points for arbitrary shapes. For example, if you want to compute a link point for the "left-most" point on the shape, you can call this method with (-1, 0, 0). #Returns (0, 0, 0) if the shape is not initialized or if an error occurs. return (hull get-point-on-shape on-vector theVector). + to set-color-integer to col(int): color = col. if col == 0: self set-color to (1,0,0). #trial vehicle if col == 1: self set-color to (0,0,1). #segments if col == 2: self set-color to (0,0,0). #carried XxXxXx Deprecated if col == 3: self set-color to (0,1,0). #child if col == 4: self set-color to (1,1,1). # sensors if col == 5: self set-color to (.3, .3, .3). # wheels if col == 7: self set-color to (.6, .6, .6). # lights XXXX Note: create light signals as output + to get-color-integer: return color. + to add-tip at location (vector) of-kind t (int) with-normal norm (vector): lil(object). lil = (new Cube init-with size (.05,.05,.05)).#(.01, .01, .01)). cap = new Link. cap set-shape to lil. #cap draw-as-point. tipjoint = new RevoluteJoint. tipjoint link parent self to-child cap with-normal norm with-parent-point location with-child-point (0, 0, 0). #tipjoint enable-automatic-joint-scaling. + to get-tip-loc: return (cap get-location). + to get-tipjoint: return tipjoint. + to get-tip: return cap. + to enable-joint-scaling: if joint: joint enable-automatic-joint-scaling. + to lift a seg(object) at location (vector) with-normal norm(vector) and child-loc(vector): tipjoint link parent self to-child seg with-normal norm with-parent-point location with-child-point child-loc. + to add-sensor at location (vector) of-kind t (int) with-normal norm (vector): % Adds a sensor at location on the vehicle. This method returns % the sensor which is created, a OBJECT(BraitenbergSensor). You'll % use the returned object to connect it to the vehicle's wheels. sensor, jnt (object). sensorShape (object). sensorShape = new Shape. sensorShape init-with-polygon-cone radius .05 sides 10 height .12. sensor = new BraitenbergSensor2. sensor add-kind of t. sensor set-shape to sensorShape. #sensor rotate around-axis (1,0,0) by .7534. #1.57. jnt = new RevoluteJoint. jnt set-relative-rotation around-axis (0, 1, 0) by -1.57. jnt link parent self to-child sensor with-normal norm with-parent-point location with-child-point (0, 0, 0). jnt set-double-spring with-strength 300 with-max 0.01 with-min -0.01. #jnt enable-automatic-joint-scaling. jnt set-joint-velocity to 5.0 . #self add-dependency on jnt. #self add-dependency on sensor. sensor set-color to (0, 0, 0). return sensor. + to setup-collision-handlers: self handle-collisions with-type "Segment" with-method "affix". #self handle-collisions with-type "BraitenbergWheel2" with-method "affix". # Mobile: get-colliding-objects + to affix to seg(object): mul(object). #multibody of self get-parent colorB(int). colorA(int). tmp(object). car(object). jnt(object). shp(object). child(object). spot(vector). ospot(vector). osize(vector). tester(string). lft(int). i(int). j(int). colorA = (seg get-color-integer). #print "color $color other color $colorA". if (color == 0 ):{ #&& (self get-parent) mul = (self get-parent). j = ((mul get-number-buildPointers) - 1). colorA = (seg get-color-integer). if (colorA != 0):{ for i = 0, i < j, i++:{ tmp = (mul get-buildPointer for-limb{i}). # print "buildPointer for limb $i is $tmp and self is $self". if ((self == tmp) && ((mul get-lifts at i) == 1)):{ child = mul get-child. if !child:{ child = new BraitenbergVehicle2. child add-body with seg of-type 3. mul set-child to child. child set-all-kinds to 3. child set-all-parent. mul set-child to child. controller temp-driver-lock. # print "creating child $child". } else:{ mul set-carried index i to seg. # print "setting carried index $i to $seg". } } } } } if (color == 3):{ #print "collision of type $color with type $colorA ". mul = (self get-parent). if (mul && colorA != 0):{ j = ((mul get-number-buildPointers) - 1). #print "my parent $mul has $j buildPointers". for i = 0, i <= j, i++:{ print " i $i j $j ". tmp = (mul get-buildPointer for-limb i). #print "color 3 tmp is $tmp and self is $self". if (self == tmp):{ colorA = (seg get-color-integer). if (colorA == 1):{ print "hello". if i == 0:{ spot = (0, 1, -2). } else if i == 1:{ spot = (0, 1, 2). } spot = (self get-point-on-shape on-vector spot). ospot = (0, -1, 0). ospot = (seg get-point-on-shape on-vector ospot). mul add-arm-segment of seg to-limb i at-parent-location spot with-child-location ospot with-normal (0, 1, 0) with-rotation ( 0, 0, 0). #mul set-buildPointer for-limb i to seg. mul set-all-kinds to 3. mul set-all-parent. } } else:{ #mul add-new-arm. } mul set-all-parent. } } } if (color == 1):{ #print "collision of type $color with type $colorA ". mul = (seg get-parent). if (mul && colorA != 0):{ j = ((mul get-number-buildPointers) - 1). #print "segs parent $mul has $j buildPointers". for i = 0, i <= j, i++:{ #print " i $i j $j ". tmp = (mul get-buildPointer for-limb i). #print "color is 1 seg is $seg and tmp is $tmp". if (seg == tmp):{ colorA = (seg get-color-integer). if (colorA == 3 && color == 1):{ #print "hello2". if i == 0:{ spot = (0, 1, -2). } else if i == 1:{ spot = (0, 1, 2). } spot = (seg get-point-on-shape on-vector spot). ospot = (0, -1, 0). ospot = (self get-point-on-shape on-vector ospot). mul add-arm-segment of self to-limb i at-parent-location spot with-child-location ospot with-normal (0, 1, 0) with-rotation ( 0, 0, 0). #mul set-buildPointer for-limb i to self. mul set-all-kinds to 3. mul set-all-parent. self set-color-integer to 3. } } else:{ #mul add-new-arm. } mul set-all-parent. } } } } Segment : BraitenbergVoice (aka BraitenbergVoices) { % A BraitenbergVoice is used in conjunction with OBJECT(BraitenbergControl) % and OBJECT(BraitenbergVehicle). It is what the OBJECT(BraitenbergEar) % objects on the BraitenbergVehicle detect. %
% There are no special behaviors associated with the lights--they're % basically just plain OBJECT(Mobile) objects. #Note: use light signals as output from host manipulator to neighbors + variables: word(double). hull(object). + to init: #super init. hull = (new Sphere init-with-sphere radius .3). self set-shape to hull. #super set-color-integer to 0. # Until we change it's flavor. self disable-auto-free. + to get-word: if word > 1: word = 1. if word < 0: word = 0. return word. + to set-word to w(double): word = w. if word > 1: word = 1. if word < 0: word = 0. self set-color to (word, 0, 0). } Segment : BraitenbergEar (aka BraitenbergEars) { + variables: word(double). hull(object). + to init: hull = new Cube init-with size (.3, .3, .3). self set-shape to hull. + to get-word: voice(object). pos(vector). dist(double). near(double). focus(object). rent(object). word = 0. near = 100000. foreach voice in (all BraitenbergVoices):{ pos = (voice get-location). rent = (voice get-parent). dist = (|(self get-location) - pos|). if (dist < near) && (rent != (self get-parent)):{ near = dist. focus = voice. word = (focus get-word). } } if word > 1: word = 1. if word < 0: word = 0. if isnan(word): word = 0. if isinf(word): word = 1. self set-color to (word, 0, 0). return word. + to set-word to w(double): word = w. if word > 1: word = 1. if word < 0: word = 0. } #location = (self get-location). #location::z = 0. #self move to location. Segment : BraitenbergWheel2 (aka BraitenbergWheels2) { % A BraitenbergWheel is used in conjunction with OBJECT(BraitenbergVehicle) % to build Braitenberg vehicles. This class is typically not instantiated % manually, since OBJECT(BraitenbergVehicle) creates one for you when you % add a wheel to the vehicle. %
% NOTE: this class is included as part of the file "Braitenberg.tz". + variables: #joint (object). naturalVelocity (float). newVelocity, oldVelocity (float). + to init: super init. naturalVelocity = 0. newVelocity = 0. self disable-auto-free. #+ to destroy: #free joint. #super destroy. #self free-all-connected-objects. #free self. + section "Configuring the Wheel's Natural Velocity" + to set-natural-velocity to n (float): % Sets the "natural" velocity of this wheel. The natural velocity % is the speed at which the wheel turns in the absence of sensor % input. naturalVelocity = n. + to activate with-input n (float): % Used internally. newVelocity = n. + to reset-velocity: joint set-joint-velocity to 0. + to iterate: #if brain: newVelocity = (brain get-neuron-state at start). if newVelocity > BRAITENBERG_MAX_VELOCITY: newVelocity = BRAITENBERG_MAX_VELOCITY. if newVelocity < -BRAITENBERG_MAX_VELOCITY: newVelocity = -BRAITENBERG_MAX_VELOCITY. # this oldVelocity stuff is used to limit the deceleration so that if newVelocity == 0: { if joint: joint set-joint-velocity to oldVelocity. oldVelocity *= .95. } else { if joint: joint set-joint-velocity to newVelocity. oldVelocity = newVelocity. } newVelocity = naturalVelocity. #if last: brain re-states. } Segment : BraitenbergSensor2 (aka BraitenbergSensors2) { % A BraitenbergSensor is used in conjunction with OBJECT(BraitenbergVehicle) % to build Braitenberg vehicles. This class is typically not instantiated % manually, since OBJECT(BraitenbergVehicle) creates one for you when you % add a sensor to the vehicle. %
% NOTE: this class is included as part of the file "Braitenberg.tz". + variables: wheels (list). bias (float). direction (vector). sensorAngle (float). activationObject (object). activationMethod (string). kinds(list). strengths(list). cnt(int). #+ to destroy: #if activationObject: free activationObject. #super destroy. #self free-all-connected-objects. #free self. + to init: super init. bias = 1.0. direction = (0, 1, 0). sensorAngle = 1.0. self disable-auto-free. + section "Linking the Sensor to a Wheel" + to link to w (object): % Associates this sensor with wheel w. push w onto wheels. + section "Configuring the Sensor Values" + to add-kind of d (int): #print " adding kind of $d to $self ". push d onto kinds. push 1 onto strengths. #print " added to kind list $kinds and $strengths ". + to get-kinds: return kinds. + to get-strengths: temporary(list). temporary{0} = 0.0. #print " getting-strengths in $self of $strengths". if (strengths):{ return strengths. } else:{ #print "returning tempMMMMMMMMMMMMMMMM". return temporary. } + to re-states: w(int). if (strengths):{ for w = 0, w < |strengths|, w++:{ strengths{w} = 0.0 . } } + to set-direction to d(vector): direction = d. + to set-bias to d (float): % Sets the "bias" of this sensor. The default bias is 1, meaning % that the sensor has a positive influence on associated wheels % with strength 1. You can change this to any magnitude, positive % or negative. bias = d. + to set-sensor-angle to n (float): % Sets the angle in which this sensor can detect light. The default % value of 1.5 means that the sensor can see most of everything in % front of it. Setting the value to be any higher leads to general % wackiness, so I don't suggest it. sensorAngle = n. + to set-activation-method to m (string) in-object o (object): % This method specifies an activation method for the sensor. An % activation method is a method which takes as input the strength % read by the sensor, and as output returns the strength of the % signal which will travel on to the motor. %
% Your activation function should be defined as: %
% + to activation-function-name with-sensor-strength s (float): %%
% The default activation method is linear, but more complex vehicles % may require non-linear activation functions. % activationMethod = m. activationObject = o. + to iterate: i (object). lights (int). total, strength, angle (float). toLight, transDir (vector). n(int). #print " iterating sensor strengths $strengths". transDir = (self get-rotation) * direction. for n=0, n<|kinds|, n++:{ strengths{n}= 0.0. #print "cycling through kinds setting strengths $n". } for n=0, n<|kinds|, n++:{ foreach i in (all Segments): { if ((i get-color-integer) == (kinds{n}) ):{ toLight = (i get-location) - (self get-location). angle = angle(toLight, transDir). if angle < sensorAngle: { strength = | (self get-location) - (i get-location) |. strength = 1.0 / (strength * strength). if activationMethod && activationObject: { strength = (activationObject call-method named activationMethod with-arguments { strength }). } if strength > 10: strength = 10. total += strength. lights++. } } if lights != 0: total /= lights. total = 5 * total * bias. strengths{n} = strengths{n} + total. #print "activation of sensors of type $n to val $total". total = 0. } } #if lights != 0: total /= lights. #total = 50 * total * bias. #print " strengths in sensor iterate $strengths ". #for n = start, n < (|strengths| + start), n++:{ #if brain: brain set-neuron-state at n to strengths{n - start}. #strengths{n - start} = 0. #} }