一、概述
在官方实现的AirSim中有一个Block的工程可以通过MavLink协议遥控无人机的飞行,但是Block的场景比较单调,缺少真实性。所以可以更换不同的场景来运行AirSim
原来的Block场景:
更换后的场景:
二、下载场景
-
在【虚幻商城】中找到自己喜欢的场景,然后下载到一个目录下面,记得路径不能有中文,否则会编译出错。
-
双击*.uptoject打开
点击菜单【文件】-》【生产Visual Studio 2019项目】
-
CarGame根目录下面也就是CarGame.uproject同一级目录新建文件夹Plugins
-
把下载的D:\002_UE4\AirSim-1.5.0-windows\Unreal\Environments\Blocks\Plugins下的AirSim复制到CarGame/Plugins下面
-
使用文本编辑器打开CarGame.uproject添加AirSim插件模块
{
"FileVersion": 3,
"EngineAssociation": "4.26",
"Category": "Samples",
"Description": "",
"Modules": [
{
"Name": "VehicleGame",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "VehicleGameLoadingScreen",
"Type": "Runtime",
"LoadingPhase": "PreLoadingScreen"
}
],
"Plugins": [
{
"Name": "PhysXVehicles",
"Enabled": true
},
{
"Name": "RawInput",
"Enabled": true
},
{
"Name": "AirSim",
"Enabled": true
}
],
"TargetPlatforms": [
"MacNoEditor",
"WindowsNoEditor"
],
"EpicSampleNameHash": "2902796019"
}
- 右键点击CarGame.uproject ->Generate Visual Studio project files
- 双击打开【CarGame.sln】就可以看到AirSim已经添加到工程中了。
三.配置编译
- 在工程目录下新建一个项目命名:SelfDemo(自定义的实例),添加一个空的MainCpp.cpp文件。
把AirSim-1.5.0-windows\HelloSpawnedDrones\HelloSpawnedDrones.cpp,中的内容全部复制过来。
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "common/common_utils/StrictMode.hpp"
STRICT_MODE_OFF
#ifndef RPCLIB_MSGPACK
#define RPCLIB_MSGPACK clmdep_msgpack
#endif // !RPCLIB_MSGPACK
#include "rpc/rpc_error.h"
STRICT_MODE_ON
#include "vehicles/multirotor/api/MultirotorRpcLibClient.hpp"
#include "common/common_utils/FileSystem.hpp"
#include <iostream>
#include <chrono>
#include <cstdlib>
#include <thread>
void runSingleClient(uint16_t port, int ordinal)
{
using namespace msr::airlib;
const char host[] = "localhost";
float timeout_s = 60;
try
{
MultirotorRpcLibClient *client = new MultirotorRpcLibClient(host, port, timeout_s);
std::cout << "Confirming connections..." << std::endl;
client->confirmConnection();
std::string vehicle_name = "UAV_" + std::to_string(ordinal);
std::cout << "Vehicle name:" << vehicle_name << std::endl;
Pose pose(Vector3r(0, 5.0f * (ordinal + 1), 0), Quaternionr(0, 0, 0, 0));
client->simAddVehicle(vehicle_name, "simpleflight", pose, "");
// This is a bit crude, but give it a moment to settle on the ground, else takeoff will fail
std::this_thread::sleep_for(std::chrono::duration<double>(2));
// moveByVelocityZ is an offboard operation, so we need to set offboard mode.
client->enableApiControl(true, vehicle_name);
client->armDisarm(true, vehicle_name);
auto ground_pos = client->getMultirotorState(vehicle_name).getPosition();
float groundZ = ground_pos.z(); // current position (NED coordinate system).
float takeoff_timeout = 5;
std::cout << "Initiating takeoff for " << vehicle_name << "..." << std::endl;
client->takeoffAsync(takeoff_timeout, vehicle_name)->waitOnLastTask();
std::cout << "Completed takeoff for " << vehicle_name << "..." << std::endl;
const float speed = 3.0f;
// switch to explicit hover mode so that this is the fallback when
// move* commands are finished.
std::cout << "Initiating hover for " << vehicle_name << "..." << std::endl;
client->hoverAsync(vehicle_name)->waitOnLastTask();
std::cout << "Completed hover for " << vehicle_name << "..." << std::endl;
auto position = client->getMultirotorState(vehicle_name).getPosition();
float duration = 1;
float z = position.z(); // current position (NED coordinate system).
// Altitude difference between each platform, in meters
const float altitude_delta = 1.0f;
z -= ordinal * altitude_delta;
float timeout = 10.0f;
client->moveToZAsync(z, speed, timeout, YawMode(), -1.0f, 1.0f, vehicle_name)->waitOnLastTask();
std::cout << "Completed move to z " << z << " for " << vehicle_name << "..." << std::endl;
std::cout << "Flying in a 10m box pattern at 3 m/s velocity" << std::endl;
const float size = 5.0f;
duration = size / speed;
DrivetrainType drivetrain = DrivetrainType::ForwardOnly;
YawMode yaw_mode(true, 0);
position = client->getMultirotorState(vehicle_name).getPosition();
std::cout << "Position of " << port << ": " << position << std::endl;
z = position.z(); // current position (NED coordinate system).
std::cout << "moveByVelocityZ(" << speed << ", 0, " << z << "," << duration << ")" << std::endl;
client->moveByVelocityZAsync(speed, 0, z, duration, drivetrain, yaw_mode, vehicle_name);
std::this_thread::sleep_for(std::chrono::duration<double>(duration));
std::cout << "moveByVelocityZ(0, " << speed << "," << z << "," << duration << ")" << std::endl;
client->moveByVelocityZAsync(0, speed, z, duration, drivetrain, yaw_mode, vehicle_name);
std::this_thread::sleep_for(std::chrono::duration<double>(duration));
std::cout << "moveByVelocityZ(" << -speed << ", 0, " << z << "," << duration << ")" << std::endl;
client->moveByVelocityZAsync(-speed, 0, z, duration, drivetrain, yaw_mode, vehicle_name);
std::this_thread::sleep_for(std::chrono::duration<double>(duration));
std::cout << "moveByVelocityZ(0, " << -speed << "," << z << "," << duration << ")" << std::endl;
client->moveByVelocityZAsync(0, -speed, z, duration, drivetrain, yaw_mode, vehicle_name);
std::this_thread::sleep_for(std::chrono::duration<double>(duration));
client->moveToZAsync(groundZ - 0.5f, speed, timeout, YawMode(), -1.0f, 1.0f, vehicle_name)->waitOnLastTask();
std::cout << "Hovering..." << std::endl;
client->hoverAsync(vehicle_name)->waitOnLastTask();
client->enableApiControl(true, vehicle_name);
std::cout << "Landing..." << std::endl;
client->landAsync(timeout, vehicle_name)->waitOnLastTask();
std::this_thread::sleep_for(std::chrono::duration<double>(5));
std::cout << "Disarming..." << std::endl;
client->armDisarm(false, vehicle_name);
std::cout << "Done!..." << std::endl;
delete client;
std::this_thread::sleep_for(std::chrono::duration<double>(50));
}
catch (rpc::rpc_error& e)
{
std::string msg = e.get_error().as<std::string>();
std::cout << "Exception raised by the API, something went wrong." << std::endl << msg << std::endl;
}
}
int main(int argc, char *argv[])
{
using namespace msr::airlib;
uint16_t rpc_port = 41451;
int num_platforms = 1;
std::cout << "argc is " << argc << std::endl;
if (argc > 1)
{
std::cout << "Num plats string: " << argv[1] << std::endl;
num_platforms = static_cast<uint16_t>(std::stoi(argv[1]));
}
std::cout << "First port is " << rpc_port << std::endl;
std::cout << "Num platforms: " << num_platforms << std::endl;
std::cout << "Making clients..." << std::endl;
try
{
std::cout << "Press Enter to begin..." << std::endl;
std::cin.get();
std::vector<std::thread> clientThreads;
// Count down, so the first one can easily go the highest (without knowing count)
int client_ordinal = num_platforms - 1;
for (int i = 0; i < num_platforms; i++)
{
clientThreads.push_back(std::thread(runSingleClient, rpc_port, client_ordinal));
client_ordinal--;
std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
}
for (auto &toJoin : clientThreads)
{
toJoin.join();
}
}
catch (rpc::rpc_error& e)
{
std::string msg = e.get_error().as<std::string>();
std::cout << "Exception raised by the API, something went wrong." << std::endl << msg << std::endl;
}
return 0;
}
-
选择配置项,注意:一定要选Debug x64
-
配置包含目录
-
配置附加库目录
-
添加附加依赖项
如果配置正确的话,一次就会编译成功!
四、运行CarGame
编译CarGame
如果电脑配置不高的话,可能需要一段时间。编译完成以后按【Ctrl+F5】运行,发现弹出以下对话框。
解决办法:打开ue->【文件】-》【烘焙Windows的内容】
经过一段较长时间的运行,完成以后,
设置游戏模式,在【世界场景设置】-》游戏模式重载:AirSimGameMode
使用【独立进场游戏】运行
弹出对话框选择载具【是】汽车【否】无人机,我们选择无人机。
然后运行【SelfDemo】选中项目【SelfDemo】按【Ctrl+F5】运行。点击【回车】就可以运行无人机了
aaa