Уравновешивающая коробка на колесах с пружинами (блокировка поворота относительно коробки) пимунк - PullRequest
4 голосов
/ 05 мая 2020

Я хочу иметь возможность фиксировать угол наклона колес относительно шасси автомобиля. Между колесами есть пружины, которые должны позволить машине подвешиваться, но сейчас угол не заблокирован. Я использую функцию pymunk "RotaryLimitJoint"

Такое поведение является целью (gif)

Wanted behavior

Сейчас это выглядит так это:

Current state

Мой код:

car_pos = Vec2d(100,500)
mass = 30
radius = 10
moment = pymunk.moment_for_circle(mass, 20, radius)
wheel1_b = pymunk.Body(mass, moment)
wheel1_s = pymunk.Circle(wheel1_b, radius)
wheel1_s.friction = 1.5
wheel1_s.color = wheel_color
space.add(wheel1_b, wheel1_s)

mass = 30
radius = 10
moment = pymunk.moment_for_circle(mass, 20, radius)
wheel2_b = pymunk.Body(mass, moment)
wheel2_s = pymunk.Circle(wheel2_b, radius)
wheel2_s.friction = 1.5
wheel2_s.color = wheel_color
space.add(wheel2_b, wheel2_s)

mass = 100
size = (80,25)
moment = pymunk.moment_for_box(mass, size)
chassi_b = pymunk.Body(mass, moment)
chassi_s = pymunk.Poly.create_box(chassi_b, size)
chassi_s.color = chassi_color
space.add(chassi_b, chassi_s)


#Positions
chassi_b.position = car_pos + (0,-15)
wheel1_b.position = car_pos + (-25,0)
wheel2_b.position = car_pos + (25,0)

#Joints

spring1 = pymunk.DampedSpring(chassi_b, wheel1_b, (-25,0), (0,0), 20, 100000, 1)
spring1.collide_bodies = False
spring2 = pymunk.DampedSpring(chassi_b, wheel2_b, (25,0), (0,0), 20, 100000, 1)
spring2.collide_bodies = False

wheelAngle1 = pymunk.RotaryLimitJoint(wheel1_b, chassi_b, 0, 0)
wheelAngle1.collide_bodies = False
wheelAngle2 = pymunk.RotaryLimitJoint(chassi_b, wheel2_b, 0, 0)
wheelAngle2.collide_bodies = False



space.add(
    spring1,
    spring2,
    wheelAngle1,
    wheelAngle2
)
speed = 20

space.add(
    pymunk.SimpleMotor(wheel1_b, chassi_b, speed),
    pymunk.SimpleMotor(wheel2_b, chassi_b, speed)
)

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Первое упоминание @ vilbo.

Что заставляет следующий код работать, так это то, что GrooveJoint ( см. Документы ) создается перпендикулярно шасси автомобиля. GrooveJoint определяет линию, по которой тело может свободно скользить. Определяя GrooveJoint, он прикреплен к шасси автомобиля и к колесу (как для переднего, так и для заднего колеса).

Теперь это выглядит так:

Working gif

Я преобразовал код (из @vilbo) в python и вот он:

def car(space, speed, add_car):
    car_pos = Vec2d(100,500)

    #bodies
    wheel_color = 0,0,0
    chassi_color = 255,0,0
    wheelCon_color = 0,255,255

    #Wheel 1
    mass = 25
    radius = 10
    moment = pymunk.moment_for_circle(mass, 20, radius)
    wheel1_b = pymunk.Body(mass, moment)
    wheel1_s = pymunk.Circle(wheel1_b, radius)
    wheel1_s.friction = 1.5
    wheel1_s.color = wheel_color

    #Wheel 2
    mass = 25
    radius = 10
    moment = pymunk.moment_for_circle(mass, 20, radius)
    wheel2_b = pymunk.Body(mass, moment)
    wheel2_s = pymunk.Circle(wheel2_b, radius)
    wheel2_s.friction = 1.5
    wheel2_s.color = wheel_color

    #Chassi
    mass = 30
    size = (80,25)
    moment = pymunk.moment_for_box(mass, size)
    chassi_b = pymunk.Body(mass, moment)
    chassi_s = pymunk.Poly.create_box(chassi_b, size)
    chassi_s.color = chassi_color

    #Positions
    chassi_b.position = car_pos + (0,-15)
    wheel1_b.position = car_pos + (-25,0)
    wheel2_b.position = car_pos + (25,0)

    #Joints
    spring1 = pymunk.constraint.DampedSpring(chassi_b, wheel1_b, (-25,0), (0,0), 15, 5000, 250)
    spring1.collide_bodies = False
    spring2 = pymunk.constraint.DampedSpring(chassi_b, wheel2_b, (25,0), (0,0), 15, 5000, 250)
    spring2.collide_bodies = False

    groove1 = pymunk.constraint.GrooveJoint(chassi_b, wheel1_b, (-25,0), (-25,25), (0, 0))
    groove1.collide_bodies = False
    groove2 = pymunk.constraint.GrooveJoint(chassi_b, wheel2_b, (25,0), (25,25), (0,0))
    groove2.collide_bodies = False

    if add_car:
        motor1 = pymunk.SimpleMotor(wheel1_b, chassi_b, speed)
        motor2 = pymunk.SimpleMotor(wheel2_b, chassi_b, speed)
        space.add(
            spring1,
            spring2,
            groove1,
            groove2,
            motor1,
            motor2,
            chassi_b, 
            chassi_s,
            wheel2_b,
            wheel2_s,
            wheel1_b,
            wheel1_s
        )
1 голос
/ 06 мая 2020

RotaryLimitJoint - это не то, что вам нужно. Это ограничит угол между колесом и шасси, но колесо должно вращаться, поэтому оно не будет работать.

Вместо этого вы можете попробовать GrooveJoint.

Вот как выглядит код в коде c, его должно быть довольно легко преобразовать в python:

Полный исходный код: https://github.com/slembcke/Chipmunk2D/blob/master/demo/Joints.c#L263

Соответствующая часть:

boxOffset = cpv(0, 0);
cpBody *wheel1 = addWheel(space, posA, boxOffset);
cpBody *wheel2 = addWheel(space, posB, boxOffset);
cpBody *chassis = addChassis(space, cpv(80, 100), boxOffset);

cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel1, cpv(-30, -10), cpv(-30, -40), cpvzero));
cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel2, cpv( 30, -10), cpv( 30, -40), cpvzero));

cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel1, cpv(-30, 0), cpvzero, 50.0f, 20.0f, 10.0f));
cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel2, cpv( 30, 0), cpvzero, 50.0f, 20.0f, 10.0f));

Если вы не можете понять это, я могу попробовать преобразовать его в python, но, к сожалению, я не на компьютере с Python и настройкой Pymunk для этого сейчас.

...