Beispiel #1
0
    def get_torque(self):
        # Get angle to rotate
        ang_to_rot = vector2angle(self.get_rel_position(self.taget_entity_id)) -\
                                                self.get_heading(self.entity_id)
        # Estimate torque
        torque = - P * ang_to_rot

        #Return the torque
        return self.check_torque(torque)
Beispiel #2
0
    def get_torque(self):
        # Get angle to rotate
        ang_to_rot = vector2angle(self.get_rel_position(self.taget_entity_id)) -\
                                                self.get_heading(self.entity_id)
        # Estimate torque
        torque = - P * ang_to_rot

        #Return the torque
        return self.check_torque(torque)
               
Beispiel #3
0
    def __init__(self, event_handler, world, screen, mouse, spinner, keyboard):
        self.event_handler = event_handler
        self.world = world
        self.screen = screen
        self.mouse = mouse
        self.spinner = spinner
        self.keyboard = keyboard

        self.steering_entities = []
        self.entity_list = []

        # SVG Parser
        self.SVGdata = SVGParser()
        player_file = os.path.join(filepath, 'GameData', 'Player_demo.svg')
        parse(player_file, self.SVGdata)

        # View realted information
        avatar = os.path.join(filepath, 'GameData',
                              self.SVGdata.view["avatar"])
        fwdvector = self.SVGdata.view["fwd_dir"]
        #####

        # Model Related information
        # Physical properties
        mass = self.SVGdata.model["mass"][0]
        masunits = self.SVGdata.model["mass"][1]
        #####

        # Kinematical information
        # Initial velocity
        # TODO: Comes from SVG. Where (Intelligence?)??
        v = (50.0, 0)

        # Initial position
        # TODO: Comes from SVG, Map
        p = (300, 300)

        # Initial angle
        # TODO: Comes from SVG, Where (Intelligence?)??
        # Rotate the unit such that tangential velocity an dforward vetor match
        angle = vector2angle(fwdvector, v)

        # Initial angular speed
        # TODO: Comes from SVG, Where (Intelligence?)??
        angspeed = 0.0

        #####

        # Add circling entity

        # This comes from the Scale of the Game.
        # TODO: Comes form SVG, Map (??)
        scale = 0.6

        self.entity_list.append(
            self.world.add_entity(position=p,
                                  velocity=v,
                                  ang=0.0,
                                  angspeed=angspeed,
                                  mass=mass))
        self.screen.add_entity(self.entity_list[0],
                               trace=False,
                               image=avatar,
                               angle=angle,
                               size=scale)

        f = 20.0
        # Angular velocity to match spin with orbit
        w = f / (mass * sqrt(dot(v, v)))
        self.world.apply_relative_force(self.entity_list[0], pi / 2, f)
        self.world.set_angspeed(self.entity_list[0], w)

        #Left click ends app
        event_handler.bind(self.on_mouse_left_up, mouse.MOUSE_BTN3_UP)

        # Space pauses
        event_handler.bind(self.on_pause,
                           keyboard.register_event_type('Space', 'UP'))
        # Debug information
        event_handler.bind(self.on_toggle_id,
                           keyboard.register_event_type('i', 'UP'))

        # Drag and Drop
        self.grabbed = None
        event_handler.bind(self.on_mouse_down, mouse.MOUSE_BTN1_DOWN)
        event_handler.bind(self.on_mouse_up, mouse.MOUSE_BTN1_UP)
        event_handler.bind(self.on_mouse_move, mouse.MOUSE_MOVE)

        for listener_obj in \
             [self.mouse, self.world, self.screen, self.keyboard]:
            event_handler.bind(listener_obj.on_update, self.spinner.TICK)
Beispiel #4
0
        
    def precalculate(self, ent_id):
        '''
        Calculates averages for all entities in sensor range of the given entity.
        DO NOT CALL DIRECTLY
        '''
        radius, aperture=self.sensors[ent_id]
        
        position=self.entities[ent_id].position
        in_range=set()   
        to_average=list()   
        angle=self.entities[ent_id].ang
        lower_angle=-aperture
        higher_angle=aperture
        sin_ang=sin(angle)
        cos_ang=cos(angle)

        for ent in self.entities:
            if ent.id==ent_id:
                continue
            rel_position=ent.position-position
            dx=rel_position[0]
            dy=rel_position[1]
                
            #Skip if entity is outside a box that contains the circle of radius radius
            if dx>radius or dx<-radius or dy>radius or dy<-radius:
                continue
                
            #Skip if outside the circle of radius radius                
            distance2=dx*dx+dy*dy
            if distance2>radius*radius:
                continue
            
            # Rotate the relative position vector to have 0 angle at entity direction          
            rot_rel_pos=array((rel_position[0]*cos_ang+rel_position[1]*sin_ang, \
                              -rel_position[0]*sin_ang +rel_position[1]*cos_ang ))
                
            # If unit is in sensor area add to do avergae
            rot_rel_ang=vector2angle(rot_rel_pos)
            if lower_angle<=rot_rel_ang<=higher_angle:
                    
                to_average.append(concatenate(\
              (ent.position, array((cos(ent.ang), sin(ent.ang))),ent.velocity)))
              
                in_range.add(ent.id)
        
        # Perform the averaging    
        try:
            average=reduce(add, to_average,0)*1.0/len(to_average)
        except ZeroDivisionError:
            average=array([0.0, 0.0, cos_ang, sin_ang, cos_ang, sin_ang])
     
        self._centroid[ent_id]=average[0:2]
        heading=average[2:4]
        heading=heading/sqrt(dot(heading, heading))
        self._heading[ent_id]=heading
        direction=average[4:6]
        try:
            direction=direction/sqrt(dot(direction, direction))
        except FloatingPointError:
            pass
        self._direction[ent_id]=direction
Beispiel #5
0
    def __init__(self, event_handler, world, screen, mouse, spinner, keyboard):
        self.event_handler=event_handler
        self.world=world
        self.screen=screen
        self.mouse=mouse
        self.spinner=spinner
        self.keyboard=keyboard
        
        self.steering_entities=[]
        self.entity_list=[]
        
        # SVG Parser
        self.SVGdata=SVGParser()
        player_file=os.path.join(filepath,'GameData','Player_demo.svg')
        parse(player_file,self.SVGdata)

        # View realted information
        avatar=os.path.join(filepath,'GameData',self.SVGdata.view["avatar"])
        fwdvector=self.SVGdata.view["fwd_dir"]
        #####
        
        # Model Related information
        # Physical properties
        mass=self.SVGdata.model["mass"][0]
        masunits=self.SVGdata.model["mass"][1] 
        #####

        # Kinematical information
        # Initial velocity
        # TODO: Comes from SVG. Where (Intelligence?)??
        v=(50.0,0)
        
        # Initial position
        # TODO: Comes from SVG, Map
        p=(300,300)

        # Initial angle
        # TODO: Comes from SVG, Where (Intelligence?)??
        # Rotate the unit such that tangential velocity an dforward vetor match
        angle = vector2angle(fwdvector,v)
        
        # Initial angular speed
        # TODO: Comes from SVG, Where (Intelligence?)??
        angspeed=0.0
        
        #####

        # Add circling entity
        
        
        # This comes from the Scale of the Game.
        # TODO: Comes form SVG, Map (??)
        scale=0.6        

        self.entity_list.append(self.world.add_entity(position=p,
                                                      velocity=v,
                                                      ang=0.0,
                                                      angspeed=angspeed,
                                                      mass=mass))
        self.screen.add_entity(self.entity_list[0],trace=False,
                                              image=avatar,
                                              angle=angle,size=scale)
                                              
        f=20.0
        # Angular velocity to match spin with orbit
        w=f/(mass*sqrt(dot(v,v)))
        self.world.apply_relative_force(self.entity_list[0], pi/2, f)
        self.world.set_angspeed(self.entity_list[0], w)       
        
        
        #Left click ends app
        event_handler.bind(self.on_mouse_left_up, mouse.MOUSE_BTN3_UP)

        # Space pauses
        event_handler.bind(self.on_pause, 
                                    keyboard.register_event_type('Space', 'UP'))
        # Debug information
        event_handler.bind(self.on_toggle_id, 
                                 keyboard.register_event_type('i', 'UP'))

        # Drag and Drop
        self.grabbed=None
        event_handler.bind(self.on_mouse_down, mouse.MOUSE_BTN1_DOWN)
        event_handler.bind(self.on_mouse_up, mouse.MOUSE_BTN1_UP)
        event_handler.bind(self.on_mouse_move, mouse.MOUSE_MOVE)
                                
        for listener_obj in \
             [self.mouse, self.world, self.screen, self.keyboard]:
            event_handler.bind(listener_obj.on_update, self.spinner.TICK)
Beispiel #6
0
            
        def ERM_step(ent):
            '''
                Euler-Richardson Method step
                "Numerical integration of Newton's equations including velocity
                dependent forces". 
                Ian R. Gatland. Am. J. Phys., Vol. 62, No. 3, March 1994
            '''
            # There are three frames of reference:
            #       Global: 
            #               X axis horizontal pointing right,
            #               Y axis vertical  pointing down
            #       LocalVel (or LocalCourse):
            #               X axis parallel to velocity,
            #               Y axis perpendicular to velocity
            #       LocalHeading:
            #               X axis parallel to the direction the unit is
            #                pointing,
            #               Y axis perpendicular to that (defines the left of 
            #               the entity)
            #       We could define a transfrom in the model too using what is
            #       in real2pix.py
            
            # WARNING: The follwoing computation assumes relatives forces are
            # ginven in LocalCourse frame            
            ang = vector2angle(ent.velocity)
            R = rotv(array((0,0,1)), ang)[0:2,0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)                

            # Update the total force                    
            force = (ent.total_force + rel2global_f) - DAMPING*ent.velocity
            
            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity 
            #       is missing in the damping factor
            torque = ent.total_torque - DAMPING*ent.angspeed
            
            # Update vel(t+1/2) and position pos(t+1/2)
            v_2 = ent.velocity + force*dt_2/ent.mass
            
            
            w_2 = ent.angspeed + torque*dt_2/ent.inertia_moment
            
            # Commented out. Used when forces depend on position and angle explicitly. Not programmed yet.
            # p_2 = ent.position + v_2*dt_2
            # a_2 = ent.ang + w_2*dt_2
                
            # Update forces
#            ang = ent.ang = vector2angle(v_2)
            ang = vector2angle(v_2)
            R = rotv(array((0,0,1)), ang)[0:2,0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)
            force = (ent.total_force + rel2global_f) - DAMPING*v_2
            
            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity 
            #       is missing in the damping factor
            torque = ent.total_torque - DAMPING*w_2
                
            # Update vel(t+1)
            ent.velocity = ent.velocity + force*dt_sec/ent.mass
            ent.angspeed = ent.angspeed + torque*dt_sec/ent.inertia_moment
            
            ent.position = ent.position + v_2*dt_sec
Beispiel #7
0
        
        def verletV_step(ent):
            '''
                Perform one step of the verlet velocity algorithm
                Not vectorized
            '''
            # Put the forces given in the entity frame into the global frame
            # TODO: Put this in a function. Soon the entties wont be points 
            #       anymore and more projections/rotations will be needed.
            # There are three frames of reference:
            #       Global: 
            #               X axis horizontal pointing right,
            #               Y axis vertical  pointing down
            #       LocalVel (or LocalCourse):
            #               X axis parallel to velocity,
            #               Y axis perpendicular to velocity
            #       LocalHeading:
            #               X axis parallel to the direction the unit is
            #                pointing,
            #               Y axis perpendicular to that (defines the left of 
            #               the entity)
            #       We could define a transfrom in the model too using what is
            #       in real2pix.py

            # WARNING: The follwoing computation assumes relatives forces are
            # ginven in LocalCourse frame            
            ang = vector2angle(ent.velocity)
            R = rotv(array((0,0,1)), ang)[0:2,0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)                

            # Update the total force                    
            force = (ent.total_force + rel2global_f) - DAMPING*ent.velocity
            
            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity 
            #       is missing in the dmaping factor
            torque = ent.total_torque - DAMPING*ent.angspeed
            
            # Update vel(t+1/2) and position pos(t+1)
            v_2 = ent.velocity + force*dt_2/ent.mass
            ent.position = ent.position + v_2*dt_sec
            
            w_2 = ent.angspeed + torque*dt_2/ent.inertia_moment

            ent.ang = ent.ang + w_2*dt_sec
                
            # Update forces
            #ang = ent.ang = vector2angle(v_2)
            ang = vector2angle(v_2)
            R = rotv(array((0,0,1)), ang)[0:2,0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)
            force = (ent.total_force + rel2global_f) - DAMPING*v_2
            
            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity 
            #       is missing in the dmaping factor
            torque = ent.total_torque - DAMPING*w_2
                
            # Update vel(t+1)
            ent.velocity = v_2 + force*dt_2/ent.mass
            
Beispiel #8
0
    def precalculate(self, ent_id):
        '''
        Calculates averages for all entities in sensor range of the given entity.
        DO NOT CALL DIRECTLY
        '''
        radius, aperture = self.sensors[ent_id]

        position = self.entities[ent_id].position
        in_range = set()
        to_average = list()
        angle = self.entities[ent_id].ang
        lower_angle = -aperture
        higher_angle = aperture
        sin_ang = sin(angle)
        cos_ang = cos(angle)

        for ent in self.entities:
            if ent.id == ent_id:
                continue
            rel_position = ent.position - position
            dx = rel_position[0]
            dy = rel_position[1]

            #Skip if entity is outside a box that contains the circle of radius radius
            if dx > radius or dx < -radius or dy > radius or dy < -radius:
                continue

            #Skip if outside the circle of radius radius
            distance2 = dx * dx + dy * dy
            if distance2 > radius * radius:
                continue

            # Rotate the relative position vector to have 0 angle at entity direction
            rot_rel_pos=array((rel_position[0]*cos_ang+rel_position[1]*sin_ang, \
                              -rel_position[0]*sin_ang +rel_position[1]*cos_ang ))

            # If unit is in sensor area add to do avergae
            rot_rel_ang = vector2angle(rot_rel_pos)
            if lower_angle <= rot_rel_ang <= higher_angle:

                to_average.append(concatenate(\
              (ent.position, array((cos(ent.ang), sin(ent.ang))),ent.velocity)))

                in_range.add(ent.id)

        # Perform the averaging
        try:
            average = reduce(add, to_average, 0) * 1.0 / len(to_average)
        except ZeroDivisionError:
            average = array([0.0, 0.0, cos_ang, sin_ang, cos_ang, sin_ang])

        self._centroid[ent_id] = average[0:2]
        heading = average[2:4]
        heading = heading / sqrt(dot(heading, heading))
        self._heading[ent_id] = heading
        direction = average[4:6]
        try:
            direction = direction / sqrt(dot(direction, direction))
        except FloatingPointError:
            pass
        self._direction[ent_id] = direction
        self._neighbours[ent_id] = in_range
Beispiel #9
0
        def ERM_step(ent):
            '''
                Euler-Richardson Method step
                "Numerical integration of Newton's equations including velocity
                dependent forces". 
                Ian R. Gatland. Am. J. Phys., Vol. 62, No. 3, March 1994
            '''
            # There are three frames of reference:
            #       Global:
            #               X axis horizontal pointing right,
            #               Y axis vertical  pointing down
            #       LocalVel (or LocalCourse):
            #               X axis parallel to velocity,
            #               Y axis perpendicular to velocity
            #       LocalHeading:
            #               X axis parallel to the direction the unit is
            #                pointing,
            #               Y axis perpendicular to that (defines the left of
            #               the entity)
            #       We could define a transfrom in the model too using what is
            #       in real2pix.py

            # WARNING: The follwoing computation assumes relatives forces are
            # ginven in LocalCourse frame
            ang = vector2angle(ent.velocity)
            R = rotv(array((0, 0, 1)), ang)[0:2, 0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)

            # Update the total force
            force = (ent.total_force + rel2global_f) - DAMPING * ent.velocity

            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity
            #       is missing in the damping factor
            torque = ent.total_torque - DAMPING * ent.angspeed

            # Update vel(t+1/2) and position pos(t+1/2)
            v_2 = ent.velocity + force * dt_2 / ent.mass

            w_2 = ent.angspeed + torque * dt_2 / ent.inertia_moment

            # Commented out. Used when forces depend on position and angle explicitly. Not programmed yet.
            # p_2 = ent.position + v_2*dt_2
            # a_2 = ent.ang + w_2*dt_2

            # Update forces
            #            ang = ent.ang = vector2angle(v_2)
            ang = vector2angle(v_2)
            R = rotv(array((0, 0, 1)), ang)[0:2, 0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)
            force = (ent.total_force + rel2global_f) - DAMPING * v_2

            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity
            #       is missing in the damping factor
            torque = ent.total_torque - DAMPING * w_2

            # Update vel(t+1)
            ent.velocity = ent.velocity + force * dt_sec / ent.mass
            ent.angspeed = ent.angspeed + torque * dt_sec / ent.inertia_moment

            ent.position = ent.position + v_2 * dt_sec
            ent.ang = ent.ang + w_2 * dt_sec
Beispiel #10
0
        def verletV_step(ent):
            '''
                Perform one step of the verlet velocity algorithm
                Not vectorized
            '''
            # Put the forces given in the entity frame into the global frame
            # TODO: Put this in a function. Soon the entties wont be points
            #       anymore and more projections/rotations will be needed.
            # There are three frames of reference:
            #       Global:
            #               X axis horizontal pointing right,
            #               Y axis vertical  pointing down
            #       LocalVel (or LocalCourse):
            #               X axis parallel to velocity,
            #               Y axis perpendicular to velocity
            #       LocalHeading:
            #               X axis parallel to the direction the unit is
            #                pointing,
            #               Y axis perpendicular to that (defines the left of
            #               the entity)
            #       We could define a transfrom in the model too using what is
            #       in real2pix.py

            # WARNING: The follwoing computation assumes relatives forces are
            # ginven in LocalCourse frame
            ang = vector2angle(ent.velocity)
            R = rotv(array((0, 0, 1)), ang)[0:2, 0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)

            # Update the total force
            force = (ent.total_force + rel2global_f) - DAMPING * ent.velocity

            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity
            #       is missing in the dmaping factor
            torque = ent.total_torque - DAMPING * ent.angspeed

            # Update vel(t+1/2) and position pos(t+1)
            v_2 = ent.velocity + force * dt_2 / ent.mass
            ent.position = ent.position + v_2 * dt_sec

            w_2 = ent.angspeed + torque * dt_2 / ent.inertia_moment

            ent.ang = ent.ang + w_2 * dt_sec

            # Update forces
            #ang = ent.ang = vector2angle(v_2)
            ang = vector2angle(v_2)
            R = rotv(array((0, 0, 1)), ang)[0:2, 0:2]
            rel2global_f = np.dot(R, ent.total_relative_force)
            force = (ent.total_force + rel2global_f) - DAMPING * v_2

            # Update total torque
            # TODO: A factor accounting for the effective radius of the entity
            #       is missing in the dmaping factor
            torque = ent.total_torque - DAMPING * w_2

            # Update vel(t+1)
            ent.velocity = v_2 + force * dt_2 / ent.mass

            ent.angspeed = w_2 + torque * dt_2 / ent.inertia_moment