Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argument --settings is ineffective for Release v1.3.1-linux Blocks environment #3195

Closed
wangwwno1 opened this issue Dec 8, 2020 · 11 comments · Fixed by #4416
Closed

Argument --settings is ineffective for Release v1.3.1-linux Blocks environment #3195

wangwwno1 opened this issue Dec 8, 2020 · 11 comments · Fixed by #4416

Comments

@wangwwno1
Copy link
Contributor

wangwwno1 commented Dec 8, 2020

OS: Ubuntu 18.04
AirSim: v1.3.1-linux(release)
Python: 3.8.4
Unreal Engine: 4.24.3

This doc said I can specify customized settings.json through argument --settings or -s. However, this argument seems ineffective for the Blocks environment downloaded from the same releases page.

How to replicate:

  • navigate to the Blocks package folder
  • run ./Blocks.sh --settings '{"SimMode": "Multirotor"}' in the terminal console

Result: Pop-up "Choose Vehicle"window that ask to use car or quadcopter
Expect: No pop-up window

Edit: This issue disappeared after:

  • pull the master branch
  • rebuild and package the Blocks environment
  • use pexpect.spawn to send arguments instead of the terminal console in ubuntu

Here is my python code with pexpect.spawn

import airsim
import pexpect

s = '{"SimMode": "Multirotor"}'
task = pexpect.spawn(f"/home/$USER/path/to/Blocks.sh --settings {s}", encoding="utf-8")
while line.find("LogLoad: (Engine Initialization)") == -1:
     line = task.readline()
client = airsim.MultirotorClient()
print(client.confirmConnection())

The resuslt would be:

Connected!
Client Ver:1 (Min Req: 1), Server Ver:1 (Min Req: 1)

I'm not sure the root of this problem, maybe there is something wrong in the terminal console.

Edit: Passing settings as argument to pexpect.spawn, however, is ineffective

# The setting will be ineffective
task = pexpect.spawn(f"/home/$USER/path/to/Blocks.sh", args=["--settings", s], encoding="utf-8")
@wangwwno1 wangwwno1 changed the title Argument --settings is ineffective for v1.3.1-release-linux Blocks environment Argument --settings is ineffective for Release v1.3.1-linux Blocks environment Dec 8, 2020
@ahmed-elsaharti
Copy link
Contributor

Hi @wangwwno1 , the feature was introduced in #2668 which was merged a couple of months after the 1.3.1 release. If you clone the latest repo and compile the binary through the included Blocks development environment this would probably work.

@wangwwno1
Copy link
Contributor Author

Hi @wangwwno1 , the feature was introduced in #2668 which was merged a couple of months after the 1.3.1 release. If you clone the latest repo and compile the binary through the included Blocks development environment this would probably work.

Thanks! I'll give a try!

@wangwwno1
Copy link
Contributor Author

wangwwno1 commented Dec 8, 2020

Get an error during package process, just like issue #2957:
SegmentationMaterial.uasset was saved with a newer custom version than the current
Removing SegmentationMaterial.uasset can partially resolve this issue.

Current Status:
./Blocks.sh --settings '/home/$USER/path/to/settings.json' is NOT work
./Blocks.sh --settings /home/$USER/path/to/settings.json is OK(with quotation marks removed)

./Blocks.sh --settings '{ "SettingsVersion": 1.2, "SimMode": "Multirotor" }' is NOT work
./Blocks.sh --settings ' " {\"SimMode\":\"Multirotor\"} " ' is OK

@wangwwno1
Copy link
Contributor Author

wangwwno1 commented Dec 9, 2020

It looks like the UnrealEngine parser won't process json strings without opening and closing quote.
Therefore, to passing json text in command line, one should rewrite
'{"SettingsVersion": 1.2, "SimMode": "Multirotor"}'
into
'"{\"SettingsVersion\": 1.2, \"SimMode\":\"Multirotor\"}"'

@wangwwno1
Copy link
Contributor Author

@ahmed-elsaharti
This issue disappeared in pexpect.spawn, so maybe there is something wrong in my ubuntu terminal console.
Could you replicate this problem in the same system? Here is the process:

  • navigate to the Blocks package folder
  • run ./Blocks.sh --settings '{"SimMode": "Multirotor"}' in the terminal console

Result: Pop-up "Choose Vehicle"window that ask to use car or quadcopter
Expect: No pop-up window

@ahmed-elsaharti
Copy link
Contributor

I currently don't have access to my Linux system. However, I'll compile a binary using the latest repo on my Windows system and test this.
I'll report back ASAP.

@ahmed-elsaharti
Copy link
Contributor

Here's what I found so far (for Windows):
Block --settings C:\Path\to\settings.json
and
Block --settings "C:\Path\to\settings.json"
work perfectly

Block --settings 'C:\Path\to\settings.json' does NOT. Neither does any form of passing the actual settings string to the parser

@wangwwno1
Copy link
Contributor Author

Here's what I found so far (for Windows):
Block --settings C:\Path\to\settings.json
and
Block --settings "C:\Path\to\settings.json"
work perfectly

Block --settings 'C:\Path\to\settings.json' does NOT. Neither does any form of passing the actual settings string to the parser

Thanks for the response! I got similar result on Ubuntu 18.04 terminal console.
Both ./Blocks.sh --settings /home/$USER/path/to/settings.json and ./Blocks.sh --settings "/home/$USER/path/to/settings.json" are OK while ./Blocks.sh --settings '/home/$USER/path/to/settings.json' is not.

The console encoding is en_US.UTF-8, identical with the pexpect code, so the root may not be there.
Perhaps I should move on with pexpect.spawn...

@niwc-jamelc
Copy link

I was experiencing the same issue with the --settings command line launch argument not working when launching AirSim as a Standalone game from the Unreal Editor on Windows 11. Upon further investigation into the SimHud.cpp and settings.md files, I found that the bool ASimHUD::getSettingsTextFromCommandLine(std::string& settingsText) function was poorly implemented and inconsistently documented.

The function does not properly support passing a json object with --settings, and the argument fails to be read if any other command line arguments and values exists after --setting. The implementation goes against the UE4's convention for passing and reading command line launch arguments.

FParse::Param is used for reading argument flags (ex: -flag), FParse::Value is used for reading arguments that pass along a number or string (ex: -number=1 -string="I'm a string"). The only way to pass a json object with FParse::Value is to make sure the remove all the whitespace and set the bStopOnSeperators flag to false for FParse::Value (ex: {"foo1":"bar1","foo2":"bar2"})

Here is my suggested fixes to SimHud.cpp and settings.md

Change the settings command line argument from --settings to be -settings= to follow UE4 conventions.

SimHud.cpp

// Attempts to parse the settings file path or the settings text from the command line
// Looks for the flag "-settings=". If it exists, settingsText will be set to the value.
// Example (Path): AirSim.exe -settings="C:\path\to\settings.json"
// Example (Text): AirSim.exe -settings={"foo":"bar"} -> settingsText will be set to {"foo":"bar"}
// Returns true if the argument is present, false otherwise.
bool ASimHUD::getSettingsTextFromCommandLine(std::string& settingsText)
{
    const TCHAR* commandLineArgs = FCommandLine::Get();
    FString settingsJsonFString;

    if (FParse::Value(commandLineArgs, TEXT("-settings="), settingsJsonFString, false)) {
        if (readSettingsTextFromFile(settingsJsonFString, settingsText)) {
            return true;
        }
        else {
            UAirBlueprintLib::LogMessageString("Loaded settings from commandline: ", TCHAR_TO_UTF8(*settingsJsonFString), LogDebugLevel::Informational);
            settingsText = TCHAR_TO_UTF8(*settingsJsonFString);
            return true;
        }
    }

    return false;
}

settings.md

# AirSim Settings

## Where are Settings Stored?
AirSim is searching for the settings definition in the following order. The first match will be used:

1. Looking at the (absolute) path specified by the `-settings` command line argument.
For example, in Windows: `AirSim.exe -settings="C:\path\to\settings.json"`
In Linux `./Blocks.sh -settings="/home/$USER/path/to/settings.json"`

2. Looking for a json document passed as a command line argument by the `-settings` argument.
For example, in Windows: `AirSim.exe -settings={"foo":"bar"}`
In Linux `./Blocks.sh -settings={"foo":"bar"}`

....

@jonyMarino
Copy link
Collaborator

Thanks, @niwc-jamelc for sharing a fix. Why don't you submit a pull request?

@niwc-jamelc
Copy link

@jonyMarino Apologies for the delay. I've created a pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants