首页 > 解决方案 > 关于pymunk准确性的几个问题

问题描述

我有兴趣模拟一种杆摆系统:

from intro import pymunk, space, App
import pygame
from pymunk.vec2d import Vec2d

pygame.init()


b0 = space.static_body                      #declare a universe

b1 = pymunk.Body(mass=1000, moment=10)
b1.position = (240, 200)
c1 = pymunk.Segment(b1, (0, -40), (0, 40), 6)
c1.elasticity = 0.1
space.add(b1, c1)

b2 = pymunk.Body(mass=.1, moment=1)
b2.position = (240, 100)
c2 = pymunk.Segment(b2, (0, 0), (0, -40), 6)
c2.elasticity = 0.1
space.add(b2, c2)

j1 = pymunk.constraints.PinJoint(b0, b1, (240, 200), (0,0))
j2 = pymunk.constraints.PinJoint(b2, b1, (0, 0),(0,-40))

space.add(j1, j2)
b1.torque = 4000
space.gravity = 0,0                 #gx , gy
print(b1.position, b1.velocity)
App().run()
print(b1.position, b1.velocity)

但它并没有像我预期的那样运行。

  1. 我在主杆上有一个设定扭矩。我认为系统应该随着时间的推移慢慢加速。我没有看到。
  2. 辅助杆似乎没有感觉到向心加速度。我认为当它摆动时,它会指向外面。我认为这与模拟质量的分布方式有关。我需要将辅助杆变成一系列质量,还是有更简单的方法来移动质心?
  3. 我可以改变主杆与副杆的质量比。我会假设当 M1>>M2 时系统会像没有辅助杆一样旋转。但我没有看到这一点,而是主杆振荡,好像它正在将大量的角动量传递给辅助杆。我错过了什么吗?
  4. pymunk 甚至应该是一个可靠的物理模拟器吗?或者它只是近似于物理,足以成为游戏的一部分?
  5. 是否有一个基于 python 的物理模拟器,您会为这样的系统推荐它。最终,我希望能够通过可变扭矩和阻力来模拟振荡,同时记录系统上的力。

标签: pythonsimulationphysicspymunk

解决方案


  1. 每一步都会重置扭矩,如此处所述:http: //www.pymunk.org/en/latest/pymunk.html#pymunk.Body.torque鉴于此,我认为期望它应该随着时间的推移而减慢。我还应该补充一点,通常手动设置这些类型的值有点棘手,最好使用 SimpleMotor 约束。

  2. 是的,正如您所写的那样,重心似乎是这里的问题。重心将位于段的 0,0 处(如果您创建多边形形状,重心将位于 0,0 处)。因此c1,重心在中间,而c2在一端。您可以仅更改c2to be的定义(b2, (0,-20), (0,20)...)并修改主体的位置以进行补偿,也可以使用主体 center_of_gravity 属性来调整其位置。http://www.pymunk.org/en/latest/pymunk.html#pymunk.Body.center_of_gravity

  3. 我认为问题在于你用于两个段体的时刻非常极端。可以使用内置方法 moment_for_segment 计算力矩,例如:pymunk.moment_for_segment(1000, (0, -40), (0, 40), 6)计算的力矩为 717000,与您代码中的值有很大不同。您还可以让 Pymunk 根据附加的形状计算物体的质量和力矩,http: //www.pymunk.org/en/latest/pymunk.html#pymunk.Body.__init__

  4. Pymunk 使用 C 库 Chipmunk 进行实际模拟。这个库的重点主要是游戏或其他实时用途,Pymunk 也是如此。但是,我知道 Pymunk 已用于许多不同的目的,如此处的使用列表所示:http://www.pymunk.org/en/latest/showcase.html页面。如果 Pymunk 内部的算法对您的用例来说足够准确和全面,我不知道。

  5. 没有把握。

最后一点是,在space.step函数中使用尽可能小的 dt 可能是个好主意,因为这样会产生更好的模拟。


推荐阅读