当前位置: 首页 > 科技观察

在Python中解释SpaceX如何进行火箭回收

时间:2023-03-18 11:46:58 科技观察

要了解有关非线性控制的更多信息,我一直在试验一种非常有效的方法,称为轨迹优化。一旦设置了基本代码,它就可以很容易地应用于各种系统。观看星舰SN15发射后,我决定进行一些动态计算,看看我的2D玩具sim是否可以执行翻转并自行着陆。令我兴奋的是,经过一些仔细的研究,它工作得很好。但真正令我惊讶的是,当我将输出与实际着陆镜头并排播放时:它完美地跟踪。并且我在编写整个程序和优化它时没有参考视频或其他明确的时序信息。我有两种可能性:1.我很幸运,2.SpaceX在他们的实际系统上运行非常相似的优化。这是一件非常有趣的事情,并希望打开一扇窗户,让我们了解火箭回收背后的魔力。在开始编写代码之前,最好解释一下轨迹优化的理论(但如果您愿意,也可以直接跳转到代码)。轨迹优化:“最优轨迹”是什么意思?“最好”在这种情况下意味着通常的意思:“好”、“最好”、“理想”等。作为一个简单的例子,假设你想穿过房间到达冰箱:你可以选择一个看似无限的数字路线,但不知何故只能选择其中一条。两条轨迹的例子应该很容易看出有好的和坏的路线,但是究竟什么定义了好的或坏的轨迹呢?这就是“成本”概念的用武之地。如果你有机器学习经验,它基本上是相同的概念。您运行优化以最小化成本函数。在我们的冰箱示例中,成本函数是什么?一个简单的方法是走我们的路。现在可以要求计算机找出你和冰箱之间的最短路径。选择成本函数这可行,但有一些微妙的缺点。想象一下你和冰箱之间的死亡陷阱。我们的“查找最小长度”算法将使您正确,我认为您可能认为这并不是真正的最佳选择。可能更好的成本函数(也是我在Starship着陆代码中最常使用的那个)是基于“努力”的。假设您在地板上向前迈出一步需要1点努力,而越过PitofDeath?则需要1000点努力。这更好地匹配了我们认为是最优的还是非最优的:约束很少有优化问题可以在没有很多约束的情况下完成,解决冰箱问题的是一些“逻辑”问题。附加信息这是轨迹优化的核心。通过在保持一组约束条件的同时最小化某些成本函数来优化点之间的轨迹。以下是一些更深入数学的重要资源:https://www.youtube.com/watch?v=wlkRYMVUZTs编写火箭着陆代码!现在进入有趣的东西。有一些很棒的库可以迭代方程式并进行优化工作,所以真正的“艺术”在于向解释器提出正确的问题。这里有一个collabnotebook的链接,可以让你在浏览器中运行整个代码:https://colab.research.google.com/drive/18MVtu4reVJLBE1RXByQEmu0O9aLXlMHz?usp=sharing跟踪时间被切成0.04秒每一步都会生成火箭状态和控制状态的块和变量。这导致路径上出现一堆离散点,在尝试为整个对象提出封闭形式的解决方案之前,这些点相对容易处理。由三个点和沿该轨迹的状态组成的轨迹的示例火箭状态向量:x[n]=[x,x_dot,y,y_dot,theta,theta_dot]控制状态向量:u[n]=[thrust_mag,thrust_angle]generation步骤和优化变量被选择为0.04s,因为它允许以每秒25帧的速度进行1:1回放。是的,我确实更改了模拟时间步长,因为25fps看起来不错。为了找到时间步长,我手动增加了时间步长,直到找到可行的解决方案。有多种方法可以让求解器自己找到最短的时间轨迹(主要是:让它确定点之间的时间步长)。成本函数设置成本函数所有成本都是平方和->cost[0]2+cost[1]2+cost[2]2...等等。最小化推力输出——理想情况下,您希望在着陆时使用少量燃料。最小化TVC的万向节角度-移动喷嘴很困难,理想情况下你希望它名义上指向下方。最小化角速度-看起来有点可笑,但我有一种预感,角速度/加速度给引擎带来了最大的压力,所以你想保持它尽可能低。约束集1:初始条件和最终条件初始条件是在空中以90m/s的速度向下旋转90度,然后开始向下飞行1000m。初始条件和最终条件约束起始高度和速度来自飞行俱乐部的SN9数据:https://flightclub.io/result/2d?id=1code=SN91ConstraintSet2:Dynamic每个状态时间步长必须遵守:x[n+1]-x[n]=f(x[n],u[n])*dt本质上,这是“不破坏物理”的约束。相当于火箭的离散时间模拟,下一状态等于当前状态+导数*dt。(注意:我在代码中使用x_dot()而不是f()因为我认为它更容易阅读)。为状态向量中的所有元素设置动态约束飞行常数和动态函数:g=9.8m=100000kg精度,我只是为了简单起见)长度=50米I=(1/12)*m*length2(均匀杆的惯性)定义f(x,u)=x_dot(注意:这是一个相当差的离散化,并且存在更好的方法,例如串联。但是,这是最简单和最快的编写方式)约束集3:可变范围推力不能超过Raptormax,油门不能低于40%,推力矢量不能在每个方向上摆动超过20度Raptormax取自维基百科,+-20度是一个总的猜测,我很想知道是否有更可靠的数据。设置你的有界约束优化!剩下要做的就是运行它!选择一个求解器并运行!基本上就是这样,你调用opti.solve(),它把它变成一个Ipopt(一个开源优化求解器)可以理解的问题。希望这条消息应该在很多迭代打印中得到底部:这是我们希望看到的状态和控制数组图代码的下一部分使用matplotlib制作了一个漂亮的动画,它需要一点时间来生成所有帧,但结果还是很不错的。总结虽然近乎完美的轨迹可能主要是我对事物的估计的运气问题,但仍有一些有趣的东西可以借鉴,主要是:Starship很可能会遵循预先计划的优化轨迹,或者实时运行动态生成最佳轨迹的优化。(或两者的混合)不仅如此,我们还可以进一步猜测他们的优化成本函数/“目标”与我们的非常相似:最小化推力、最小化TVC角和最小化角速度。轨道有时几乎是不可思议的,尤其是在双向滑动时。(我一直认为这是超调,但它可能只是达阵的最佳路径)。这也是一个有趣的分析工具,我真的很想找出导致SN8和SN9着陆失败的其他一些限制条件(需要一些调整:最终状态不再是严格的限制条件)。为什么实际着陆火箭比“哇,我刚刚弄清楚SpaceX如何着陆他们的火箭!!”要难得多,但遗憾的是,事实并非如此。一旦你生成了一条物理上可能的轨迹,将你带到你想去的地方,你需要做很多事情才能沿着这条轨迹实际移动:状态估计、闭环反馈控制、基于实际运动轨迹的动力学更新时间条件……以及许多真正的航空工程师都知道的东西。最重要的是,这些求解器需要很长时间才能运行,并且在线(实时)优化很难正确和安全地进行:一个错误的输入,您的求解器可能会发出“失败”的蜂鸣声,从而导致失败发生。下面是LarsBlackmore网站的链接,他是StarshipEDL的首席工程师,也是Falcon9着陆技术的负责人。他的论文和其他出版物更全面地概述了如何在EDL问题中使用最优控制。