예제 #1
0
# Add some pin joints to hold the circles in place.
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset)))
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset)))
# Ratchet every 90 degrees
c = pymunk.RatchetJoint(b1, b2, 0, math.pi / 2)
txts[box_offset] = inspect.getdoc(c)
space.add(c)

box_offset = box_size * 2, box_size
b1 = add_bar(space, (50, 100), box_offset)
b2 = add_bar(space, (150, 100), box_offset)
# Add some pin joints to hold the circles in place.
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset)))
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset)))
# Force one to sping 2x as fast as the other
c = pymunk.GearJoint(b1, b2, 0, 2)
txts[box_offset] = inspect.getdoc(c)
space.add(c)

box_offset = box_size * 3, box_size
b1 = add_bar(space, (50, 100), box_offset)
b2 = add_bar(space, (150, 100), box_offset)
# Add some pin joints to hold the circles in place.
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset)))
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset)))
# Make them spin at 1/2 revolution per second in relation to each other.
c = pymunk.SimpleMotor(b1, b2, math.pi)
txts[box_offset] = inspect.getdoc(c)
space.add(c)

# TODO add one or two advanced constraints examples, such as a car or rope
def main():
    N = int(DURATION / DT) + 1

    space = pymunk.Space()
    space.gravity = (0, 0)

    box_body = pymunk.Body()
    box_body.position = (1, 0.3)
    box_r = 0.5
    box_corners = [(-box_r, box_r), (-box_r, -box_r), (box_r, -box_r),
                   (box_r, box_r)]
    box = pymunk.Poly(box_body, box_corners, radius=0.01)
    # box = pymunk.Circle(box_body, 0.5)
    box.mass = M
    box.friction = 0.5
    box.collision_type = 1
    space.add(box.body, box)

    # linear friction
    pivot = pymunk.PivotJoint(space.static_body, box.body, box.body.position)
    pivot.max_force = MU * M * G  # μmg
    pivot.max_bias = 0  # disable correction so that body doesn't bounce back
    space.add(pivot)

    # angular friction
    gear = pymunk.GearJoint(space.static_body, box.body, 0, 1)
    gear.max_force = 2
    gear.max_bias = 0
    space.add(gear)

    control_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
    control_body.position = (0, 0)
    control_shape = pymunk.Circle(control_body, 0.1, (0, 0))
    control_shape.friction = 1
    control_shape.collision_type = 1
    space.add(control_shape.body, control_shape)

    watcher = CollisionWatcher()
    space.add_collision_handler(1, 1).post_solve = watcher.update

    plt.ion()
    fig = plt.figure()
    ax = plt.gca()

    ax.set_xlabel('x (m)')
    ax.set_ylabel('y (m)')
    ax.set_xlim([-5, 5])
    ax.set_ylim([-3, 3])
    ax.grid()

    ax.set_aspect('equal')

    options = pymunk.matplotlib_util.DrawOptions(ax)
    options.flags = pymunk.SpaceDebugDrawOptions.DRAW_SHAPES

    space.debug_draw(options)
    fig.canvas.draw()
    fig.canvas.flush_events()

    control_body.velocity = (0.25, 0)

    for i in range(N - 1):
        t = i * DT

        # step the sim
        space.step(DT)

        if i % PLOT_PERIOD == 0:
            ax.cla()
            ax.set_xlim([-5, 5])
            ax.set_ylim([-3, 3])
            ax.grid()

            space.debug_draw(options)
            fig.canvas.draw()
            fig.canvas.flush_events()
 def testPhase(self):
     a,b = p.Body(10,10), p.Body(20,20)
     j = p.GearJoint(a, b, 1, 0)
     self.assertEqual(j.phase, 1)
     j.phase = 2
     self.assertEqual(j.phase, 2)
 def testRatio(self):
     a,b = p.Body(10,10), p.Body(20,20)
     j = p.GearJoint(a, b, 0, 1)
     self.assertEqual(j.ratio, 1)
     j.ratio = 2
     self.assertEqual(j.ratio, 2)
예제 #5
0
 def __init__(self, name, context,  pos, color, manager, width= 2.5, length=2.5, mass = 120, maxForce = 400, maxTorque = 20000, maxSpeed = 30, maxAngSpeed = 1): #force in lbs
     self.name = name
     self.context = context
     self.pPickUp = dict.fromkeys(RET_NAMES) # probability of picking up retrievable
     self.tPickUp = dict.fromkeys(RET_NAMES) # avg time spent picking up retrievable
     self.maxPickUp = dict.fromkeys(RET_NAMES) # max # of rets in possession
     self.stPickUp = dict.fromkeys(RET_NAMES) # std dev of pickup time?
     self.scores = dict.fromkeys(SCORE_NAMES) # attainable scores in scorespots
     self.pScores = dict.fromkeys(SCORE_NAMES) # probability of getting score at scorespots
     self.tScores = dict.fromkeys(SCORE_NAMES) # avg time spent scoring at scorespot (seconds)
     self.stScores = dict.fromkeys(SCORE_NAMES) # std dev of score time?
     self.width = width * SCALE
     self.length = length * SCALE
     self.mass=mass
     self.pos = pos * SCALE
     self.maxSpeed = maxSpeed * SCALE
     self.maxAngSpeed = maxAngSpeed * SCALE
     self.angFriction = maxTorque * SCALE * 9
     self.maxForce = maxForce * SCALE
     self.force = Vec2d(0,0)
     self.maxTorque = maxTorque * SCALE
     self.torque = 0
     self.color = color
     self.scale = SCALE
     # create body
     points = [(-self.width/2, -self.length/2),(-self.width/2,self.length/2),(self.width/2,self.length/2),(self.width/2,-self.length/2)]
     self.inertia = pymunk.moment_for_poly(self.mass,points)
     self.body = pymunk.Body(self.mass, self.inertia)
     self.body.position = self.pos
     # setup control body
     self.control = pymunk.Body(pymunk.inf, pymunk.inf, body_type = pymunk.cp.CP_BODY_TYPE_KINEMATIC)
     self.control.position = self.body.position
     self.controlPivot = pymunk.PivotJoint(self.body, self.control,(0,0),(0,0))
     self.controlPivot.max_bias = 0
     self.controlPivot.max_force = 100 * self.maxForce
     self.controlGear = pymunk.GearJoint(self.body, self.control, 0, 1)
     self.controlGear.max_bias = 0
     self.controlGear.max_force = 250 * self.maxTorque
     #create shape
     self.shape = pymunk.Poly(self.body,points)
     self.shape.elasticity = 0.95
     self.shape.friction = 1000
     self.shape.color = pygame.color.THECOLORS[self.color]
     if color is "blue":
         self.score = self.context.blueScore
         self.enemyScore = self.context.redScore
         self.multiplier = -1
     else:
         self.score = self.context.redScore
         self.enemyScore = self.context.blueScore
         self.multiplier = 1
     self.VisField = SensorField("VisField",self.context,self.body,  self.multiplier * 10, self.multiplier * 15, owner = self)# make variables for vis field dims
     self.RetField = SensorField("RetField", self.context, self.body, self.multiplier * 2, self.multiplier * 10, owner = self)
     self.shape.collision_type = collision_types[self.name]
     self.context.objects[self.shape._get_shapeid()] = self
     self.Randomize()
     self.damping = 1
     self.friction = maxForce * SCALE * 6
     self.canPickup = False
     self.canScore = False
     self.immobileTime = 0
     self.inputs = []
     self.RNNInputs = []
     self.logits = []
     self.actions = []
     self.teamScores =[]
     self.objectList = []
     self.rets = defaultdict(lambda:[])
     self.prev = 0 # team's score 1 second ago
     self.numObstacles = 0
예제 #6
0
    def setup(self, *args, **kwargs) -> None:
        super().setup(*args, **kwargs)

        # Physics. This joint setup was taken form tank.py in the pymunk
        # examples.
        if self.shape_type == ShapeType.SQUARE:
            side_len = math.sqrt(math.pi) * self.shape_size
            shapes = self._make_square(side_len)
        elif self.shape_type == ShapeType.CIRCLE:
            shapes = self._make_circle()
        elif self.shape_type == ShapeType.STAR:
            star_npoints = 5
            star_out_rad = 1.3 * self.shape_size
            star_in_rad = 0.5 * star_out_rad
            shapes, convex_parts = self._make_star(star_npoints, star_out_rad,
                                                   star_in_rad)
        else:
            # These are free-form shapes b/c no helpers exist in Pymunk.
            try:
                factor, num_sides = POLY_TO_FACTOR_SIDE_PARAMS[self.shape_type]
            except KeyError:
                raise NotImplementedError("haven't implemented",
                                          self.shape_type)
            side_len = factor * gtools.regular_poly_circ_rad_to_side_length(
                num_sides, self.shape_size)
            shapes, poly_verts = self._make_regular_polygon(
                num_sides, side_len)

        for shape in shapes:
            shape.friction = 0.5
            self.add_to_space(shape)

        trans_joint = pm.PivotJoint(self.space.static_body, self.shape_body,
                                    (0, 0), (0, 0))
        trans_joint.max_bias = 0
        trans_joint.max_force = self.phys_vars.shape_trans_joint_max_force
        self.add_to_space(trans_joint)
        rot_joint = pm.GearJoint(self.space.static_body, self.shape_body, 0.0,
                                 1.0)
        rot_joint.max_bias = 0
        rot_joint.max_force = self.phys_vars.shape_rot_joint_max_force
        self.add_to_space(rot_joint)

        # Graphics.
        geoms_outer = []
        if self.shape_type == ShapeType.SQUARE:
            geoms = [r.make_square(side_len, outline=True)]
        elif self.shape_type == ShapeType.CIRCLE:
            geoms = [r.make_circle(self.shape_size, 100, True)]
        elif self.shape_type == ShapeType.STAR:
            star_short_verts = gtools.compute_star_verts(
                star_npoints,
                star_out_rad - SHAPE_LINE_THICKNESS,
                star_in_rad - SHAPE_LINE_THICKNESS,
            )
            short_convex_parts = autogeom.convex_decomposition(
                star_short_verts + star_short_verts[:1], 0)
            geoms = []
            for part in short_convex_parts:
                geoms.append(r.Poly(part, outline=False))
            geoms_outer = []
            for part in convex_parts:
                geoms_outer.append(r.Poly(part, outline=False))
        elif (self.shape_type == ShapeType.OCTAGON
              or self.shape_type == ShapeType.HEXAGON
              or self.shape_type == ShapeType.PENTAGON
              or self.shape_type == ShapeType.TRIANGLE):
            geoms = [r.Poly(poly_verts, outline=True)]
        else:
            raise NotImplementedError("haven't implemented", self.shape_type)

        if self.shape_type == ShapeType.STAR:
            for g in geoms_outer:
                g.color = darken_rgb(self.color)
            for g in geoms:
                g.color = self.color
        else:
            for g in geoms:
                g.color = self.color
                g.outline_color = darken_rgb(self.color)

        self.shape_xform = r.Transform()
        shape_compound = r.Compound(geoms_outer + geoms)
        shape_compound.add_transform(self.shape_xform)
        self.viewer.add_geom(shape_compound)
예제 #7
0
def stick_arrow_to_target(arrow_body, target_body, position, space):
    pivot_joint = pymunk.PivotJoint(arrow_body, target_body, position)
    phase = target_body.angle - arrow_body.angle
    gear_joint = pymunk.GearJoint(arrow_body, target_body, phase, 1)
    space.add(pivot_joint)
    space.add(gear_joint)
예제 #8
0
    def run_once(self, keep=False, start=False, verbose=False, **kwargs):

        pygame.init()
        if not self.headless:
            self.screen = pygame.display.set_mode(self.display_size, self.display_flags)
            width, height = self.screen.get_size()
            self.draw_options = pymunk.pygame_util.DrawOptions(self.screen)

        def to_pygame(p):
            """Small hack to convert pymunk to pygame coordinates"""
            return int(p.x), int(-p.y+height)
        def from_pygame(p):
            return to_pygame(p)

        clock = pygame.time.Clock()
        running = True
        font = pygame.font.Font(None, 16)

        # Create the torso box.
        box_width = 50
        box_height = 100
        # box_width = 75
        # box_height = 200
        # box_width = 200
        # box_height = 100
        leg_length = 100
        # leg_length = 125
        leg_thickness = 2

        leg_shape_filter = pymunk.ShapeFilter(group=LEG_GROUP)

        # Create torso.
        torso_mass = 500
        torso_points = [(-box_width/2, -box_height/2), (-box_width/2, box_height/2), (box_width/2, box_height/2), (box_width/2, -box_height/2)]
        moment = pymunk.moment_for_poly(torso_mass, torso_points)
        body1 = pymunk.Body(torso_mass, moment)
        body1.position = (self.display_size[0]/2, self.ground_y+box_height/2+leg_length)
        body1.start_position = Vec2d(body1.position)
        body1.start_angle = body1.angle
        body1.center_of_gravity = (0, 0) # centered
        # body1.center_of_gravity = (0, box_height/2) # top-heavy
        # body1.center_of_gravity = (box_width/2, 0) # right-heavy
        shape1 = pymunk.Poly(body1, torso_points)
        shape1.filter = leg_shape_filter
        shape1.friction = 0.8
        shape1.elasticity = 0.0
        self.space.add(body1, shape1)

        # Create leg extending from the right to the origin.
        leg_mass = 1
        leg_points = [
            (leg_thickness/2, -leg_length/2),
            (-leg_thickness/2, -leg_length/2),
            # (-leg_thickness/2, leg_length/2-leg_thickness),
            # (leg_thickness/2, leg_length/2-leg_thickness/2)
            (-leg_thickness/2, leg_length/2),
            (leg_thickness/2, leg_length/2)
        ]
        leg_moment = pymunk.moment_for_poly(leg_mass, leg_points)
        body2 = pymunk.Body(leg_mass, leg_moment)
        if self.leg_position == CORNER:
            # Position leg at far corner of torso.
            body2.position = (self.display_size[0]/2-box_width/2+leg_thickness/2, self.ground_y+leg_length/2)
        elif self.leg_position == OFFSET:
            # Position leg near center of torso, but still offset to create slight instability.
            body2.position = (self.display_size[0]/2-leg_thickness/2, self.ground_y+leg_length/2)
        elif self.leg_position == CENTER:
            body2.position = (self.display_size[0]/2, self.ground_y+leg_length/2)
        else:
            raise NotImplementedError
        body2.start_position = Vec2d(body2.position)
        body2.start_angle = body2.angle
        shape2 = pymunk.Poly(body2, leg_points)
        shape2.filter = leg_shape_filter
        shape2.friction = 0.8
        shape2.elasticity = 0.0
        self.space.add(body2, shape2)

        # Link bars together at end.
        # pj = pymunk.PivotJoint(body1, body2, (self.display_size[0]/2-box_width/2, self.ground_y+leg_length-leg_thickness))
        if self.leg_position == CORNER:
            pj = pymunk.PivotJoint(body1, body2, (self.display_size[0]/2-box_width/2+leg_thickness/2, self.ground_y+leg_length)) # far corner
        elif self.leg_position == OFFSET:
            pj = pymunk.PivotJoint(body1, body2, (self.display_size[0]/2-leg_thickness/2, self.ground_y+leg_length)) # near center
        elif self.leg_position == CENTER:
            pj = pymunk.PivotJoint(body1, body2, (self.display_size[0]/2, self.ground_y+leg_length)) # near center
        else:
            raise NotImplementedError
        # pj = pymunk.PivotJoint(body1, body2, Vec2d(body2.position))
        self.space.add(pj)

        # Attach the foot to the ground in a fixed position.
        # We raise it above by the thickness of the leg to simulate a ball-foot. Otherwise, the default box foot creates discontinuities.
        if self.leg_position == CORNER:
            pj = pymunk.PivotJoint(self.space.static_body, body2, (self.display_size[0]/2-box_width/2+leg_thickness/2, self.ground_y+leg_thickness)) # far
        elif self.leg_position == OFFSET:
            pj = pymunk.PivotJoint(self.space.static_body, body2, (self.display_size[0]/2-leg_thickness/2, self.ground_y+leg_thickness)) # off center
        elif self.leg_position == CENTER:
            pj = pymunk.PivotJoint(self.space.static_body, body2, (self.display_size[0]/2, self.ground_y+leg_thickness)) # center
        else:
            raise NotImplementedError
        self.space.add(pj)

        # Actuate the bars via a motor.
        motor_joint = None
        motor_joint = pymunk.SimpleMotor(body1, body2, 0)
        # motor_joint.max_force = 1e10 # mimicks default infinity, too strong, breaks rotary limit joints
        motor_joint.max_force = 1e9
        # motor_joint.max_force = 1e7 # too weak, almost no movement
        self.space.add(motor_joint)

        # Simulate friction on the foot joint.
        # https://chipmunk-physics.net/forum/viewtopic.php?f=1&t=2916
        foot_gj = pymunk.GearJoint(self.space.static_body, body2, 0.0, 1.0)
        foot_gj.max_force = 1e8
        self.space.add(foot_gj)

        # Simulate friction on the hip joint.
        # https://chipmunk-physics.net/forum/viewtopic.php?f=1&t=2916
        # hip_gj = pymunk.GearJoint(body1, body2, 0.0, 1.0)
        # hip_gj.max_force = 1e10
        # self.space.add(hip_gj)

        # Add hard stops to leg pivot so the leg can't rotate through the torso.
        angle_range = pi/4. # 45 deg
        # angle_range = pi/2. # 90 deg
        hip_limit_joint = pymunk.RotaryLimitJoint(body1, body2, -angle_range, angle_range) # -45deg:+45deg
        self.space.add(hip_limit_joint)

        # default angle = 270/2 = 135 deg
        servo = None
        if motor_joint:
            servo = ServoController(motor_joint, max_rate=20.0)
            servo.set_degrees(135)

        # pygame.time.set_timer(USEREVENT+1, 70000) # apply force
        # pygame.time.set_timer(USEREVENT+2, 120000) # reset
        # pygame.event.post(pygame.event.Event(USEREVENT+1))
        # pygame.mouse.set_visible(False)

        self.reset()

        last_body1_pos = None
        last_body1_vel = None
        simulate = False
        self.cnt = 0
        failed = None
        simulate = start
        current_state = None
        # The point at which the torso has toppled over.
        failure_degrees = 45
        while running:
            self.cnt += 1
            # print('angles:', body1.angle, body2.angle)
            # print('torso force:', body1.force)
            # print('body1.position: %.02f %.02f' % (body1.position.x, body1.position.y))

            current_body1_vel = None
            if last_body1_pos:
                current_body1_vel = body1.position - last_body1_pos
                # print('current_body1_vel: %.02f %.02f' % (current_body1_vel.x, current_body1_vel.y))

            current_body1_accel = None
            if last_body1_vel:
                current_body1_accel = current_body1_vel - last_body1_vel
                # print('current_body1_accel: %.02f %.02f' % (current_body1_accel.x, current_body1_accel.y))

            # Angle of the torso, where 0 degrees is the torso perfectly parallel to the ground.
            # A positive angle is clockwise rotation.
            # This simulates the IMU's y euler angle measurement.
            torso_angle = -body1.angle * 180/pi
            # print('torso_angle:', torso_angle)

            # Angle of the hip servo.
            # A positive angle is clockwise rotation.
            # This simulates the estimated hip servo potentiometer.
            hip_angle = (body2.angle - body1.angle) * 180/pi # 0 degrees means leg is angled straight down

            # Angle of the foot, where 0 degrees is the foot perfectly perpedicular to the ground.
            # A positive angle is clockwise rotation.
            foot_angle = -body2.angle * 180/pi
            # print('foot_angle:', foot_angle)

            # Re-frame angle so that 135 degrees indicates the straight down orientation.
            hip_angle += 135
            # print('hip_angle:', hip_angle)

            current_state = [torso_angle/360., hip_angle/360., foot_angle/360.]
            # assert not [_ for _ in current_state if abs(_) > 1]

            # Auto-shift COG using foot angle as proportion of shift
            # iters=163
            # If we lean right, shift COG left, and vice versa.
            # body1.center_of_gravity = (-box_width/2*foot_angle/90.*10, 0)
            # cog_limit = box_width/2
            # print('cog_limit:', cog_limit)
            # print('foot_angle:', foot_angle)
            # dist_from_center = sin(-body2.angle)*leg_length
            # print('dist_from_center:', dist_from_center)
            # max_dist_from_center = sin(pi/4)*leg_length
            # print('max_dist_from_center:', max_dist_from_center)
            # comp_rate = -dist_from_center/max_dist_from_center
            # print('comp_rate:', comp_rate)
            # gamma = 4
            # comp_rate2 = exp(abs(comp_rate*gamma))
            # if comp_rate < 0:
                # comp_rate2 = -comp_rate2
            # print('comp_rate2:', comp_rate2)
            # comp_rate3 = max(min(comp_rate2, cog_limit), -cog_limit)
            # print('comp_rate3:', comp_rate3)
            # body1.center_of_gravity = (comp_rate3, 0)

            if self.verbose:
                print('foot.angular_velocity:', body2.angular_velocity) # positive=CCW, negative=CW
                if isnan(float(body2.angular_velocity)):
                    print('Physics breakdown! Terminating simulation!', file=sys.stderr)
                    return

            # Auto-shift COG using foot angular velocity direction.
            # iters=403
            servo.set_position(1500)
            servo.attach()
            # if body2.angular_velocity > 0:
                # # falling left
                # body1.center_of_gravity = (box_width/2, 0) # shift weight right
            # else:
                # # falling right
                # body1.center_of_gravity = (-box_width/2, 0) # shift weight left

            # Auto-shift COG using foot angular velocity magnitude.
            # body1.center_of_gravity = (box_width/2*body2.angular_velocity/5*1, 0)# iters=158
            # body1.center_of_gravity = (box_width/2*body2.angular_velocity/5*2, 0)# iters=161
            # body1.center_of_gravity = (box_width/2*body2.angular_velocity/5*2.5, 0)# iters=157
            # body1.center_of_gravity = (box_width/2*body2.angular_velocity/5*3, 0)# iters=160
            # body1.center_of_gravity = (box_width/2*body2.angular_velocity/5*5, 0)# iters=153
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*1, box_width/2), -box_width/2), 0)# iters=153
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*2, box_width/2), -box_width/2), 0)# iters=135
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*3, box_width/2), -box_width/2), 0)# iters=132
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*100, box_width/2), -box_width/2), 0)# iters=290
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*50, box_width/2), -box_width/2), 0)# iters=216
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*25, box_width/2), -box_width/2), 0)# iters=278
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*200, box_width/2), -box_width/2), 0)# iters=293
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*1000, box_width/2), -box_width/2), 0)# iters=304
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*10000, box_width/2), -box_width/2), 0)# iters=333
            # body1.center_of_gravity = (max(min(box_width/2*body2.angular_velocity*100000, box_width/2), -box_width/2), 0)# iters=333

            if self.verbose:
                print('cog:', body1.center_of_gravity)

            # Auto-shift hip angle to level.
            #TODO

            # Handle balancer agent input.
            if self.balancer:
                relative_position_change = self.balancer.get_action(state=current_state, actions=self.get_actions(self.balancer))
                if self.verbose:
                    print('balancer action:', relative_position_change)
                # Otherwise convert the relative +/- position into an absolute servo position.
                hip_position = servo.degree_to_position(hip_angle)
                new_hip_position = hip_position + relative_position_change
                servo.set_position(new_hip_position)
                # servo.set_position(1000)#manual
                servo.attach()

            # Handle shifter agent input.
            if self.shifter:
                shifter_state = [body2.angular_velocity/10.]
                cog_shift = self.shifter.get_action(
                    state=list(shifter_state),
                    actions=[-box_width/2., -box_width/4., -box_width/16., -box_width/32., 0, +box_width/2., +box_width/4., +box_width/16., +box_width/32.])
                body1.center_of_gravity = (max(min(cog_shift, box_width/2), -box_width/2), 0)

            # Handle user input.
            for event in pygame.event.get():
                if event.type == QUIT or (event.type == KEYDOWN and event.key in (K_q, K_ESCAPE)):
                    running = False
                elif event.type == KEYDOWN and event.key == K_s:
                    # Start/stop simulation.
                    simulate = not simulate
                elif event.type == KEYDOWN and event.key == K_r:
                    # Reset.
                    self.reset_bodies()
                elif event.type == KEYDOWN and event.key == K_LEFT:
                    # Angle backwards by rotating torso about the hips counter-clockwise.
                    servo.set_degrees(servo.min_degrees)
                    servo.attach()
                elif event.type == KEYDOWN and event.key == K_RIGHT:
                    # Angle forwarads by rotating torso about the hips clockwise.
                    servo.set_degrees(servo.max_degrees)
                    servo.attach()
                elif event.type == KEYUP:
                    # Otherwise, make the servo go unpowered and idle.
                    servo.detach()
                servo.update(current_degrees=hip_angle)

            if not self.headless:
                self.draw()

            last_body1_pos = Vec2d(body1.position)
            if current_body1_vel:
                last_body1_vel = Vec2d(current_body1_vel)

            ### Update physics
            fps = 50
            iterations = 25
            dt = 1.0/float(fps)/float(iterations)
            if simulate:
                for x in range(iterations): # 10 iterations to get a more stable simulation
                    self.space.step(dt)

            if not self.headless:
                pygame.display.flip()
            clock.tick(fps)

            # Give balancer feedback.
            # The balancer's objective is to keep the torso as level as possible, balanced on the foot.
            failed = abs(foot_angle) > failure_degrees
            if self.balancer:
                # Feedback is the inverse distance of the torso's angle from center.
                if failed:
                    # Terminal failure.
                    feedback = -1
                else:
                    # Otherwise, grade performance based on how level the torso is.
                    feedback = valmap(abs(torso_angle), 0, 90, 1, -1)

                # print('failed:', failed)
                self.balancer.reinforce(feedback=feedback+self.cnt, state=current_state, end=failed)

            if self.shifter:
                if failed:
                    feedback = -1
                else:
                    # feedback = 0
                    feedback = (90. - abs(foot_angle))/90.
                self.shifter.reinforce(feedback=feedback, state=shifter_state, end=failed)

            # Check failure criteria.
            if not keep and (failed or self.cnt >= 1000):
                break

        print('Result: %s' % {True: 'failure', False:'aborted', None:'aborted'}[failed])
        print('Iterations: %i' % self.cnt)

        if self.balancer:
            self.balancer.save()
        if self.shifter:
            self.shifter.save()
예제 #9
0
def init():
    
    space = pymunk.Space()
    space.iterations = 10
    space.sleep_time_threshold = 0.5
    
    static_body = space.static_body
        
    # Create segments around the edge of the screen.
    shape = pymunk.Segment(static_body, (1,1), (1,480), 1.0)
    space.add(shape)
    shape.elasticity = 1
    shape.friction = 1

    shape = pymunk.Segment(static_body, (640,1), (640,480), 1.0)
    space.add(shape)
    shape.elasticity = 1
    shape.friction = 1
    
    shape = pymunk.Segment(static_body, (1,1), (640,1), 1.0)
    space.add(shape)
    shape.elasticity = 1
    shape.friction = 1
    
    shape = pymunk.Segment(static_body, (1,480), (640,480), 1.0)
    space.add(shape)
    shape.elasticity = 1
    shape.friction = 1
    
    for _ in range(50):
        body = add_box(space, 20, 1)
        
        pivot = pymunk.PivotJoint(static_body, body, (0,0), (0,0))
        space.add(pivot)
        pivot.max_bias = 0 # disable joint correction
        pivot.max_force = 1000 # emulate linear friction
        
        gear = pymunk.GearJoint(static_body, body, 0.0, 1.0)
        space.add(gear)
        gear.max_bias = 0 # disable joint correction
        gear.max_force = 5000  # emulate angular friction
    
    # We joint the tank to the control body and control the tank indirectly by modifying the control body.
    global tank_control_body
    tank_control_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
    tank_control_body.position = 320, 240
    space.add(tank_control_body)
    global tank_body
    tank_body = add_box(space, 30, 10)
    tank_body.position = 320, 240
    for s in tank_body.shapes:
        s.color = (0,255,100,255)
    
    pivot = pymunk.PivotJoint(tank_control_body, tank_body, (0,0), (0,0))
    space.add(pivot)
    pivot.max_bias = 0 # disable joint correction
    pivot.max_force = 10000 # emulate linear friction
    
    gear = pymunk.GearJoint(tank_control_body, tank_body, 0.0, 1.0)
    space.add(gear)    
    gear.error_bias = 0 # attempt to fully correct the joint each step
    gear.max_bias = 1.2  # but limit it's angular correction rate
    gear.max_force = 50000 # emulate angular friction
        
    return space
예제 #10
0
    def __init__(self, space: pymunk.Space, theta: int = 0):
        self.space = space

        # Define initial angle
        angle = Angle(theta)

        # Define bodies
        self.top = pymunk.Body(50, 10000, pymunk.Body.STATIC)
        self.bottom = pymunk.Body(50, 10000, pymunk.Body.STATIC)
        self.rod1 = pymunk.Body(5, 10000)
        self.rod2 = pymunk.Body(5, 10000)
        self.rod3 = pymunk.Body(5, 10000)
        self.seat = pymunk.Body(10, 10000)
        self.torso = pymunk.Body(10, 10000)
        self.legs = pymunk.Body(10, 10000)
        self.head = pymunk.Body(5, 10000)

        # Create shapes
        self.top_shape = pymunk.Poly.create_box(self.top, size=(1200, 50))
        self.bottom_shape = pymunk.Poly.create_box(self.bottom,
                                                   size=(1200, 50))
        self.rod1_shape = pymunk.Segment(self.rod1, (0, 0),
                                         angle.rod1,
                                         radius=3)
        self.rod2_shape = pymunk.Segment(self.rod2, (0, 0),
                                         angle.rod2,
                                         radius=3)
        self.rod3_shape = pymunk.Segment(self.rod3, (0, 0),
                                         angle.rod3,
                                         radius=3)
        self.seat_shape = pymunk.Segment(self.seat,
                                         angle.seat[0],
                                         angle.seat[1],
                                         radius=5)
        self.torso_shape = pymunk.Poly.create_box(self.torso,
                                                  size=(10, torso_length))
        self.legs_shape = pymunk.Poly.create_box(self.legs,
                                                 size=(10, legs_length))
        self.head_shape = pymunk.Circle(self.head, radius=20)

        # Set layer of shapes (disables collisions between bodies)
        self.rod1_shape.filter = pymunk.ShapeFilter(
            categories=0b100, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0b100)
        self.rod2_shape.filter = pymunk.ShapeFilter(
            categories=0b100, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0b100)
        self.rod3_shape.filter = pymunk.ShapeFilter(
            categories=0b100, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0b100)
        self.seat_shape.filter = pymunk.ShapeFilter(
            categories=0b100, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0b100)
        self.torso_shape.filter = pymunk.ShapeFilter(
            categories=0b100, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0b100)
        self.legs_shape.filter = pymunk.ShapeFilter(
            categories=0b100, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0b100)
        self.head_shape.filter = pymunk.ShapeFilter(
            categories=0b100, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0b100)

        # Set positions of bodies
        self.top.position = (600, 720)
        self.bottom.position = (600, 0)
        self.rod1.position = (600, 695)
        self.rod2.position = angle.point1
        self.rod3.position = angle.point2
        self.seat.position = angle.point4
        self.torso.position = (angle.point4[0] + angle.seat[1][0] +
                               (torso_length / 2) * math.sin(angle._theta),
                               angle.point4[1] + angle.seat[1][1] +
                               (torso_length / 2) * math.cos(angle._theta))
        self.torso._set_angle(-angle._theta)
        self.legs.position = (angle.point4[0] + angle.seat[0][0] -
                              (legs_length / 2) * math.sin(angle._theta),
                              angle.point4[1] + angle.seat[0][1] -
                              (legs_length / 2) * math.cos(angle._theta))
        self.legs._set_angle(-angle._theta)
        self.head.position = (angle.point4[0] + angle.seat[1][0] +
                              (torso_length - 10) * math.sin(angle._theta),
                              angle.point4[1] + angle.seat[1][1] +
                              (torso_length - 10) * math.cos(angle._theta))

        # Create pivot joints for bodies
        self.pivot1 = pymunk.PivotJoint(self.top, self.rod1, (600, 695))
        self.pivot2 = pymunk.PivotJoint(self.rod1, self.rod2, angle.point1)
        self.pivot3 = pymunk.PivotJoint(self.rod2, self.rod3, angle.point2)
        self.pivot4 = pymunk.PivotJoint(self.rod3, self.seat, angle.point4)
        self.pivot5 = pymunk.PinJoint(self.rod3,
                                      self.seat,
                                      anchor_a=angle.rod3,
                                      anchor_b=angle.seat[0])
        self.pivot6 = pymunk.PinJoint(self.rod3,
                                      self.seat,
                                      anchor_a=angle.rod3,
                                      anchor_b=angle.seat[1])
        self.pivot7 = pymunk.PivotJoint(self.torso, self.seat,
                                        (angle.point4[0] + angle.seat[1][0],
                                         angle.point4[1] + angle.seat[1][1]))
        self.pivot8 = pymunk.PivotJoint(self.seat, self.legs,
                                        (angle.point4[0] + angle.seat[0][0],
                                         angle.point4[1] + angle.seat[0][1]))
        self.pivot9 = pymunk.PivotJoint(self.head, self.torso,
                                        self.head.position)
        self.gear1 = pymunk.GearJoint(self.torso, self.seat, angle._theta, 1.0)
        self.gear2 = pymunk.GearJoint(self.seat, self.legs, -angle._theta, 1.0)

        # Prevent pivots from exerting infinite force
        self.pivot1.max_force = 1000000
        self.pivot2.max_force = 1000000
        self.pivot3.max_force = 1000000
        self.pivot4.max_force = 1000000

        # Add damping (not yet working)
        # damping1 = pymunk.DampedSpring(self.top, self.rod1, anchor_a=(-600,-25),
        #                                anchor_b=(0,-rod1_length / 2),
        #                                rest_length=100, stiffness=5, damping=3)
        # damping2 = pymunk.DampedSpring(self.top, self.rod1, anchor_a=(600,-25),
        #                                anchor_b=(0,-rod1_length / 2),
        #                                rest_length=100, stiffness=5, damping=3)

        # Disable collisions between rods
        self.pivot1.collide_bodies = False
        self.pivot2.collide_bodies = False
        self.pivot3.collide_bodies = False
        self.pivot4.collide_bodies = False
        self.pivot7.collide_bodies = False
        self.pivot8.collide_bodies = False
        self.pivot9.collide_bodies = False

        # Add bodies and pivots to space
        self.space.add(self.top, self.top_shape, self.bottom,
                       self.bottom_shape, self.rod1, self.rod1_shape,
                       self.rod2, self.rod2_shape, self.rod3, self.rod3_shape,
                       self.seat, self.seat_shape, self.torso,
                       self.torso_shape, self.legs, self.legs_shape, self.head,
                       self.head_shape, self.pivot1, self.pivot2, self.pivot3,
                       self.pivot4, self.pivot5, self.pivot6, self.pivot7,
                       self.pivot8, self.pivot9, self.gear1, self.gear2)
예제 #11
0
        body.position = xylist[i]
        body.velocity = (0, 0)
        shape = pymunk.Poly(body, vertices)
        shape.collision_type = COLLTYPE_UNIT
        shape.elasticity = elasticityConstant
        shape.friction = frictionConstant
        shape.color = color
        shape.group = 0
        space.add(body, shape)
    # Add joints
    botlist = []
    for bot in space.shapes:
        if isinstance(bot, pymunk.Poly) and bot.body != None:
            botlist.append(bot.body)
    space.add(pymunk.PivotJoint(botlist[0], botlist[1], jointlist[0]))
    space.add(pymunk.GearJoint(botlist[0], botlist[1], 0, 1))
    space.add(pymunk.PivotJoint(botlist[0], botlist[2], jointlist[1]))
    space.add(pymunk.GearJoint(botlist[0], botlist[2], 0, 1))
    space.add(pymunk.PivotJoint(botlist[1], botlist[3], jointlist[2]))
    space.add(pymunk.GearJoint(botlist[1], botlist[3], 0, 1))
    space.add(pymunk.PivotJoint(botlist[2], botlist[3], jointlist[3]))
    space.add(pymunk.GearJoint(botlist[2], botlist[3], 0, 1))
    # End of Option 2

    # Instantiate collision handler
    ch = space.add_collision_handler(COLLTYPE_UNIT, COLLTYPE_UNIT)
    ch.data["surface"] = screen
    ch.pre_solve = groupCheck
    ch.post_solve = addJoints

    # Counter for random motion
예제 #12
0
 def AddToSpace(self):
     if self.shape.space == None:
         #constrain to bot's body
         self.pivotConstraint = pymunk.PivotJoint(self.bot, self.body, (0,0), (0,0))
         self.gearJoint = pymunk.GearJoint(self.bot, self.body,0 , 1)
         self.context.space.add(self.body,self.shape,  self.pivotConstraint, self.gearJoint)
예제 #13
0
 def __init__(self, b, b2, phase, ratio):
     joint = pymunk.GearJoint(b, b2, phase, ratio)
     space.add(joint)