Skip to content

Commit

Permalink
Linux build working with Unreal 4.16
Browse files Browse the repository at this point in the history
  • Loading branch information
sytelus committed Jul 27, 2017
1 parent 2bf1180 commit 9d7ee76
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 19 deletions.
24 changes: 15 additions & 9 deletions AirLib/include/controllers/MavLinkDroneController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,12 +389,18 @@ struct MavLinkDroneController::impl {
for (auto iter = result.begin(); iter != result.end(); iter++)
{
mavlinkcom::SerialPortInfo info = *iter;
if (info.vid == pixhawkVendorId) {
if (info.pid == pixhawkFMUV4ProductId || info.pid == pixhawkFMUV2ProductId || info.pid == pixhawkFMUV2OldBootloaderProductId)
{
// printf("Auto Selecting COM port: %S\n", info.displayName.c_str());
return std::string(info.portName.begin(), info.portName.end());
}
if (
(
(info.vid == pixhawkVendorId) &&
(info.pid == pixhawkFMUV4ProductId || info.pid == pixhawkFMUV2ProductId || info.pid == pixhawkFMUV2OldBootloaderProductId)
) ||
(
(info.displayName.find(L"PX4_") != std::string::npos)
)
)
{
// printf("Auto Selecting COM port: %S\n", info.displayName.c_str());
return std::string(info.portName.begin(), info.portName.end());
}
}
return "";
Expand Down Expand Up @@ -457,16 +463,16 @@ struct MavLinkDroneController::impl {
if (port_name_auto == "" || port_name_auto == "*") {
port_name_auto = findPixhawk();
if (port_name_auto == "") {
throw std::domain_error("Could not find a connected PX4 flight controller");
throw std::domain_error("Could not detect a connected PX4 flight controller on any USB ports. You can specify USB port in settings.json.");
}
}

if (port_name_auto == "") {
throw std::invalid_argument("SerialPort setting has an invalid value.");
throw std::invalid_argument("USB port for PX4 flight controller is empty. Please set it in settings.json.");
}

if (baud_rate == 0) {
throw std::invalid_argument("SerialBaudRate has an invalid value");
throw std::invalid_argument("Baud rate specified in settings.json is 0 which is invalid");
}

connection_ = mavlinkcom::MavLinkConnection::connectSerial("hil", port_name_auto, baud_rate);
Expand Down
52 changes: 49 additions & 3 deletions MavLinkCom/src/impl/linux/MavLinkFindSerialPorts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,61 @@
#include "MavLinkConnection.hpp"
#include "Utils.hpp"

#include <cstdio>
#include <iostream>
#include <memory>
#include <sstream>
#include <locale>
#include <codecvt>

using namespace mavlinkcom;
using namespace mavlinkcom_impl;

std::vector<SerialPortInfo> MavLinkConnection::findSerialPorts(int vid, int pid)
{
unused(vid); // avoid warning: unused parameter
unused(pid); // avoid warning: unused parameter
// todo: not implemented on Linux yet... probably need to do an lstat on '/dev/serial/by-id' and find
// todo: alternative: probably need to do an lstat on '/dev/serial/by-id' and find
// something that looks like PX4 and return that name, or follow the symbolic link to /dev/ttyACM0...
std::vector<SerialPortInfo> result;
return result;

std::string bash_command =
"bash -c '"
"for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do "
"syspath=\"${sysdevpath%/dev}\"; devname=\"$(udevadm info -q name -p $syspath)\"; "
"[[ \"$devname\" == \"bus/\"* ]] && continue; "
"eval \"$(udevadm info -q property --export -p $syspath)\"; "
"[[ -z \"$ID_SERIAL\" ]] && continue; "
"echo \"/dev/$devname \"$ID_SERIAL\"\"; "
"done"
"'";

std::vector<SerialPortInfo> ports;
std::string command_result;
{
std::array<char, 128> buffer;
std::shared_ptr<FILE> pipe(popen(bash_command.c_str(), "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
command_result += buffer.data();
}
}

{
std::stringstream ss(command_result);
std::string port_name, display_name;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

while (std::getline(ss, port_name, ' ') && std::getline(ss, display_name)) {
SerialPortInfo portInfo;
portInfo.pid = 0;
portInfo.vid = 0;
portInfo.displayName = converter.from_bytes(display_name);
portInfo.portName = converter.from_bytes(port_name);

ports.push_back(portInfo);
}
}

return ports;
}
3 changes: 2 additions & 1 deletion MavLinkCom/src/serial_com/SerialPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ class SerialPort::serialport_impl
{
return -1;
}
setAttributes(baudRate, parity, dataBits, sb, hs, readTimeout, writeTimeout);
if (setAttributes(baudRate, parity, dataBits, sb, hs, readTimeout, writeTimeout) != 0)
return -1;

closed_ = false;
return 0;
Expand Down
3 changes: 1 addition & 2 deletions Unreal/Environments/Blocks/Blocks.uproject
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,5 @@
"Name": "AirSim",
"Enabled": true
}
],
"EngineAssociation": "4.16"
]
}
1 change: 1 addition & 0 deletions Unreal/Environments/Blocks/Config/DefaultEngine.ini
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ TriangleMeshTriangleMinAreaThreshold=5.000000
bEnableAsyncScene=False
bEnableShapeSharing=False
bEnablePCM=False
bEnableStabilization=False
bWarnMissingLocks=True
bEnable2DPhysics=False
LockedAxis=Invalid
Expand Down
3 changes: 2 additions & 1 deletion Unreal/Plugins/AirSim/Source/AirSimGameMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ void AAirSimGameMode::initializeSettings()

if (!file_found) {
std::string json_content;
//TODO: there is a crash in Linux due to settings.saveJSonString(). Remove this workaround after we know the reason.
//TODO: there is a crash in Linux due to settings.saveJSonString(). Remove this workaround after we only support Unreal 4.17
//https://answers.unrealengine.com/questions/664905/unreal-crashes-on-two-lines-of-extremely-simple-st.html
#ifdef _WIN32
json_content = settings.saveJSonString();
#else
Expand Down
6 changes: 3 additions & 3 deletions Unreal/Plugins/AirSim/Source/MultiRotorConnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ void MultiRotorConnector::beginPlay()

controller_->start();
}
catch (std::exception ex) {
catch (std::exception& ex) {

UAirBlueprintLib::LogMessage(FString("Vehicle controller cannot be started: "), FString(ex.what()), LogDebugLevel::Failure, 180);
UAirBlueprintLib::LogMessage("Tip: check settings.json: ", FString(ex.what()), LogDebugLevel::Failure, 180);
UAirBlueprintLib::LogMessage(FString("Vehicle controller cannot be started: "), FString(ex.what()), LogDebugLevel::Failure);
UAirBlueprintLib::LogMessage("Tip: check settings.json: ", FString(ex.what()), LogDebugLevel::Informational);
}
}

Expand Down
8 changes: 8 additions & 0 deletions docs/linux_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Our current recommanded and tested environment is **Ubuntu 16.04 LTS**. Theorati
## Install and Build
It's super simple 1-2-3!

**Note:** You can either use Unreal 4.16 or 4.17, but not the older versions. Both versions have some known issues. Please see FAQ later in this doc.

1. Make sure you are [registered with Epic Games](https://docs.unrealengine.com/latest/INT/Platforms/Linux/BeginnerLinuxDeveloper/SettingUpAnUnrealWorkflow/1/index.html). This is required so you can get Unreal engine's source code.
2. Clone Unreal in your favorite folder and run setup.sh (this may take a while!). Note: We only support Unreal 4.16 and newer.
```
Expand Down Expand Up @@ -47,6 +49,12 @@ You can also copy `clean.sh` from `AirSim/Unreal/Environments/Blocks` folder to

## FAQ

#### What are the known issues with Unreal 4.16?
One of the major issue is [this bug in Unreal](https://answers.unrealengine.com/questions/664905/unreal-crashes-on-two-lines-of-extremely-simple-st.html). We have done a workaround for some parts of the code but we haven't tested if everything is covered. Another known issue is that when clicking "End" button causes Unreal to crash. A final knowm issue is that report function (when you press `R` key), also causes crash because of above reasons.

#### What are the known issues with Unreal 4.17?
At the time of writing (July, 2017), version 4.17 is still in "preview" stage and is unstable. We have seen some rare but random crashes during startup. You might get warning that AirSim plugin is incompatible which you can ignore. Also, when clicking on "End" button freezes the Unreal Editor requiring to manual kill of its process.

#### Unreal crashed! How do I know what went wrong?
First go to folder `MyUnrealProject/Saved/Crashes` and then search directories for MyProject.log file. At the end of this file you will see stack trace and message. Also see `Diagnostics.txt` file.

Expand Down
3 changes: 3 additions & 0 deletions docs/sitl.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ out own copy of the [PX4 setup instructions](px4.md) which is a bit more concise

3. Get the PX4 source code and build the posix SITL version of PX4:
```
mkdir -p PX4
cd PX4
git clone https://github.com/PX4/Firmware.git
cd Firmware
git checkout tags/v1.5.5 -b v1.5.5
make posix_sitl_default
```
4. Use following command to start PX4 firmware in SITL mode:
Expand Down
45 changes: 45 additions & 0 deletions install_run_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#! /bin/bash

# get path of current script: https://stackoverflow.com/a/39340259/207661
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
pushd "$SCRIPT_DIR" >/dev/null

set -e
set -x

#confirm unreal install directory
UnrealDir=$1
if [[ !(-z "UnrealDir") ]]; then
UnrealDir="$SCRIPT_DIR/UnrealEngine"
fi

read -p "Unreal will be installed in $UnrealDir. To change it invoke script with path argument. Continue? " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
popd >/dev/null
exit 0
fi

#install unreal
if [[ !(-d "$UnrealDir") ]]; then
git clone -b 4.16 https://github.com/EpicGames/UnrealEngine.git "$UnrealDir"
pushd "$UnrealDir" >/dev/null

./Setup.sh
./GenerateProjectFiles.sh
make

popd >/dev/null
fi

#install airsim
./setup.sh
./build.sh

#start Unreal editor with Blocks project
pushd "$UnrealDir" >/dev/null
Engine/Binaries/Linux/UE4Editor "$SCRIPT_DIR/AirSim/Unreal/Environments/Blocks/Blocks.uproject" -game -log
popd >/dev/null

popd >/dev/null

0 comments on commit 9d7ee76

Please sign in to comment.