Esempio n. 1
0
class Fsh:
    def __init__(self,pos,bounds,imgr,imgl):
        self.bounds = bounds
        self.max_vel = 75
        self.imgr = imgr 
        self.imgl = imgl
        self.size = 25
        self.per = self.size*3
        self.pos = pos
        angle = random.random()*math.pi*2
        self.vel = Vector(math.cos(angle),math.sin(angle)) * 20
    def draw(self,canvas):
        #canvas.draw_circle(self.pos.get_p(),4,1,"red","red")
        
        a = self.vel.angle(Vector(0,1))
        if self.vel.x > 0: 
            a *= -1 
            img = self.imgr
            a += math.pi/2
        else:
            a -= math.pi/2
            img = self.imgl
        
        img.pos = self.pos
        img.draw(canvas,rotation=a)
        #canvas.draw_line(self.pos.get_p(),(self.pos+self.vel).get_p(),2,"blue")
        #canvas.draw_circle(self.pos.get_p(),self.size,1,"black")
    def allign(self,fish):
        if len(fish) < 1:
            return
        # calculate the average velocities of the other boids
        avg = Vector()
        count = 0
        for boid in fish:
            if(boid.pos - self.pos).length()<self.per:
                count+=1
                avg += boid.vel
        
        if count>0:
            avg = avg.divide(count)		
            # set our velocity towards the others
            return (avg).normalize()
        else:
            return Vector()
    def cohesion(self,fish):
        if len(fish) < 1:
            return

        # calculate the average distances from the other boids
        com = Vector()
        count = 0
        for boid in fish:
            if boid.pos == self.pos:
                continue
            elif (boid.pos - self.pos).length()<self.per:
                com += (self.pos - boid.pos)
                count+=1
        if count>0:
            com = com.divide(count)
            return -com.normalize()
        else:
            return Vector()
    def seperation(self,fish, minDistance):
        if len(fish) < 1:
            return Vector()

        distance = 0
        numClose = 0
        distsum = Vector()
        for boid in fish:
            distance = (self.pos-boid.pos).length()
            if  distance < minDistance and distance != 0:
                numClose += 1
                distsum += (boid.pos-self.pos).divide(distance**2)

        if numClose == 0:
            return Vector()

        return  (-distsum.divide(numClose)).normalize()
    def update(self,delta,fish):
        self.vel = self.vel.add(self.allign(fish).multiply(self.max_vel/50))
        self.vel = self.vel.add(self.cohesion(fish).multiply(self.max_vel/50))
        self.vel = self.vel.add(self.seperation(fish,self.per*3/5).multiply(self.max_vel/30))
        self.vel = self.vel.normalize().multiply(self.max_vel)
        self.vel.rotate((random.random()*2-1)*delta*20)
        self.pos = self.pos.add(self.vel * delta)
        self.pos = self.bounds.correct(self)
Esempio n. 2
0
def run_simulation(body, rocket, target_orbit):
   
    # Time
    t = 0.0

    # Our step size
    dt = 0.1


    time_list = []
    altitude_list = []
    phi_list = []
    drag_list = []
    thrust_list = []
    velocity_list = []
    mass_list = []

    start = time.time()
    
    rocket.throttle = 1.0

    # Let's run our simulation
    for i in range(75000):
        
        # gravity depends on altitude!
        A_gravity = body.accelleration(rocket.position)

        # Valid up to 2500,000 meters
        P0, density = body.air_pressure_and_density(rocket.position)

        # AUTO PILOT
        # really crude pitch control. Once above target_orbit. start pushing along the surface of the earth        

        # First find orientation of the rocket. We assume this is always
        # along the surface of the earth, which is the tangent of the 
        # position vector.
        orientation = Vector([-rocket.position[1], rocket.position[0],0])
        
        # In order to rotate the force vector 'upwards' a certain degree
        # we need to find the rotation axis. This is the vector orthogonal
        # to the position and the orientation.
        rotation_axis = rocket.position.cross( orientation ).normalize()

        # High tech auto pilot
        # Straight up first, then abruptly point force vector along the
        # surface of the earth at 200km up. Then when orbital velocity is
        # acchieved power down.
        delta = 1.0
        if rocket.position.magnitude > body.radius + 1e3:
            delta = 0.5
        if rocket.position.magnitude > body.radius + 200e3:
             delta = 0.1

        # should really test for velocity parallel with Earth.
        if rocket.velocity.magnitude > 8672.0:
            rocket.throttle = 0.0

        # Negative rotation means point the force vector out from earth
        # along the surface.
        orientation.rotate(  - delta * math.pi/2.0, rotation_axis )
        rocket.set_orientation(orientation.normalize())

        # Force from rocket thurst depends on altitude    
        F_rocket = rocket.thrust(P0)
        
        # Force from drag due to atmosphere
        F_drag = rocket.drag(density)

        # Force from Gravity
        F_gravity = A_gravity * rocket.mass()
        
        # Make sure our airframe can handle!
        F_rocket_mag = F_rocket.magnitude
        F_drag_mag = F_drag.magnitude
        F_gravity_mag = F_gravity.magnitude
        force_mag_list = [F_rocket_mag, F_drag_mag, F_gravity_mag]

        # if the drag magnitude becomes too big, the airframe will break.    
        maxForce = sum( force_mag_list )
        if ( maxForce > rocket.max_forces ):
            print("R.U.D. Rapid Unscheduled Dissambly, too much forces, your rocket broke up in mid flight, iteration {}".format(i))
            print("velocity={} altitude={}, max_force={}, force_list={} delta={}".format(rocket.velocity, rocket.position.magnitude, maxForce, force_mag_list, delta))
            break

        # Sum Forces: Weight, Rocket Thrust and Drag in 3 dimensions.
        Fs = F_rocket + F_drag + F_gravity
        dv = Fs * (dt / rocket.mass())
        
        # Time step!
        rocket.velocity += dv
        rocket.position += rocket.velocity * dt

        # did we make it back to terra firma?
        # hope we are going slow.
        if rocket.position.magnitude < body.radius - 1:
            print("Current Forces = {}".format(force_mag_list))
            if rocket.velocity.magnitude > 5:
                print("R.U.D. Rapid Unscheduled Dissambly, welcome home!")
            else:
                print("Level: Musk, Mars is next")
            break

        # debug print
        if i%5000==0:
            print("velocity={} pos={}, drag={} delta={}".format(rocket.velocity, rocket.position.magnitude, F_drag, delta))

        # step the rocket time ahead, this burns the fuel and potentially does stage sep.
        rocket.time_step(dt, t)
        
        # keep a list of maxForce and position so we can plot.
        time_list.append(t)    
        drag_list.append( ( F_drag_mag  ) / 1000.0 )
        thrust_list.append( (F_rocket_mag ) / 1000.0 )
        altitude_list.append((rocket.position.magnitude - body.radius ) / 1000.0)
        phi_list.append( 180.0 * rocket.position.phi / math.pi )
        velocity_list.append( rocket.velocity.magnitude )
        mass_list.append(rocket.mass())
        # next time step!
        t = t + dt

    print("Simulation ran for {} seconds".format(time.time()-start))

    return time_list, altitude_list, drag_list, velocity_list, phi_list, thrust_list, mass_list