马可怪物';在C++;,汽车行为混乱 我试图在C++中采用马尔科姆怪兽的物理演示(文档和C参考代码:)。 我遇到了这样一个问题:汽车围绕自身旋转,并以不可预测的方式沿轴移动(因为它对输入做出反应,但不可预测)。在过去的4天里,我一直在努力寻找问题,但一无所获。请帮帮我,因为我已经绝望了。我已经将汽车的功能分为不同的类别(为了更好的维护),并推断问题发生在车轮类别和车内类别中。代码如下:

马可怪物';在C++;,汽车行为混乱 我试图在C++中采用马尔科姆怪兽的物理演示(文档和C参考代码:)。 我遇到了这样一个问题:汽车围绕自身旋转,并以不可预测的方式沿轴移动(因为它对输入做出反应,但不可预测)。在过去的4天里,我一直在努力寻找问题,但一无所获。请帮帮我,因为我已经绝望了。我已经将汽车的功能分为不同的类别(为了更好的维护),并推断问题发生在车轮类别和车内类别中。代码如下:,c++,c++11,game-physics,game-development,C++,C++11,Game Physics,Game Development,车轮.h Wheel.cpp Car.cpp void Car::更新(float&elapsedSec) { m_ElapsedSec=ElapsedSec; m_GearShifterInput=m_p此转向和踏板->GetCurrentGearValue(); m_vehiclethrottleinput=m_p此转向和踏板->获取当前油门值(m_ElapsedSec,m_vehiclethrottleinput); m_Vehicle转向角度输入=m_p此转向和踏板->获取当前转向值

车轮.h


Wheel.cpp


Car.cpp

void Car::更新(float&elapsedSec)
{
m_ElapsedSec=ElapsedSec;
m_GearShifterInput=m_p此转向和踏板->GetCurrentGearValue();
m_vehiclethrottleinput=m_p此转向和踏板->获取当前油门值(m_ElapsedSec,m_vehiclethrottleinput);
m_Vehicle转向角度输入=m_p此转向和踏板->获取当前转向值(m_ElapsedSec);
m_VehicleBrakeInput=m_p此转向和踏板->获取当前制动值(m_ElapsedSec);
m_NOSStatus=m_pthisSteering和踏板->GetIsNOSOnValue();
m_IsEBrakeOn=m_p此转向和踏板->获取IsebrakeonValue();
m_CSHeading=std::cosf(m_VehicleHeadingDirectionAngleRad);
m_SNHeading=std::sinf(m_VehicleHeadingDirectionAngleRad);
m_LocalVehicleLocity.x=m_CSHeading*m_WorldVehicleLocity.y+m_SNHeading*m_WorldVehicleLocity.x;
m_localvehicleLocity.y=-m_SNHeading*m_worldVehicleLocity.y+m_CSHeading*m_worldVehicleLocity.x;
m_p此传动系->设置值(m_NOSStatus、m_换档输入、m_VehicletHrottleInput、m_LocalVehicleLocity.Length());
m_传动系扭矩输出=m_pthis传动系->获取传动系输出(m_ElapsedSec);
m_pThisSuspension->设置值(m_VehicleLocalAcceleration,m_LocalVehicleLocity.Length());
m_FrontAxleLoad=m_pThisSuspension->GetFrontAxleWeight();
m_后轴负载=m_pthis悬架->获取后轴重量();
m_p此车轮->设置值(m_制动,m_传动系扭矩输出,m_车辆转向角度输入,m_车辆制动输入,m_前轴负载,
m_后轴负载、m_表面效率、m_车辆正常行驶速度、m_本地车辆行驶速度);
m_pThisWheel->Update();
m_WheelForces=m_pThisWheel->GetSumForce();
m_AngularTorque=m_pThisWheel->GetLateralTorque();
m_阻力力.x=-((m_滚动阻力*m_本地车辆等级.x)+(m_牵引效率*m_本地车辆等级.x*std::abs(m_本地车辆等级.x));
m_阻力力.y=-((m_滚动阻力*m_本地车辆等级.y)+(m_牵引效率*m_本地车辆等级.y*std::abs(m_本地车辆等级.y));
m_总力。x=m_车轮力。x+m_阻力。x;
m_TotalForce.y=m_车轮力。y+m_阻力力。y;
m_车辆局部加速。x=m_总力。x/m_卡马斯;
m_车辆局部加速。y=m_总力。y/m_卡马斯;
如果(m_WorldVehicleLocity.Length()<1.0f和m_VehicleLottleInput<0.5f)
{
m_localvehicleLocity.x=m_localvehicleLocity.y=0.f;
m_车辆角加速度=m_角度扭矩=m_角度加速度=0.f;
}
m_角度加速度=m_角度扭矩/m_惯性;
m_VehicleWorldAcceleration.x=m_CSHeading*m_VehicleLocalAcceleration.y+m_SNHeading*m_VehicleLocalAcceleration.x;
m_车辆世界加速度.y=-(m_SNHeading)*m_车辆局部加速度.y+m_CSHeading*m_车辆局部加速度.x;
m_WorldVehicleLevelocity.x+=m_ElapsedSec*m_VehicleWorldAcceleration.x;
m_WorldVehicleLocity.y+=m_ElapsedSec*m_VehicleWorldAcceleration.y;
m_WorldVehicleCoordinate.x+=m_ElapsedSec*m_WorldVehicleLocity.x;
m_WorldVehicleCoordinate.y+=m_ElapsedSec*m_WorldVehicleLocity.y;

std::cout由于汽车旋转,我查看了你对角速度的使用情况。
m_VehicleAngularVelocity
值在两个类中都没有初始化,因此它有一个不确定的值。它唯一设置值的时间是在你检查停下来的汽车时

不可预测的运动很可能是类似的问题

您应该初始化构造函数中的所有类成员以避免这些问题


为什么
Wheel::SetValues
通过引用获取其所有参数?因为它只是将它们复制到内部变量中,并且它们是基本类型,只需通过值传递它们即可。

感谢您指出这一点。我已经修复了
m_VehiclerAngularvelocity
的初始化,但这并没有完全解决问题。Af在进一步调查该问题后,我认为这与计算
m_Vehicle侧向力Front
m_Vehicle侧向力Rear
m_AngularTorque
的方式有关。尽管我不清楚到底是什么问题,以及如何解决它。
class Wheel
{

public:

    Wheel(const bool &isABSOn, const float &frontAxleToCG, const float &rearAxleToCG, const float &tireGripValue, const float &lockedTireGripCoef,
        const float &lateralStiffnessFront, const float &lateralStiffnessRear, const float &brakeForceCoef, const float &ebrakeForceCoef,
        const float &brakeTorque);

    void SetValues(bool &isEbrakeOn, float &drivetrainTorque, float &steeringAngle, float &brakingInput,
        float &frontAxleLoad, float &rearAxleLoad, float &surfaceCoefficient, float &angularVelocity, Vector2f &localVelocity);

    void Update();

    Vector2f GetSumForce();
    float GetLateralTorque();


private:

    bool m_IsEBrakeOn;
    const bool m_IsABSOn;

    float m_YawSpeed, m_VehicleAngularVelocity, m_VehicleRotationAngle, m_VehicleSideSlip, m_VehicleSlipAngleFrontAxle, m_VehicleSlipAngleRearAxle,
        m_VehicleSteeringAngleRadInput,
        m_SurfaceTypeGripCoefficient, m_DrivetrainTorqueNm, m_BrakingForceInputPercentage, m_FrontAxleLoad, m_RearAxleLoad;

    const float m_CGtoFrontAxle, m_CGtoRearAxle, m_BaseTireGripValue, m_LockedTireGripCoefficent, m_LateralStiffnessFront,
        m_LateralStiffnessRear, m_BreakForceCoefficent, m_EBrakeForceCoefficent, m_BrakeTorqueLimit, m_StableSpeedBoundary;

    Vector2f m_LocalVehicleVelocity, m_VehicleLateralForceFront, m_VehicleLateralForceRear, m_VehicleLongtitudonalForceRear;

    float FrontTireGripValue();
    float RearTireGripValue();
    float CombinedBrakingForceValueRearAxle();

};
Wheel::Wheel(const bool &isABSOn, const float &frontAxleToCG, const float &rearAxleToCG, const float &tireGripValue, const float &lockedTireGripCoef,
const float &lateralStiffnessFront, const float &lateralStiffnessRear, const float &brakeForceCoef, const float &ebrakeForceCoef,
const float &brakeTorque)
: m_IsABSOn{ isABSOn }
, m_CGtoFrontAxle{ frontAxleToCG }
, m_CGtoRearAxle{ rearAxleToCG }
, m_BaseTireGripValue{ tireGripValue }
, m_LockedTireGripCoefficent{ lockedTireGripCoef }
, m_LateralStiffnessFront { lateralStiffnessFront }
, m_LateralStiffnessRear{ lateralStiffnessRear }
, m_BreakForceCoefficent{ brakeForceCoef }
, m_EBrakeForceCoefficent{ ebrakeForceCoef }
, m_BrakeTorqueLimit{ brakeTorque }
, m_StableSpeedBoundary{ 40.f } {}

   void Wheel::Update()
{
    if ((-0.01f < m_LocalVehicleVelocity.x) || (m_LocalVehicleVelocity.x < 0.01f))
    {
        m_YawSpeed = 0.f;
    }
    else
    {
        m_YawSpeed = ((m_CGtoFrontAxle + m_CGtoRearAxle) / 2.f) * m_VehicleAngularVelocity;
    }

    if ((-0.01f < m_LocalVehicleVelocity.x) || (m_LocalVehicleVelocity.x < 0.01f))
    {
        m_VehicleRotationAngle = 0.f;
    }
    else
    {
        m_VehicleRotationAngle = std::atan2(m_YawSpeed, m_LocalVehicleVelocity.x);
    }

    if ((-0.01f < m_LocalVehicleVelocity.x) || (m_LocalVehicleVelocity.x < 0.01f))
    {
        m_VehicleSideSlip = 0.f;
    }
    else
    {
        m_VehicleSideSlip = std::atan2(m_LocalVehicleVelocity.y, m_LocalVehicleVelocity.x);
    }

    m_VehicleSlipAngleFrontAxle = m_VehicleSideSlip + m_VehicleRotationAngle - m_VehicleSteeringAngleRadInput;
    m_VehicleSlipAngleRearAxle = m_VehicleSideSlip - m_VehicleRotationAngle;

    m_VehicleLateralForceFront.x = 0.f;
    m_VehicleLateralForceFront.y = m_LateralStiffnessFront * m_VehicleSlipAngleFrontAxle;
    m_VehicleLateralForceFront.y = std::fminf(FrontTireGripValue(), m_VehicleLateralForceFront.y);
    m_VehicleLateralForceFront.y = std::fmaxf(-FrontTireGripValue(), m_VehicleLateralForceFront.y);
    m_VehicleLateralForceFront.y *= m_FrontAxleLoad;

    m_VehicleLateralForceRear.x = 0.f;
    m_VehicleLateralForceRear.y = m_LateralStiffnessRear * m_VehicleSlipAngleRearAxle;
    m_VehicleLateralForceRear.y = std::fminf(RearTireGripValue(), m_VehicleLateralForceRear.y);
    m_VehicleLateralForceRear.y = std::fmaxf(-RearTireGripValue(), m_VehicleLateralForceRear.y);
    m_VehicleLateralForceRear.y *= m_RearAxleLoad;

    m_VehicleLongtitudonalForceRear.x = m_SurfaceTypeGripCoefficient * (m_DrivetrainTorqueNm - (CombinedBrakingForceValueRearAxle() * utils::Sign(m_LocalVehicleVelocity.x)));
    m_VehicleLongtitudonalForceRear.y = 0.f;
}

Vector2f Wheel::GetSumForce()
{
    if (m_LocalVehicleVelocity.Length() < 1.0f && m_DrivetrainTorqueNm < 0.5f)
    {
        m_LocalVehicleVelocity.x = m_LocalVehicleVelocity.y = 0.f;
        m_VehicleLateralForceFront.x = m_VehicleLateralForceFront.y = m_VehicleLateralForceRear.x = m_VehicleLateralForceRear.y = 0.f;
    }

    return Vector2f
    {
        m_VehicleLongtitudonalForceRear.x + std::sinf(m_VehicleSteeringAngleRadInput) * m_VehicleLateralForceFront.x + m_VehicleLateralForceRear.x,
        m_VehicleLongtitudonalForceRear.y + std::cosf(m_VehicleSteeringAngleRadInput) * m_VehicleLateralForceFront.y + m_VehicleLateralForceRear.y
    };
}

float Wheel::GetLateralTorque()
{
    return m_CGtoFrontAxle * m_VehicleLateralForceFront.y - m_CGtoRearAxle * m_VehicleLateralForceRear.y;
}

void  Wheel::SetValues(bool &isEbrakeOn, float &drivetrainTorque, float &steeringAngle, float &brakingInput,
    float &frontAxleLoad, float &rearAxleLoad, float &surfaceCoefficient, float &angularVelocity, Vector2f &localVelocity)
{
    m_IsEBrakeOn = isEbrakeOn;
    m_DrivetrainTorqueNm = drivetrainTorque;
    m_VehicleSteeringAngleRadInput = steeringAngle;
    m_BrakingForceInputPercentage = brakingInput;
    m_FrontAxleLoad = frontAxleLoad;
    m_RearAxleLoad = rearAxleLoad;
    m_SurfaceTypeGripCoefficient = surfaceCoefficient;
    m_LocalVehicleVelocity = localVelocity;
    m_VehicleAngularVelocity = angularVelocity;
}

float Wheel::CombinedBrakingForceValueRearAxle()
{
    return (m_BrakeTorqueLimit * m_BrakingForceInputPercentage);
}

float Wheel::FrontTireGripValue()
{
    return m_BaseTireGripValue * m_SurfaceTypeGripCoefficient;
}

float Wheel::RearTireGripValue()
{
    if ((CombinedBrakingForceValueRearAxle() > m_DrivetrainTorqueNm) && (!m_IsABSOn) && (m_LocalVehicleVelocity.Length() > m_StableSpeedBoundary))
    {
        return m_BaseTireGripValue * m_LockedTireGripCoefficent * m_SurfaceTypeGripCoefficient;
    }
    else
    {
        return m_BaseTireGripValue * m_SurfaceTypeGripCoefficient;
    }
}
class Car
{

public:

    Car(VehicleCfg *pVehicleSpecs);

    InputControl *m_pThisSteeringAndPedals;

    void Draw() const;
    void Update(float &elapsedSec);

private:

    bool m_NOSStatus, m_IsEBrakeOn;

    int m_GearShifterInput;

    float m_VehicleThrottleInpute, m_VehicleSteeringAngleRadInput, m_VehicleBrakeInput, 
        m_DrivetrainTorqueOutput, m_FrontAxleLoad, m_RearAxleLoad,
        m_ElapsedSec, m_VehicleHeadingDirectionAngleRad, m_CSHeading, m_SNHeading,
        m_VehicleRotationAngle, m_YawSpeed, m_VehicleAngularVelocity, m_VehicleSideSlip,
        m_VehicleSlipAngleFrontAxle, m_VehicleSlipAngleRearAxle,
        m_SurfaceCoefficent, m_AngularTorque, m_AngularAcceleration, m_VehicleHealthStatus;

    const float m_FrontToCG, m_RearToCG, m_CarMass, m_Inertia, m_RollingResistance, m_DragCoefficient;

    Point2f m_WorldVehicleCoordinate;

    Vector2f m_LocalVehicleVelocity, m_WorldVehicleVelocity, m_VehicleLocalAcceleration, m_VehicleWorldAcceleration,
        m_WheelForces, m_ResistanceForces, m_TotalForce;

    Suspension *m_pThisSuspension;
    Drivetrain *m_pThisDrivetrain;  
    Wheel *m_pThisWheel;
    ModularRenderer *m_pThisVehicleDrawn;

};
void Car::Update(float &elapsedSec)
{
    m_ElapsedSec = elapsedSec;

    m_GearShifterInput = m_pThisSteeringAndPedals->GetCurrentGearValue();
    m_VehicleThrottleInpute = m_pThisSteeringAndPedals->GetCurrentThrottleValue(m_ElapsedSec, m_VehicleThrottleInpute);
    m_VehicleSteeringAngleRadInput = m_pThisSteeringAndPedals->GetCurrentSteeringValue(m_ElapsedSec);
    m_VehicleBrakeInput = m_pThisSteeringAndPedals->GetCurrrentBrakeValue(m_ElapsedSec);
    m_NOSStatus = m_pThisSteeringAndPedals->GetIsNOSOnValue();
    m_IsEBrakeOn = m_pThisSteeringAndPedals->GetIsEBrakeOnValue();

    m_CSHeading = std::cosf(m_VehicleHeadingDirectionAngleRad);
    m_SNHeading = std::sinf(m_VehicleHeadingDirectionAngleRad);

    m_LocalVehicleVelocity.x = m_CSHeading * m_WorldVehicleVelocity.y + m_SNHeading * m_WorldVehicleVelocity.x;
    m_LocalVehicleVelocity.y = -m_SNHeading * m_WorldVehicleVelocity.y + m_CSHeading * m_WorldVehicleVelocity.x;

    m_pThisDrivetrain->SetValues(m_NOSStatus, m_GearShifterInput, m_VehicleThrottleInpute, m_LocalVehicleVelocity.Length());
    m_DrivetrainTorqueOutput = m_pThisDrivetrain->GetDrivetrainOutput(m_ElapsedSec);

    m_pThisSuspension->SetValues(m_VehicleLocalAcceleration, m_LocalVehicleVelocity.Length());
    m_FrontAxleLoad = m_pThisSuspension->GetFrontAxleWeight();
    m_RearAxleLoad = m_pThisSuspension->GetRearAxleWeight();


    m_pThisWheel->SetValues(m_IsEBrakeOn, m_DrivetrainTorqueOutput, m_VehicleSteeringAngleRadInput, m_VehicleBrakeInput, m_FrontAxleLoad,
        m_RearAxleLoad, m_SurfaceCoefficent, m_VehicleAngularVelocity, m_LocalVehicleVelocity);
    m_pThisWheel->Update();
    m_WheelForces = m_pThisWheel->GetSumForce();
    m_AngularTorque = m_pThisWheel->GetLateralTorque();

    m_ResistanceForces.x = -((m_RollingResistance * m_LocalVehicleVelocity.x) + (m_DragCoefficient * m_LocalVehicleVelocity.x * std::abs(m_LocalVehicleVelocity.x)));
    m_ResistanceForces.y = -((m_RollingResistance * m_LocalVehicleVelocity.y) + (m_DragCoefficient * m_LocalVehicleVelocity.y * std::abs(m_LocalVehicleVelocity.y)));

    m_TotalForce.x = m_WheelForces.x + m_ResistanceForces.x;
    m_TotalForce.y = m_WheelForces.y + m_ResistanceForces.y;

    m_VehicleLocalAcceleration.x = m_TotalForce.x / m_CarMass;
    m_VehicleLocalAcceleration.y = m_TotalForce.y / m_CarMass;

    if (m_WorldVehicleVelocity.Length() < 1.0f && m_VehicleThrottleInpute < 0.5f)
    {
        m_LocalVehicleVelocity.x = m_LocalVehicleVelocity.y = 0.f;
        m_VehicleAngularVelocity = m_AngularTorque = m_AngularAcceleration = 0.f;
    }

    m_AngularAcceleration = m_AngularTorque / m_Inertia;

    m_VehicleWorldAcceleration.x = m_CSHeading * m_VehicleLocalAcceleration.y + m_SNHeading * m_VehicleLocalAcceleration.x;
    m_VehicleWorldAcceleration.y = -(m_SNHeading) * m_VehicleLocalAcceleration.y + m_CSHeading * m_VehicleLocalAcceleration.x;

    m_WorldVehicleVelocity.x += m_ElapsedSec * m_VehicleWorldAcceleration.x;
    m_WorldVehicleVelocity.y += m_ElapsedSec * m_VehicleWorldAcceleration.y;

    m_WorldVehicleCoordinate.x += m_ElapsedSec * m_WorldVehicleVelocity.x;
    m_WorldVehicleCoordinate.y += m_ElapsedSec * m_WorldVehicleVelocity.y;

    std::cout << "m_WorldVehicleCoordinate: " << m_WorldVehicleCoordinate.x << ", " << m_WorldVehicleCoordinate.y << "\n";

    m_VehicleAngularVelocity += m_ElapsedSec * m_AngularAcceleration;

    m_VehicleHeadingDirectionAngleRad += m_ElapsedSec * m_VehicleAngularVelocity;

    m_pThisVehicleDrawn->SetVariables(int(0), int(0), int(0), int(0), m_VehicleHeadingDirectionAngleRad, m_VehicleSteeringAngleRadInput, m_WorldVehicleCoordinate);

}

void Car::Draw() const
{
    m_pThisVehicleDrawn->DrawTheVehicle();
}