flightgear中实现双机控制(本地)

需求

在flightgear中实现控制两个飞行器


一、Fg中双飞行器的显示

1.使用fg提供的multiplay接口

在FlightGear中,Multiplay是用于支持多人联机游戏的接口。通过Multiplay接口,玩家可以连接到FlightGear的多人游戏服务器,与其他玩家一起飞行,进行飞行比赛或共同探索虚拟世界。

Multiplay接口允许玩家在游戏中进行实时通信、位置更新、飞行数据传输等操作。玩家可以使用诸如FGNet、FlightGear模拟器内建的Multiplay功能或其他连接工具来连接到Multiplay服务器。

2.在本地双开fg实例并配置multipaly接口实现两个实例的通信

格式为 --muliplay = 方向 (输入还是输出), 频率 ,ip地址(这里为本地地址) ,端口 

--multiplay=out,10,127.0.0.1,5000 
--multiplay=in,10,127.0.0.1,5001

3.使用bat脚本用于两个fg实例的初始化

实例1:(aircraft可自定义)

C:
cd C:\Program Files\FlightGear 2020.3
SET FG_ROOT=C:\Program Files\FlightGear 2020.3\data\
SET FG_SCENERY=C:\Program Files\FlightGear 2020.3\data\Scenery
.\bin\fgfs --aircraft=falcon9 --fdm=ufo --altitude=80 --generic=socket,in,10,127.0.0.1,5507,udp,test  --airport=KSFO  --start-date-lat=2004:06:01:09:00:00 --callsign=FG1 --multiplay=out,10,127.0.0.1,5000 --multiplay=in,10,127.0.0.1,5001

实例2:

C:
cd C:\Program Files\FlightGear 2020.3
SET FG_ROOT=C:\Program Files\FlightGear 2020.3\data\
SET FG_SCENERY=C:\Program Files\FlightGear 2020.3\data\Scenery
.\bin\fgfs --aircraft=HL20 --fdm=ufo --altitude=100 --generic=socket,in,10,127.0.0.1,5508,udp,test  --airport=KSFO  --start-date-lat=2004:06:01:09:00:00 --callsign=FG2 --multiplay=out,10,127.0.0.1,5001 --multiplay=in,10,127.0.0.1,5000 

4.运行两个脚本

即可看到双机显示

二、控制飞行器

1.配置通信xml文件

进入到protocol文件夹下

新建test.xml文件

这里配置了飞行器的部分参数用于测试通信。

该协议使用二进制通信。

<?xml version="1.0"?>

<PropertyList>
	<generic>
		<input>
			<binary_mode>true</binary_mode>
			<binary_footer>none</binary_footer>
			<byte_order>host</byte_order>
			<record_length>24</record_length>


	         <chunk>
                 <name>altitude</name>
                 <type>double</type>
                 <node>/position/altitude-ft</node>
             </chunk>

            
             <chunk>
                  <name>throttle</name>
                  <type>double</type>
                  <node>/controls/engines/engine[0]/throttle</node>
             </chunk>

             <chunk>
                  <name>elevator</name>
                  <type>double</type>
                  <node>/controls/flight/elevator</node>
             </chunk>

        </input>
	</generic>
</PropertyList>
在初始化fg时需配置
 --generic=socket,in,10,127.0.0.1,5507,udp,test向fg说明使用test自定义协议,udp报文通信。

2.使用C++编写接口实现控制

项目结构

代码:

udpsender.h

#ifndef UDPSENDER_H
#define UDPSENDER_H
#include <QHostAddress>
#include <QUdpSocket>
#include <QByteArray>
#include <QVector>
#include <QAbstractSocket>
#include <QTimer>


class UdpSender: public QObject
{
    Q_OBJECT

public:
    UdpSender(QObject *parent = 0);
    void send();

private:
    QUdpSocket *udpSocketSend1;
    QUdpSocket *udpSocketSend2;
    QTimer *timer;
    QVector<double> vec1 = {
            80,   // high
            0,  // throttle
            -1  // elevator
        };

     QVector<double> vec2 = {
            35,   // high
            0,  // throttle
            0   // elevator
        };

};

#endif // UDPSENDER_H

udpsender.cpp

#include "udpsender.h"
#include <iostream>

UdpSender::UdpSender(QObject *parent) : QObject(parent)
{
    udpSocketSend1 = new QUdpSocket(this);
    udpSocketSend2 = new QUdpSocket(this);

    udpSocketSend1->bind(QHostAddress::LocalHost, 5507);
    udpSocketSend2->bind(QHostAddress::LocalHost, 5508);

    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &UdpSender::send);
    timer->start(10); // 每10毫秒发送一次
}

void UdpSender::send()
{
    vec1[0] += 0.1;
    vec2[0] += 0.1;
    QByteArray datagram1 = QByteArray::fromRawData(
        reinterpret_cast<const char*>(vec1.constData()),
        sizeof(double) * vec1.size()
    );

    QByteArray datagram2 = QByteArray::fromRawData(
        reinterpret_cast<const char*>(vec2.constData()),
        sizeof(double) * vec2.size()
    );

    udpSocketSend1->writeDatagram(datagram1, QHostAddress::LocalHost, 5507);
    udpSocketSend2->writeDatagram(datagram2, QHostAddress::LocalHost, 5508);
}

main.cpp

#include <iostream>
#include <QGuiApplication>
#include "udpsender.h"

using namespace std;

int main(int argc, char *argv[])
{

    QGuiApplication app(argc, argv);
    UdpSender udpSender;
    udpSender.send();

    return app.exec();
}
最终效果

cd C:\Program Files\FlightGear fgfs --fg-root=C:\Program Files\FlightGear\data --aircraft=ufo --in-air --fdm=null --telnet=5501 --telnet=5502 --telnet=5503 --disable-ai-traffic --disable-real-weather-fetch --disable-random-objects --disable-terrasync --disable-clouds --disable-sound --disable-panel --disable-hud --disable-specular-highlight --timeofday=noon --prop:/sim/rendering/multi-sample-buffers=1 --prop:/sim/rendering/multi-samples=2 --prop:/sim/rendering/draw-mask-clouds=false --prop:/sim/rendering/draw-mask-terrain=true --prop:/sim/rendering/draw-mask-objects=true --prop:/sim/rendering/draw-mask-lights=true --prop:/sim/rendering/draw-mask-internal=true --prop:/sim/rendering/draw-mask-cockpit=true --prop:/sim/rendering/draw-mask-effects=true --prop:/sim/rendering/draw-mask-overlay=true --prop:/sim/rendering/draw-mask-world=true --prop:/sim/rendering/draw-mask-panel=true --prop:/sim/rendering/draw-mask-vr=true --prop:/sim/rendering/draw-mask-2d=true --prop:/sim/rendering/draw-mask-3d=true --prop:/sim/rendering/draw-mask-sky=true --prop:/sim/rendering/draw-mask-shadows=true --prop:/sim/rendering/draw-mask-cabin=true --prop:/sim/rendering/draw-mask-weather=true --prop:/sim/rendering/draw-mask-stereo=true --prop:/sim/rendering/draw-mask-internal-cockpit=true --prop:/sim/rendering/draw-mask-internal-windows=true --prop:/sim/rendering/draw-mask-internal-instruments=true --prop:/sim/rendering/draw-mask-internal-overlay=true --prop:/sim/rendering/draw-mask-internal-effects=true --prop:/sim/rendering/draw-mask-internal-lights=true --prop:/sim/rendering/draw-mask-internal-world=true --prop:/sim/rendering/draw-mask-internal-panel=true --prop:/sim/rendering/draw-mask-internal-3d=true --prop:/sim/rendering/draw-mask-internal-sky=true --prop:/sim/rendering/draw-mask-internal-cabin=true --prop:/sim/rendering/draw-mask-internal-weather=true --prop:/sim/rendering/draw-mask-internal-stereo=true --prop:/sim/rendering/draw-mask-internal-shadow=true --prop:/sim/rendering/draw-mask-internal-stall=true --prop:/sim/rendering/draw-mask-internal-aoa=true --prop:/sim/rendering/draw-mask-internal-thermal=false --prop:/sim/rendering/draw-mask-internal-ice=false --prop:/sim/rendering/draw-mask-internal-glass=true --prop:/sim/rendering/draw-mask-internal-dead=true --prop:/sim/rendering/draw-mask-internal-reflection=true --telnet=127.0.0.1:5501 --disable-panel --disable-hud --disable-specular-highlight --disable-clouds --disable-sound --timeofday=noon --enable-hud-3d=no --enable-hud-2d=yes --enable-panel=no --enable-sound=no程序显示错误
05-10
这个命令有些问题。你需要在命令行输入这个命令,并且将其的双引号去掉。此外,你需要确保FlightGear已经安装在C:\Program Files\FlightGear目录下,并且你已经选择了一个可用的飞行器(例如: ufo)。最后,如果你需要使用telnet,你需要指定不同的端口。以下是更正后的命令: ``` cd C:\Program Files\FlightGear fgfs --fg-root=C:\Program Files\FlightGear\data --aircraft=ufo --in-air --fdm=null --telnet=5501 --telnet=5502 --telnet=5503 --disable-ai-traffic --disable-real-weather-fetch --disable-random-objects --disable-terrasync --disable-clouds --disable-sound --disable-panel --disable-hud --disable-specular-highlight --timeofday=noon --prop:/sim/rendering/multi-sample-buffers=1 --prop:/sim/rendering/multi-samples=2 --prop:/sim/rendering/draw-mask-clouds=false --prop:/sim/rendering/draw-mask-terrain=true --prop:/sim/rendering/draw-mask-objects=true --prop:/sim/rendering/draw-mask-lights=true --prop:/sim/rendering/draw-mask-internal=true --prop:/sim/rendering/draw-mask-cockpit=true --prop:/sim/rendering/draw-mask-effects=true --prop:/sim/rendering/draw-mask-overlay=true --prop:/sim/rendering/draw-mask-world=true --prop:/sim/rendering/draw-mask-panel=true --prop:/sim/rendering/draw-mask-vr=true --prop:/sim/rendering/draw-mask-2d=true --prop:/sim/rendering/draw-mask-3d=true --prop:/sim/rendering/draw-mask-sky=true --prop:/sim/rendering/draw-mask-shadows=true --prop:/sim/rendering/draw-mask-cabin=true --prop:/sim/rendering/draw-mask-weather=true --prop:/sim/rendering/draw-mask-stereo=true --prop:/sim/rendering/draw-mask-internal-cockpit=true --prop:/sim/rendering/draw-mask-internal-windows=true --prop:/sim/rendering/draw-mask-internal-instruments=true --prop:/sim/rendering/draw-mask-internal-overlay=true --prop:/sim/rendering/draw-mask-internal-effects=true --prop:/sim/rendering/draw-mask-internal-lights=true --prop:/sim/rendering/draw-mask-internal-world=true --prop:/sim/rendering/draw-mask-internal-panel=true --prop:/sim/rendering/draw-mask-internal-3d=true --prop:/sim/rendering/draw-mask-internal-sky=true --prop:/sim/rendering/draw-mask-internal-cabin=true --prop:/sim/rendering/draw-mask-internal-weather=true --prop:/sim/rendering/draw-mask-internal-stereo=true --prop:/sim/rendering/draw-mask-internal-shadow=true --prop:/sim/rendering/draw-mask-internal-stall=true --prop:/sim/rendering/draw-mask-internal-aoa=true --prop:/sim/rendering/draw-mask-internal-thermal=false --prop:/sim/rendering/draw-mask-internal-ice=false --prop:/sim/rendering/draw-mask-internal-glass=true --prop:/sim/rendering/draw-mask-internal-dead=true --prop:/sim/rendering/draw-mask-internal-reflection=true ``` 请注意,如果你需要使用telnet连接到FlightGear,你需要在另一个命令行窗口输入telnet命令,例如: ``` telnet localhost 5501 ``` 这将连接到FlightGear的第一个telnet端口。如果你想连接到其他端口,你需要相应地更改端口号。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值