airsim物理
模拟方法
原始论文 https://microsoft.github.io/AirSim/paper/main.pdf
在airsim中四旋翼无人机根据各桨转速计算力矩,但被当做质点看待,计算整体的速度,加速度。
具体实现
物理参数设置
可在 AirLib\include\vehicles\multirotor\RotorParams.hpp 中设置螺旋桨各参数
可在 AirLib\include\vehicles\multirotor\MultiRotorParams.hpp\setupFrameGenericQuad 中设置无人机参数。
在simplefight下默认加载这个模型,就算换了模型还是按照这个函数中的参数加载,仿真中的参数与虚幻蓝图中参数设置没有任何关联,计算中的参数都按这个来。
更新无人机状态 :
1.假设不发生碰撞
// https://github.com/microsoft/AirSim/blob/main/AirLib/include/physics/FastPhysicsEngine.hpp#L315
avg_linear = current.twist.linear + current.accelerations.linear * (0.5f * dt_real);
avg_angular = current.twist.angular + current.accelerations.angular * (0.5f * dt_real);
const Wrench drag_wrench = getDragWrench(body, current.pose.orientation, avg_linear, avg_angular, wind);
next_wrench = body_wrench + drag_wrench;
// https://github.com/microsoft/AirSim/blob/main/AirLib/include/physics/FastPhysicsEngine.hpp#L412
next.pose.position = current_pose.position + avg_linear * dt_real;
2.检测碰撞
//if there is collision, see if we need collision response
const CollisionInfo collision_info = body.getCollisionInfo();
CollisionResponse& collision_response = body.getCollisionResponseInfo();
if (body.isGrounded() || (collision_info.has_collided && collision_response.collision_time_stamp != collision_info.time_stamp)) {
bool is_collision_response = getNextKinematicsOnCollision(dt, collision_info, body, current, next, next_wrench, enable_ground_lock_);
updateCollisionResponseInfo(collision_info, next, is_collision_response, collision_response);
}
3.碰撞处理
较复杂,见
https://github.com/microsoft/AirSim/blob/main/AirLib/include/physics/FastPhysicsEngine.hpp#L129
及 https://gafferongames.com/post/collision_response_and_coulomb_friction/
AirSim 中的 wind 模型
airsim中的wind模型与UE中的 winddirectionSOurce类关系不大,而是通过直接设置仿真物理引擎中的wind vector模拟。
//https://github.com/microsoft/AirSim/blob/main/AirLib/include/physics/FastPhysicsEngine.hpp#L325
const real_T air_density = body.getEnvironment().getState().air_density;
// Use relative velocity of the body wrt wind
const Vector3r relative_vel = linear_vel - wind_world;
const Vector3r linear_vel_body = VectorMath::transformToBodyFrame(relative_vel, orientation);