Physics 真实两腿骨骼的物理模拟

Physics 真实两腿骨骼的物理模拟,physics,simulation,game-physics,physics-engine,bulletphysics,Physics,Simulation,Game Physics,Physics Engine,Bulletphysics,我希望利用bullet physics或类似的物理引擎来创建一个具有两条腿的仿人身体的真实骨架模拟。也就是说,在两条“腿”的顶部创建一个由圆形质量组成的“身体”模拟,其中每条腿由3个实体块组成,通过3个关节连接,每个关节在每个方向上都有一定的自由度和有限的运动范围,类似于人类的臀部、膝盖和脚踝 我的目标是建立一个真实的模型,因此,只有当所有关节都正确平衡时,它才会“站立”,否则它就会掉落 任何指向现有教程或资源的指导、建议或指针都将不胜感激!这看起来像是从零开始做了大量的工作……毫无疑问,从零开

我希望利用bullet physics或类似的物理引擎来创建一个具有两条腿的仿人身体的真实骨架模拟。也就是说,在两条“腿”的顶部创建一个由圆形质量组成的“身体”模拟,其中每条腿由3个实体块组成,通过3个关节连接,每个关节在每个方向上都有一定的自由度和有限的运动范围,类似于人类的臀部、膝盖和脚踝

我的目标是建立一个真实的模型,因此,只有当所有关节都正确平衡时,它才会“站立”,否则它就会掉落


任何指向现有教程或资源的指导、建议或指针都将不胜感激!这看起来像是从零开始做了大量的工作……

毫无疑问,从零开始做将很难。我不知道你的目标是什么。但你不必重新设计车轮。你看了那本书了吗?你可能会在那里找到可以重复使用的东西。许多游戏都是建立在这个引擎的顶部。

我目前正在编写类似的代码。我的方法是使用Bullet Physics碎布玩偶演示作为起点。它有一个布娃娃,身体各部分通过关节连接

然后我使用Bullet Physics动态控制演示来学习弯曲关节。目前最具挑战性的部分是设置所有参数

我建议您学习如何创建由约束连接的两个刚体,然后激活约束电机以弯曲关节

以下是我正在使用的一些代码,以了解刚体和约束在子弹物理中是如何工作的。代码将创建由铰链约束连接的两个块。“更新”功能会随时间缓慢弯曲铰链约束

现在我有了这个,我将回到布娃娃和调整关节

class Simple
{
private:
    btScalar targetAngle;

    btCollisionShape* alphaCollisionShape;
    btCollisionShape* bravoCollisionShape;
    btRigidBody* alphaRigidBody;
    btRigidBody* bravoRigidBody;
    btHingeConstraint* hingeConstraint;

    btDynamicsWorld* dynamicsWorld;

public:
    ~Simple( void )
    {
    }

    btRigidBody* createRigidBody( btCollisionShape* collisionShape, 
                  btScalar mass, 
                  const btTransform& transform ) const
    {
    // calculate inertia
    btVector3 localInertia( 0.0f, 0.0f, 0.0f );
    collisionShape->calculateLocalInertia( mass, localInertia );    

    // create motion state
    btDefaultMotionState* defaultMotionState 
        = new btDefaultMotionState( transform );

    // create rigid body
    btRigidBody::btRigidBodyConstructionInfo rigidBodyConstructionInfo( 
        mass, defaultMotionState, collisionShape, localInertia );
    btRigidBody* rigidBody = new btRigidBody( rigidBodyConstructionInfo );      

    return rigidBody;
    }

    void Init( btDynamicsWorld* dynamicsWorld )
    {
    this->targetAngle = 0.0f;

    this->dynamicsWorld = dynamicsWorld;

    // create collision shapes
    const btVector3 alphaBoxHalfExtents( 0.5f, 0.5f, 0.5f );
    alphaCollisionShape = new btBoxShape( alphaBoxHalfExtents );

    //
    const btVector3 bravoBoxHalfExtents( 0.5f, 0.5f, 0.5f );
    bravoCollisionShape = new btBoxShape( bravoBoxHalfExtents );

    // create alpha rigid body
    const btScalar alphaMass = 10.0f;
    btTransform alphaTransform;
    alphaTransform.setIdentity();
    const btVector3 alphaOrigin( 54.0f, 0.5f, 50.0f );  
    alphaTransform.setOrigin( alphaOrigin );
    alphaRigidBody = createRigidBody( alphaCollisionShape, alphaMass, alphaTransform );
    dynamicsWorld->addRigidBody( alphaRigidBody );

    // create bravo rigid body
    const btScalar bravoMass = 1.0f;
    btTransform bravoTransform;
    bravoTransform.setIdentity();
    const btVector3 bravoOrigin( 56.0f, 0.5f, 50.0f );  
    bravoTransform.setOrigin( bravoOrigin );
    bravoRigidBody = createRigidBody( bravoCollisionShape, bravoMass, bravoTransform );
    dynamicsWorld->addRigidBody( bravoRigidBody );

    // create a constraint
    const btVector3 pivotInA( 1.0f, 0.0f, 0.0f );   
    const btVector3 pivotInB( -1.0f, 0.0f, 0.0f );
    btVector3 axisInA( 0.0f, 1.0f, 0.0f );
    btVector3 axisInB( 0.0f, 1.0f, 0.0f );
    bool useReferenceFrameA = false;
    hingeConstraint = new btHingeConstraint( 
        *alphaRigidBody,
        *bravoRigidBody,
        pivotInA,
        pivotInB,
        axisInA,
        axisInB,
        useReferenceFrameA );

    // set constraint limit
    const btScalar low = -M_PI;
    const btScalar high = M_PI;
    hingeConstraint->setLimit( low, high );

    // add constraint to the world
    const bool isDisableCollisionsBetweenLinkedBodies = false;
    dynamicsWorld->addConstraint( hingeConstraint, 
                      isDisableCollisionsBetweenLinkedBodies );
    }

    void Update( float deltaTime )
    {
    alphaRigidBody->activate();
    bravoRigidBody->activate();

    bool isEnableMotor = true;
    btScalar maxMotorImpulse = 1.0f; // 1.0f / 8.0f is about the minimum

    hingeConstraint->enableMotor( isEnableMotor );
    hingeConstraint->setMaxMotorImpulse( maxMotorImpulse );

    targetAngle += 0.1f * deltaTime;
    hingeConstraint->setMotorTarget( targetAngle, deltaTime );  
    }

};
Hase和Yamazaki(2002)刚刚发现了“利用三维全身神经肌肉骨骼模型对人体运动进行计算机模拟研究”,该研究提供了

提出了一种由神经元系统和肌肉骨骼系统组成的三维全身结构模型,用于精确模拟人体行走运动。人体动力学由14个刚性连杆系统和60个肌肉模型表示


查看OpenSim项目(OpenSim.stanford.edu),该项目被生物力学界大量用于研究人体运动,例如临床应用。在OpenSim中,人体模型通常由肌肉驱动,而不仅仅是由关节处的扭矩驱动

class Simple
{
private:
    btScalar targetAngle;

    btCollisionShape* alphaCollisionShape;
    btCollisionShape* bravoCollisionShape;
    btRigidBody* alphaRigidBody;
    btRigidBody* bravoRigidBody;
    btHingeConstraint* hingeConstraint;

    btDynamicsWorld* dynamicsWorld;

public:
    ~Simple( void )
    {
    }

    btRigidBody* createRigidBody( btCollisionShape* collisionShape, 
                  btScalar mass, 
                  const btTransform& transform ) const
    {
    // calculate inertia
    btVector3 localInertia( 0.0f, 0.0f, 0.0f );
    collisionShape->calculateLocalInertia( mass, localInertia );    

    // create motion state
    btDefaultMotionState* defaultMotionState 
        = new btDefaultMotionState( transform );

    // create rigid body
    btRigidBody::btRigidBodyConstructionInfo rigidBodyConstructionInfo( 
        mass, defaultMotionState, collisionShape, localInertia );
    btRigidBody* rigidBody = new btRigidBody( rigidBodyConstructionInfo );      

    return rigidBody;
    }

    void Init( btDynamicsWorld* dynamicsWorld )
    {
    this->targetAngle = 0.0f;

    this->dynamicsWorld = dynamicsWorld;

    // create collision shapes
    const btVector3 alphaBoxHalfExtents( 0.5f, 0.5f, 0.5f );
    alphaCollisionShape = new btBoxShape( alphaBoxHalfExtents );

    //
    const btVector3 bravoBoxHalfExtents( 0.5f, 0.5f, 0.5f );
    bravoCollisionShape = new btBoxShape( bravoBoxHalfExtents );

    // create alpha rigid body
    const btScalar alphaMass = 10.0f;
    btTransform alphaTransform;
    alphaTransform.setIdentity();
    const btVector3 alphaOrigin( 54.0f, 0.5f, 50.0f );  
    alphaTransform.setOrigin( alphaOrigin );
    alphaRigidBody = createRigidBody( alphaCollisionShape, alphaMass, alphaTransform );
    dynamicsWorld->addRigidBody( alphaRigidBody );

    // create bravo rigid body
    const btScalar bravoMass = 1.0f;
    btTransform bravoTransform;
    bravoTransform.setIdentity();
    const btVector3 bravoOrigin( 56.0f, 0.5f, 50.0f );  
    bravoTransform.setOrigin( bravoOrigin );
    bravoRigidBody = createRigidBody( bravoCollisionShape, bravoMass, bravoTransform );
    dynamicsWorld->addRigidBody( bravoRigidBody );

    // create a constraint
    const btVector3 pivotInA( 1.0f, 0.0f, 0.0f );   
    const btVector3 pivotInB( -1.0f, 0.0f, 0.0f );
    btVector3 axisInA( 0.0f, 1.0f, 0.0f );
    btVector3 axisInB( 0.0f, 1.0f, 0.0f );
    bool useReferenceFrameA = false;
    hingeConstraint = new btHingeConstraint( 
        *alphaRigidBody,
        *bravoRigidBody,
        pivotInA,
        pivotInB,
        axisInA,
        axisInB,
        useReferenceFrameA );

    // set constraint limit
    const btScalar low = -M_PI;
    const btScalar high = M_PI;
    hingeConstraint->setLimit( low, high );

    // add constraint to the world
    const bool isDisableCollisionsBetweenLinkedBodies = false;
    dynamicsWorld->addConstraint( hingeConstraint, 
                      isDisableCollisionsBetweenLinkedBodies );
    }

    void Update( float deltaTime )
    {
    alphaRigidBody->activate();
    bravoRigidBody->activate();

    bool isEnableMotor = true;
    btScalar maxMotorImpulse = 1.0f; // 1.0f / 8.0f is about the minimum

    hingeConstraint->enableMotor( isEnableMotor );
    hingeConstraint->setMaxMotorImpulse( maxMotorImpulse );

    targetAngle += 0.1f * deltaTime;
    hingeConstraint->setMotorTarget( targetAngle, deltaTime );  
    }

};

OpenSim构建在Simbody多体动力学库之上。请看Simbody的例子,它将用一个人形机器人模型落地运行:。

关于Physics.SE的一些链接可能会有所帮助。我阅读了您发布的链接。问题是这篇文章只描述了一个布娃娃。当有东西击中碎布玩偶时,碎布玩偶会做出适当的反应,真实地摔倒。你想要的是一个能自己站立的布娃娃。你可以按照这篇文章来做,激活控制约束(关节)的马达。你的答案肯定很好。你在刚性关节约束方面有什么进展吗?@Uri,我一直在为关节添加电机。我一直在关注右肘和解决一系列问题,比如当关节超出极限时电机不工作。肘关节和马达现在工作得很好。接下来,我将把我学到的知识应用到身体的其他部位。我在一系列开发人员杂志上写我的工作。好的,期待看到结果!Goodluck这真是太棒了,有没有关于实际基线模型和肌肉模型的论文或类似的东西?我不确定你所说的基线模型是什么意思。有很多人体模型,也有很多肌肉模型。以下是肌肉骨骼模型的列表:。下面是对一种肌肉模型的描述:我明白了,从
JaredsDude.cpp
代码中是否可以明显看出使用了哪种肌肉模型?哦……我刚才发送给您的两个链接与OpenSim有关,而不是Simbody。我对JaredsDude.cpp中使用的肌肉模型一无所知。肌肉建模通常在OpenSim中完成,而不是Simbody。JaredsDude示例更像是一个玩具示例。