2D比例制导(Proportional Guidance)实现:导弹转向过缓无法拦截目标
我正在用Processing实现比例制导(Proportional Guidance)来创建导弹类,要求每帧更新时接收目标位置并执行拦截。导弹需要沿自身朝向加速,模拟火箭发动机向前推进的效果,制导算法要像真实导弹的稳定翼那样控制转向。
之前试过一些简单算法但效果不好,所以选择了比例制导(仅为视觉效果,不接受其他算法推荐,除非效果完全类似)。现在的问题是导弹能转向目标,但速度太慢,没法完成拦截。我参考了相关资料实现了当前代码。
主循环
Missile missile; Target target; void setup() { fullScreen(); missile = new Missile(); target = new Target(); } void draw() { background(0); target.Update(); missile.Update(target); }
目标类
class Target { PVector Location = new PVector(); PVector Velocity = new PVector(); PVector Acceleration = new PVector(); float Speed = 100; float DeltaT = 0.0166; Target() { Location.set(width - 15,height - 15); Velocity.set(-Speed * DeltaT,0); Acceleration.set(0,0); } void Update() { Location.add(Velocity); Draw(); } void Draw() { stroke(255,0,0); fill(255,0,0); ellipse(Location.x,Location.y,10,10); } }
导弹类
class Missile { PVector LocationC = new PVector(); // 当前位置 PVector LocationP = new PVector(); // 上一帧位置 PVector Velocity = new PVector(); PVector Acceleration = new PVector(); PVector TargetLocC = new PVector(0,0); // 当前目标位置 PVector TargetLocP = new PVector(0,0); // 上一帧目标位置 PVector TargetVelC = new PVector(0,0); // 当前目标速度 PVector TargetVelP = new PVector(0,0); // 上一帧目标速度 PVector RTM_C = new PVector(); // 当前指向目标的向量 PVector RTM_P = new PVector(); // 上一帧指向目标的向量 PVector LOS_Delta = new PVector(); float LOS_Rate = 0; float VC = 0; // 接近速度 float N = 5; // 导航增益 float DeltaT = 0.0166; PVector Commanded_Accel = new PVector(0,0.1); Missile() { LocationC.set(width/2,10); Velocity.set(0,0.1); Acceleration.set(0,0.1); } void Update(Target target) { UpdateCurrentValues(target); ProportionalGuidence(); UpdatePreviousValues(); Draw(); //println(degrees(Velocity.heading())); } void ProportionalGuidence() { // 获取上一帧和当前帧的导弹-目标距离向量 RTM_P = TargetLocP.copy().sub(LocationP.copy()); RTM_C = TargetLocC.copy().sub(LocationC.copy()); // 归一化目标向量 RTM_P.normalize(); RTM_C.normalize(); // 计算视线变化率 LOS_Delta = RTM_C.copy().sub(RTM_P.copy()); if(frameCount > 1) { PVector crossProduct = RTM_P.cross(RTM_C); LOS_Rate = crossProduct.z/(RTM_P.mag() * RTM_C.mag()); } else { LOS_Rate = 0; } // 计算接近速度 VC = RTM_C.mag()-RTM_P.mag(); // 计算加速度 Commanded_Accel = RTM_C.mult(N * VC * LOS_Rate + (0.5*N)); Acceleration = Commanded_Accel.mult(DeltaT); } void UpdateCurrentValues(Target target) { Velocity.add(Acceleration); LocationC.add(Velocity); TargetLocC = target.Location; TargetVelC = target.Velocity; } void UpdatePreviousValues() { LocationP = LocationC.copy(); TargetLocP = TargetLocC.copy(); TargetVelP = TargetVelC.copy(); } void Draw() { stroke(255); fill(255); ellipse(LocationC.x, LocationC.y,5,5); } }
内容的提问来源于stack exchange,提问作者Stephan
相关产品推荐
相关产品推荐

