Skip to content

Commit

Permalink
Support for Logitech G920 whel, physics tuning for car
Browse files Browse the repository at this point in the history
  • Loading branch information
sytelus committed Dec 1, 2017
1 parent 0293441 commit 39aae01
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 46 deletions.
Binary file not shown.
4 changes: 2 additions & 2 deletions Unreal/Plugins/AirSim/AirSim.uplugin
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FileVersion" : 3,
"Version" : "1.1.5",
"VersionName": "1.1.5",
"Version" : "1.1.7",
"VersionName": "1.1.7",
"FriendlyName": "AirSim",
"Description": "AirSim - Autonomous Aerial Vehicles Simulator Plugin",
"Category" : "Science",
Expand Down
94 changes: 71 additions & 23 deletions Unreal/Plugins/AirSim/Source/Car/CarPawn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,10 @@ void ACarPawn::NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other,
HitNormal, NormalImpulse, Hit);
}

void ACarPawn::initializeForBeginPlay(bool enable_rpc, const std::string& api_server_address, bool engine_sound)
void ACarPawn::initializeForBeginPlay(bool enable_rpc, const std::string& api_server_address, bool engine_sound, int remote_control_id)
{
remote_control_id_ = remote_control_id;

if (engine_sound)
EngineSoundComponent->Activate();
else
Expand Down Expand Up @@ -209,17 +211,25 @@ void ACarPawn::initializeForBeginPlay(bool enable_rpc, const std::string& api_se

startApiServer(enable_rpc, api_server_address);

//TODO: should do reset() here?
keyboard_controls_ = joystick_controls_ = CarPawnApi::CarControls();

//joystick
joystick_.getJoyStickState(0, joystick_state_);
if (joystick_state_.is_initialized)
UAirBlueprintLib::LogMessageString("RC Controller on USB: ", joystick_state_.pid_vid, LogDebugLevel::Informational);
else
UAirBlueprintLib::LogMessageString("RC Controller on USB not detected: ",
std::to_string(joystick_state_.connection_error_code), LogDebugLevel::Informational);
if (remote_control_id_ >= 0) {
joystick_.getJoyStickState(remote_control_id_, joystick_state_);
if (joystick_state_.is_initialized)
UAirBlueprintLib::LogMessageString("RC Controller on USB: ", joystick_state_.pid_vid == "" ?
"(Detected)" : joystick_state_.pid_vid, LogDebugLevel::Informational);
else
UAirBlueprintLib::LogMessageString("RC Controller on USB not detected: ",
std::to_string(joystick_state_.connection_error_code), LogDebugLevel::Informational);
}

}

void ACarPawn::reset(bool disable_api_control)
{
keyboard_controls_ = joystick_controls_ = CarPawnApi::CarControls();
api_->reset();

if (disable_api_control)
Expand Down Expand Up @@ -385,22 +395,7 @@ void ACarPawn::Tick(float Delta)
{
Super::Tick(Delta);

const msr::airlib::CarApiBase::CarControls* current_controls = &keyboard_controls_;
if (!api_->isApiControlEnabled()) {
UAirBlueprintLib::LogMessageString("Control Mode: ", "Keyboard", LogDebugLevel::Informational);
api_->setCarControls(keyboard_controls_);
}
else {
UAirBlueprintLib::LogMessageString("Control Mode: ", "API", LogDebugLevel::Informational);
current_controls = & api_->getCarControls();
}
UAirBlueprintLib::LogMessageString("Accel: ", std::to_string(current_controls->throttle), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Break: ", std::to_string(current_controls->brake), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Steering: ", std::to_string(current_controls->steering), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Handbreak: ", std::to_string(current_controls->handbrake), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Target Gear: ", std::to_string(current_controls->manual_gear), LogDebugLevel::Informational);


updateCarControls();

updateKinematics(Delta);

Expand All @@ -420,6 +415,57 @@ void ACarPawn::Tick(float Delta)
getVehiclePawnWrapper()->setLogLine(getLogString());
}

void ACarPawn::updateCarControls()
{
const msr::airlib::CarApiBase::CarControls* current_controls = nullptr;
if (remote_control_id_ >= 0 && joystick_state_.is_initialized) {
joystick_.getJoyStickState(0, joystick_state_);

if ((joystick_state_.buttons & 4) | (joystick_state_.buttons & 1024)) { //X button or Start button
reset();
return;
}

joystick_controls_.steering = joystick_state_.left_y * 1.25;
joystick_controls_.throttle = (-joystick_state_.right_x + 1) / 2;
joystick_controls_.brake = -joystick_state_.right_z + 1;

//Two steel levers behind wheel
joystick_controls_.handbrake = (joystick_state_.buttons & 32) | (joystick_state_.buttons & 64) ? 1 : 0;

if ((joystick_state_.buttons & 256) | (joystick_state_.buttons & 2)) { //RSB button or B button
joystick_controls_.manual_gear = -1;
joystick_controls_.is_manual_gear = true;
joystick_controls_.gear_immediate = true;
}
else if ((joystick_state_.buttons & 512) | (joystick_state_.buttons & 1)) { //LSB button or A button
joystick_controls_.manual_gear = 0;
joystick_controls_.is_manual_gear = false;
joystick_controls_.gear_immediate = true;
}

UAirBlueprintLib::LogMessageString("Control Mode: ", "Wheel/Joystick", LogDebugLevel::Informational);
current_controls = &joystick_controls_;
}
else {
UAirBlueprintLib::LogMessageString("Control Mode: ", "Keyboard", LogDebugLevel::Informational);
current_controls = &keyboard_controls_;
}

if (!api_->isApiControlEnabled()) {
api_->setCarControls(* current_controls);
}
else {
UAirBlueprintLib::LogMessageString("Control Mode: ", "API", LogDebugLevel::Informational);
current_controls = & api_->getCarControls();
}
UAirBlueprintLib::LogMessageString("Accel: ", std::to_string(current_controls->throttle), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Break: ", std::to_string(current_controls->brake), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Steering: ", std::to_string(current_controls->steering), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Handbreak: ", std::to_string(current_controls->handbrake), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessageString("Target Gear: ", std::to_string(current_controls->manual_gear), LogDebugLevel::Informational);
}

void ACarPawn::BeginPlay()
{
Super::BeginPlay();
Expand Down Expand Up @@ -450,6 +496,8 @@ void ACarPawn::UpdateHUDStrings()

UAirBlueprintLib::LogMessage(TEXT("Speed: "), SpeedDisplayString.ToString(), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessage(TEXT("Gear: "), GearDisplayString.ToString(), LogDebugLevel::Informational);
UAirBlueprintLib::LogMessage(TEXT("RPM: "), FText::AsNumber(GetVehicleMovement()->GetEngineRotationSpeed()).ToString(), LogDebugLevel::Informational);


}

Expand Down
7 changes: 6 additions & 1 deletion Unreal/Plugins/AirSim/Source/Car/CarPawn.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class ACarPawn : public AWheeledVehicle
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

VehiclePawnWrapper* getVehiclePawnWrapper();
void initializeForBeginPlay(bool enable_rpc, const std::string& api_server_address, bool engine_sound);
void initializeForBeginPlay(bool enable_rpc, const std::string& api_server_address, bool engine_sound, int remoteControlID);

virtual void NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation,
FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) override;
Expand Down Expand Up @@ -131,6 +131,8 @@ class ACarPawn : public AWheeledVehicle
void stopApiServer();
bool isApiServerStarted();
void updateKinematics(float delta);
void updateCarControls();

std::string getLogString();

/* Are we on a 'slippery' surface */
Expand All @@ -157,6 +159,9 @@ class ACarPawn : public AWheeledVehicle
msr::airlib::Kinematics::State kinematics_;

CarPawnApi::CarControls keyboard_controls_;
CarPawnApi::CarControls joystick_controls_;

int remote_control_id_ = -1;

SimJoyStick joystick_;
SimJoyStick::State joystick_state_;
Expand Down
5 changes: 5 additions & 0 deletions Unreal/Plugins/AirSim/Source/Car/CarPawnApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,14 @@ CarApiBase::CarState CarPawnApi::getCarState()

void CarPawnApi::reset()
{
last_controls_ = CarControls();
UAirBlueprintLib::RunCommandOnGameThread([this]() {
pawn_->reset();
//movement_->ResetMoveState();
//movement_->SetActive(false);
//movement_->SetActive(true, true);
setCarControls(CarControls());

}, true);
}

Expand Down
22 changes: 18 additions & 4 deletions Unreal/Plugins/AirSim/Source/Car/SimModeCar.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "SimModeCar.h"
#include "ConstructorHelpers.h"
#include "AirBlueprintLib.h"
#include "controllers/Settings.hpp"
#include "Car/CarPawn.h"

ASimModeCar::ASimModeCar()
Expand Down Expand Up @@ -111,13 +112,14 @@ void ASimModeCar::setupVehiclesAndCamera(std::vector<VehiclePtr>& vehicles)
//initialize each vehicle pawn we found
TVehiclePawn* vehicle_pawn = static_cast<TVehiclePawn*>(pawn);
vehicles.push_back(vehicle_pawn);
vehicle_pawn->initializeForBeginPlay(enable_rpc, api_server_address, engine_sound);

//chose first pawn as FPV if none is designated as FPV
VehiclePawnWrapper* wrapper = vehicle_pawn->getVehiclePawnWrapper();
vehicle_pawn->initializeForBeginPlay(enable_rpc, api_server_address, engine_sound, getRemoteControlID(*wrapper));

if (enable_collision_passthrough)
wrapper->config.enable_passthrough_on_collisions = true;
if (wrapper->config.is_fpv_vehicle || fpv_vehicle_pawn_wrapper_ == nullptr)
wrapper->getConfig().enable_passthrough_on_collisions = true;
if (wrapper->getConfig().is_fpv_vehicle || fpv_vehicle_pawn_wrapper_ == nullptr)
fpv_vehicle_pawn_wrapper_ = wrapper;
}
}
Expand All @@ -126,6 +128,18 @@ void ASimModeCar::setupVehiclesAndCamera(std::vector<VehiclePtr>& vehicles)
}


int ASimModeCar::getRemoteControlID(const VehiclePawnWrapper& pawn)
{
//find out which RC we should use
msr::airlib::Settings settings;
msr::airlib::Settings::singleton().getChild(pawn.getConfig().vehicle_config_name == "" ? default_vehicle_config
: pawn.getConfig().vehicle_config_name, settings);

msr::airlib::Settings rc_settings;
settings.getChild("RC", rc_settings);
return rc_settings.getInt("RemoteControlID", -1);
}

void ASimModeCar::createVehicles(std::vector<VehiclePtr>& vehicles)
{
//find vehicles and cameras available in environment
Expand Down Expand Up @@ -168,7 +182,7 @@ void ASimModeCar::updateReport()
for (VehiclePtr vehicle : vehicles_) {
VehiclePawnWrapper* wrapper = vehicle->getVehiclePawnWrapper();
msr::airlib::StateReporter& reporter = * report_wrapper_.getReporter();
std::string vehicle_name = std::string(TCHAR_TO_UTF8(* wrapper->config.vehicle_config_name));
std::string vehicle_name = wrapper->getConfig().vehicle_config_name;

reporter.writeHeading(std::string("Vehicle: ").append(
vehicle_name == "" ? "(default)" : vehicle_name));
Expand Down
2 changes: 2 additions & 0 deletions Unreal/Plugins/AirSim/Source/Car/SimModeCar.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class AIRSIM_API ASimModeCar : public ASimModeBase
private:
void setupVehiclesAndCamera(std::vector<VehiclePtr>& vehicles);
void updateReport();
int getRemoteControlID(const VehiclePawnWrapper& pawn);


private:
UClass* external_camera_class_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ void ASimModeWorldMultiRotor::setupVehiclesAndCamera(std::vector<VehiclePtr>& ve
//chose first pawn as FPV if none is designated as FPV
VehiclePawnWrapper* wrapper = vehicle_pawn->getVehiclePawnWrapper();
if (enable_collision_passthrough)
wrapper->config.enable_passthrough_on_collisions = true;
if (wrapper->config.is_fpv_vehicle || fpv_vehicle_pawn_wrapper_ == nullptr)
wrapper->getConfig().enable_passthrough_on_collisions = true;
if (wrapper->getConfig().is_fpv_vehicle || fpv_vehicle_pawn_wrapper_ == nullptr)
fpv_vehicle_pawn_wrapper_ = wrapper;

//now create the connector for each pawn
Expand Down Expand Up @@ -189,8 +189,8 @@ void ASimModeWorldMultiRotor::createVehicles(std::vector<VehiclePtr>& vehicles)
ASimModeWorldBase::VehiclePtr ASimModeWorldMultiRotor::createVehicle(VehiclePawnWrapper* wrapper)
{
auto vehicle_params = MultiRotorParamsFactory::createConfig(
wrapper->config.vehicle_config_name == "" ? default_vehicle_config
: std::string(TCHAR_TO_UTF8(*wrapper->config.vehicle_config_name)));
wrapper->getConfig().vehicle_config_name == "" ? default_vehicle_config
: wrapper->getConfig().vehicle_config_name);

vehicle_params_.push_back(std::move(vehicle_params));

Expand Down
2 changes: 1 addition & 1 deletion Unreal/Plugins/AirSim/Source/SimMode/SimModeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void ASimModeBase::readSettings()
if (simmode_name == "Multirotor")
default_vehicle_config = "SimpleFlight";
else if (simmode_name == "Car")
default_vehicle_config = "PhysXCar4x4";
default_vehicle_config = "PhysXCar";
else
UAirBlueprintLib::LogMessageString("SimMode is not valid: ", simmode_name, LogDebugLevel::Failure);
}
Expand Down
17 changes: 15 additions & 2 deletions Unreal/Plugins/AirSim/Source/VehiclePawnWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,11 @@ void VehiclePawnWrapper::setKinematics(const msr::airlib::Kinematics::State* kin
kinematics_ = kinematics;
}

void VehiclePawnWrapper::initialize(APawn* pawn, const std::vector<APIPCamera*>& cameras)
void VehiclePawnWrapper::initialize(APawn* pawn, const std::vector<APIPCamera*>& cameras, const WrapperConfig& config)
{
pawn_ = pawn;
cameras_ = cameras;
config_ = config;

for (auto camera : cameras_) {
camera_connectors_.push_back(std::unique_ptr<VehicleCameraConnector>(new VehicleCameraConnector(camera)));
Expand Down Expand Up @@ -153,6 +154,15 @@ void VehiclePawnWrapper::initialize(APawn* pawn, const std::vector<APIPCamera*>&
setupCamerasFromSettings();
}

VehiclePawnWrapper::WrapperConfig& VehiclePawnWrapper::getConfig()
{
return config_;
}

const VehiclePawnWrapper::WrapperConfig& VehiclePawnWrapper::getConfig() const
{
return config_;
}

APIPCamera* VehiclePawnWrapper::getCamera(int index)
{
Expand All @@ -176,7 +186,10 @@ int VehiclePawnWrapper::getCameraCount()
void VehiclePawnWrapper::reset()
{
state_ = initial_state_;

//if (pawn_->GetRootPrimitiveComponent()->IsAnySimulatingPhysics()) {
// pawn_->GetRootPrimitiveComponent()->SetSimulatePhysics(false);
// pawn_->GetRootPrimitiveComponent()->SetSimulatePhysics(true);
//}
pawn_->SetActorLocationAndRotation(state_.start_location, state_.start_rotation, false, nullptr, ETeleportType::TeleportPhysics);

//TODO: delete below
Expand Down
9 changes: 6 additions & 3 deletions Unreal/Plugins/AirSim/Source/VehiclePawnWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ class VehiclePawnWrapper
public:
struct WrapperConfig {
bool is_fpv_vehicle = false;
FString vehicle_config_name = ""; //use the default config name
std::string vehicle_config_name = ""; //use the default config name
bool enable_collisions = true;
bool enable_passthrough_on_collisions = false;
float home_lattitude = 47.641468;
float home_longitude = -122.140165;
float home_altitude = 122;
bool enable_trace = false;
} config;
};

void toggleTrace();

public: //interface
VehiclePawnWrapper();
void initialize(APawn* pawn, const std::vector<APIPCamera*>& cameras);
void initialize(APawn* pawn, const std::vector<APIPCamera*>& cameras, const WrapperConfig& config = WrapperConfig());

void reset();
void onCollision(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp,
Expand Down Expand Up @@ -70,6 +70,8 @@ class VehiclePawnWrapper

void printLogMessage(const std::string& message, std::string message_param = "", unsigned char severity = 0);

WrapperConfig& getConfig();
const WrapperConfig& getConfig() const;

protected:
UPROPERTY(VisibleAnywhere)
Expand All @@ -95,6 +97,7 @@ class VehiclePawnWrapper
std::vector<std::unique_ptr<VehicleCameraConnector>> camera_connectors_;
const msr::airlib::Kinematics::State* kinematics_;
std::string log_line_;
WrapperConfig config_;

struct State {
FVector start_location;
Expand Down
8 changes: 4 additions & 4 deletions build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ IF %ERRORLEVEL% NEQ 0 (

REM //---------- get High PolyCount SUV Car Model ------------
IF NOT EXIST Unreal\Plugins\AirSim\Content\VehicleAdv mkdir Unreal\Plugins\AirSim\Content\VehicleAdv
IF NOT EXIST Unreal\Plugins\AirSim\Content\VehicleAdv\SUV\v1.1.4 (
IF NOT EXIST Unreal\Plugins\AirSim\Content\VehicleAdv\SUV\v1.1.7 (
IF NOT DEFINED noFullPolyCar (
REM //leave some blank lines because powershell shows download banner at top of console
ECHO(
Expand All @@ -38,9 +38,9 @@ IF NOT EXIST Unreal\Plugins\AirSim\Content\VehicleAdv\SUV\v1.1.4 (
IF EXIST suv_download_tmp rmdir suv_download_tmp /q /s
mkdir suv_download_tmp
@echo on
REM powershell -command "& { Start-BitsTransfer -Source https://github.com/Microsoft/AirSim/releases/download/v1.1.4/car_assets.zip -Destination suv_download_tmp\car_assets.zip }"
REM powershell -command "& { (New-Object System.Net.WebClient).DownloadFile('https://github.com/Microsoft/AirSim/releases/download/v1.1.4/car_assets.zip', 'suv_download_tmp\car_assets.zip') }"
powershell -command "& { iwr https://github.com/Microsoft/AirSim/releases/download/v1.1.4/car_assets.zip -OutFile suv_download_tmp\car_assets.zip }"
REM powershell -command "& { Start-BitsTransfer -Source https://github.com/Microsoft/AirSim/releases/download/v1.1.7/car_assets.zip -Destination suv_download_tmp\car_assets.zip }"
REM powershell -command "& { (New-Object System.Net.WebClient).DownloadFile('https://github.com/Microsoft/AirSim/releases/download/v1.1.7/car_assets.zip', 'suv_download_tmp\car_assets.zip') }"
powershell -command "& { iwr https://github.com/Microsoft/AirSim/releases/download/v1.1.7/car_assets.zip -OutFile suv_download_tmp\car_assets.zip }"
@echo off
rmdir /S /Q Unreal\Plugins\AirSim\Content\VehicleAdv\SUV
powershell -command "& { Expand-Archive -Path suv_download_tmp\car_assets.zip -DestinationPath Unreal\Plugins\AirSim\Content\VehicleAdv }"
Expand Down
Loading

0 comments on commit 39aae01

Please sign in to comment.