Agents assignment
From GeoMod
Contents |
Objective
Imagine you had to find your way across a map. You have a compass so you know what direction you want to go in (target_dir) but you can only see the topography of the area around you (local_topo). How would you choose what direction to go to get to your target?
Rules
The steeper the gradient in the direction that you try to move the slower you will move. (except if the slope is downhill, in which case you will move faster)
Requirements
Create a car class that renders an automobile and moves it to a target given the local topography and the known direction of the objective.
Each car class must have 1) A vehicle (it may be best to have the parts of the vehicle held together in a frame)
2) A function called move to move the car from its current position to a new position eg:
def move(self, new_pos):
self.racer.pos = new_pos
3) A function called chose_direction that decides which direction the car will move
- This function must take 2 variables
- local_topo is a 3x3 array of topogarphy data of the area around the car
- target_dir is a vector with the direction of the target relative to the car
eg: vector(1,0,0) is the x direction (East) vector(0,0,-1) is the negative z direction (North) vector(1,0,-1) is 45 degrees east of due north
- The function must return one variable, a vector that indicates what direction the car should move in. eg:
def chose_direction(self, local_topo, target_dir):
'''local_topo is a 3x3 array of topogarphy data of the area around the car
target_dir is a vector with the direction of the target relative to the car
eg: vector(1,0,0) is the x direction (East)
vector(0,0,-1) is the negative z direction (North)
vector(1,0,-1) is 45 degrees east of due north
RETURNS a vector indicating which direction you want your car to go'''
direction_choice = target_dir
return direction_choice
This example simply picks the direction that is the same as the direction of the target.
Example car
An example of a complete class (based on Dan Neilans' DragRacer is:
from visual import *
class DragRacer:
def __init__(self, pos, scale=1):
self.pos = pos #REQUIRED
self.scale = scale #REQUIRED
self.name = "prototype" #REQUIRED
self.racer = frame(pos=pos)
self.wheel_bl = sphere(frame=self.racer, pos = (-1*scale,1.5*scale,-1*scale), color = color.black, radius = 2*scale)
self.wheel_br = sphere(frame=self.racer, pos = (-1*scale,1.5*scale,1*scale), color = color.black, radius = 2*scale)
self.wheel_fl = sphere(frame=self.racer, pos = (8*scale,1*scale,-1*scale), color = color.black, radius = .5*scale)
self.wheel_fr = sphere(frame=self.racer, pos = (8*scale,1*scale,1*scale), color = color.black, radius = .5*scale)
self.chasiscage = box(frame=self.racer, pos = (-1*scale,2*scale,0*scale), height = 3*scale, width = 3*scale, length = 2*scale, color = color.red)
self.chasisframe = box(frame=self.racer, pos = (4*scale,1*scale,0), height = .5*scale, width = 1*scale, length = 9*scale, color = color.red)
#self.chasisframe = box(frame=self.racer, pos = (4,1,0), height = 500, width = 1000, length = 900, color = color.red)
#self.road = box(length = 300, width = 30, height = .1, color = color.blue)
def carmov(self, engine): # To move the car
while 1:
rate(20)
self.racer.pos.x = (self.racer.pos.x + 1) * engine
def move(self, new_pos): #REQUIRED
self.pos = new_pos #REQUIRED
self.racer.pos = new_pos #REQUIRED
def choose_direction(self, local_topo, target_x, target_y, target_dir, dx, max_slope=1): #REQUIRED
'''local_topo is a 3x3 array of topogarphy data of the area around the car
target_dir is a vector with the direction of the target relative to the car
eg: vector(1,0,0) is the x direction (East)
vector(0,0,-1) is the negative z direction (North)
vector(1,0,-1) is 45 degrees east of due north
dx is the cell spacing between cells in the 3x3 array
max_slope is the maximum slope that your car can traverse
RETURNS a vector indicating which direction you want your car to go'''
direction_choice = target_dir
return direction_choice
- Note the lines marked "REQUIRED". They are required in all versions of the class
The main program
This is the program that will run all the cars, except that the retardation factor for slope may be changed in the future.
You need to change the from basic_car import * line to the name of the file with your car class (in this case the file name is "basic_car.py"), and the cars.append(DragRacer(st_pos, 200)) line to change "DragRacer" to the name of your class.
from visual import *
from raster_import import *
#import all agents
#from basic_car import *
from saucer2 import *
#import topography
topog = raster_map("rastert_asciito1.txt")
topog.line_3d(50, 250, 50,250, 50.0, 1)
topog.draw_boundary()
#define target position
target = box(color=color.red,pos=scene.center+vector(0,0,topog.scale*topog.get_val(scene.center)),
width=5000, height=500, length=500)
print target.pos
#create cars and give them their initial position
cars = []
st_pos = scene.center+vector(-25000,-20000,topog.scale*topog.get_val(scene.center))
st_pos.z = topog.get_val(st_pos)*topog.scale
cars.append(saucer(st_pos, 200))
print "dragracer", cars[-1].pos
#create trails for cars.
trails = []
for i in cars:
trails.append(curve())
trails[-1].append(pos=i.pos)
l_end = 0
dt = 100
n_done = 0
#for slope retardation
max_slope = 0.02 * 50.0
rate(0.5)
while l_end <> 1:
#give agents information
#print "target.pos=", target.pos, topog.get_rc(target.pos), topog.get_val(target.pos)
#print "proto.pos= ", proto.racer.pos, topog.get_rc(proto.racer.pos), topog.get_val(proto.racer.pos)
for n,i in enumerate(cars):
# first find local 3x3 matrix
local_matrix = topog.local_3x3(i.pos)
new_dir = norm(i.choose_direction(local_matrix, target.x, target.y, norm(target.pos-i.pos), topog.dx, max_slope))
#move agents based on direction choice
# find potential new position (pnp) and potential new elevation (pnelev)
pnp = i.pos + (new_dir*topog.dx)
pnelev = topog.get_val(pnp)
slope = (pnelev - i.pos.z/topog.scale)/(topog.dx/topog.scale)
#the retardation factor (ret_fac) is
if (slope <= max_slope):
ret_fac = (max_slope - slope) / max_slope
#print i.pos.z/topog.scale, pnelev, topog.dx, slope
#dmove = mag(new_dir*dt*ret_fac)
#print slope, dmove
else:
ret_fac = 0.0
new_pos = i.pos + (new_dir*dt*ret_fac)
new_pos = vector(new_pos.x,new_pos.y,topog.scale*topog.get_val(new_pos))
i.move(new_pos)
trails[n].append(pos=new_pos)
#end simulation when someone reaches the target
#print i.pos, target.pos, abs(mag(i.pos - target.pos))
if (mag(i.pos - target.pos) < 200.0):
n_done = n_done + 1
print i.name, " has landed with rank", n_done
if n_done == len(cars):
l_end = 1
break
scene.center = cars[-1].pos
rate(5)
The additional files needed are the
- The module to import raster files. The latest version of this can be found at raster_import.py
- A raster file, the above program uses Media:Rastert_asciito1.txt
Results
- Day 1 champion: starting from (-20000,25000) max_slope=0.02
- Owner: Brad Sperry
- Driver: ??
- Vehicle name: Jeep
- Vehicle type: SUV
- The winning code
- Comments:
- "I'm just glad he did not spike the monitor"

