1. 说明
在文章《服务端仿真引擎框架》中我构建了一个可通过http控制的后台仿真引擎,且支持多场景仿真,用的运行模式类似于mission的-rt模式,能够通过http控制初始化、启动、暂停、回放、停止、速度控制,并增加了fps控制能力。但mission的-fs模式并没有做支持,这也是有朋友在咨询怎么运行fs模式,以及fs模式下出现的问题。经过修改和测试后,将这个模式增加进去并解决相关的问题。注:需结合《服务端仿真引擎框架》文章来看,上一篇是基础框架,这篇是更新。
2. 介绍
用过mission的都知道,它支持-rt -fs和 -es模式,其中rt和fs都使用的是WsfFrameStepSimulation来实现的,只是通过SetRealTime为true或false来模拟实时帧步进还是非实时帧步进。这两种模式都是帧步进,区别是:当一帧内如果模型算法等计算完成了,rt模式会等待帧时间间隔到了,才会推进到下一帧;而fs模式则不会等待,立即执行下一帧,也就是说fs模式设置帧率是无效的。
经测试,原始的afsim如果设置为fs模式,是不能控制暂停的,这应该是afsim的一个bug,本文也来将其进行规避,大家可以查看关联的视频消息看看最终效果后再来看下面的实现思路。
3. 接口修改
之前的仿真创建的接口内容中,并没有带模式参数,这里进行增加RunType参数:

RunType = 0表示rt模式,1表示fs模式
然后修改HttpServer.cpp的解析函数,增加对RunType的解析:

上图HSimAppManager的createHSimApp也同步增加一个参数,并修改实现:

这里主要是通过HSimApp的实现来根据设置的RunType创建真正的对应的仿真对象:

上述则完成了RunType的设置。此时就可根据前端传入的RunType生成不同的Simulation对象,他们分别的运行效果如下视频:
上面暂停无效的问题,是因为在WsfFrameStepSimulation的WaitForAdvanceTime没有起到真正的作用,不像rt模式时会在下图的while中死循环,直到调用Resume后继续运行。fs模式只会在第一层else中执行,所以无法暂停:

所有应该能够想到,按照rt模式的思路,我们也在fs模式下在上图的else分支中添加一个死循环。
我这里的做法也是在尽量不修改afsim源代码的原则下来实现的,就是将此WaitForAdvanceTime的实现放到我们继承的HSimFrameStepSimulation中,并在else分支下添加while循环:

修改后再次运行,即可通过http控制fs模式的暂停和恢复了:
4. 手动帧推进
另外,我这里还增加了一个实现:通过设定的推进次数来推进,即可以实现单帧步进的效果。接口是在原来的控制协议基础上增加了ControlTyp枚举值7,通过Value来控制推进的次数:

这里实现就比较简单了,HttpServer接收的地方不要改,只需要在HSimApp的control函数实现中增加手动推进指定帧数的设置:

实际的设置逻辑是:暂停->设置帧数->恢复:

最后在AdvanceFrame实现的最后判断是否推进了指定的帧数,如果是则暂停即可:

以上就是在《服务端引擎框架》基础上完成的-fs模式增加,并支持单/多帧手动推进的功能。
PS:实际情况是,afsim在RunEvent中通过FrameStep的AdvanceFrame推进时,是在后台通过Clock来完成的。虽然提供了Pause方法来暂停推进,但由于线程处理逻辑关系,在外部发出的Pause请求是与RunEventLoop异步的,所以要等待线程切换后才能真正暂停,特别是-rt模式,然后经测试-fs模式,控制的推进次数比较准确。
5. Bug修复
在之前的版本中,指定路径的脚本启动文件设置后,程序的工作目录是在exe同级目录,并且会默认寻找exe同级目录下的output目录,如果找不到会报错。而在warlock中,他是在启动脚本所在目录创建的output目录,所以,这里进行修改保持与warlock相同的逻辑。主要在HSimApp中添加和修改以下代码:

QFileInfo fileInfo(file);
QString path = fileInfo.absolutePath();
QDir dir(path);
dir.mkdir("output"); // 在当前指定脚本目录创建output目录
dir.setCurrent(path); // 将公众目录切换到脚本所在目录。
m_options.mInputFiles.push_back(fileInfo.fileName().toStdString()); // 因为目录已切换,这里只需要文件名6. 接口修改
mission还有另外一种模式-es事件驱动模式,这个是另外一个类,后续有需要再更新。本文是基于之前的服务端仿真框架进行修改的,我已更新到网盘,同时还修复了上一篇的小Bug(停止时调用的Simulation方法修改为RequestTermination来更安全的退出仿真)也一并更新到了网盘,之前有购过此资源的朋友可直接从网盘下载,未购买过的朋友可通过下面的链接看看,也可以基于上一篇和这篇自行搭建。

往期推荐

评论