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