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

Sim run console command #2996

Merged
merged 12 commits into from
Sep 2, 2020
2 changes: 2 additions & 0 deletions AirLib/include/api/RpcLibClientBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class RpcLibClientBase {

msr::airlib::GeoPoint getHomeGeoPoint(const std::string& vehicle_name = "") const;

bool simRunConsoleCommand(const std::string& command);

// sensor APIs
msr::airlib::LidarData getLidarData(const std::string& lidar_name = "", const std::string& vehicle_name = "") const;
msr::airlib::ImuBase::Output getImuData(const std::string& imu_name = "", const std::string& vehicle_name = "") const;
Expand Down
1 change: 1 addition & 0 deletions AirLib/include/api/WorldSimApiBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class WorldSimApiBase {
virtual Pose getObjectPose(const std::string& object_name) const = 0;
virtual Vector3r getObjectScale(const std::string& object_name) const = 0;
virtual bool setObjectPose(const std::string& object_name, const Pose& pose, bool teleport) = 0;
virtual bool runConsoleCommand(const std::string& command) = 0;
virtual bool setObjectScale(const std::string& object_name, const Vector3r& scale) = 0;

virtual std::unique_ptr<std::vector<std::string>> swapTextures(const std::string& tag, int tex_id = 0, int component_id = 0, int material_id = 0) = 0;
Expand Down
5 changes: 5 additions & 0 deletions AirLib/src/api/RpcLibClientBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ void RpcLibClientBase::cancelLastTask(const std::string& vehicle_name)
pimpl_->client.call("cancelLastTask", vehicle_name);
}

bool RpcLibClientBase::simRunConsoleCommand(const std::string& command)
{
return pimpl_->client.call("simRunConsoleCommand", command).as<bool>();
}

//return value of last task. It should be true if task completed without
//cancellation or timeout
RpcLibClientBase* RpcLibClientBase::waitOnLastTask(bool* task_result, float timeout_sec)
Expand Down
4 changes: 4 additions & 0 deletions AirLib/src/api/RpcLibServerBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ RpcLibServerBase::RpcLibServerBase(ApiProvider* api_provider, const std::string&
return getVehicleApi(vehicle_name)->armDisarm(arm);
});

pimpl_->server.bind("simRunConsoleCommand", [&](const std::string& command) -> bool {
return getWorldSimApi()->runConsoleCommand(command);
});

pimpl_->server.bind("simGetImages", [&](const std::vector<RpcLibAdapatorsBase::ImageRequest>& request_adapter, const std::string& vehicle_name) ->
vector<RpcLibAdapatorsBase::ImageResponse> {
const auto& response = getVehicleSimApi(vehicle_name)->getImages(RpcLibAdapatorsBase::ImageRequest::to(request_adapter));
Expand Down
14 changes: 14 additions & 0 deletions PythonClient/airsim/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,20 @@ def simGetImages(self, requests, vehicle_name = ''):
"""
responses_raw = self.client.call('simGetImages', requests, vehicle_name)
return [ImageResponse.from_msgpack(response_raw) for response_raw in responses_raw]

def simRunConsoleCommand(self, command):
"""
Allows the client to execute a command in Unreal's native console, via an API.
Affords access to the countless built-in commands such as "stat unit", "stat fps", "open [map]", adjust any config settings, etc. etc.
Allows the user to create bespoke APIs very easily, by adding a custom event to the level blueprint, and then calling the console command "ce MyEventName [args]". No recompilation of AirSim needed!

Args:
command ([string]): Desired Unreal Engine Console command to run

Returns:
[bool]: Success
"""
return self.client.call('simRunConsoleCommand', command)

# gets the static meshes in the unreal scene
def simGetMeshPositionVertexBuffers(self):
Expand Down
29 changes: 29 additions & 0 deletions PythonClient/environment/unreal_console_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import airsim
import time

def RunConsoleCmd(client, cmd):
client.simRunConsoleCommand(cmd)
print(f"Running Unreal Console cmd '{cmd}' and sleeping for 1 second")
time.sleep(1.0)

def RunCmdList(client):
RunConsoleCmd(client, 'stat fps')
RunConsoleCmd(client, 'stat unit')
RunConsoleCmd(client, 'stat unitGraph')
RunConsoleCmd(client, 'show COLLISION')
RunConsoleCmd(client, 'show CollisionVisibility')
RunConsoleCmd(client, 'stat game')
RunConsoleCmd(client, 'show COLLISION')
RunConsoleCmd(client, 'show CollisionVisibility')
RunConsoleCmd(client, 'stat game')
RunConsoleCmd(client, 'stat unitGraph')
RunConsoleCmd(client, 'stat unit')
RunConsoleCmd(client, 'stat fps')

def main():
client = airsim.client.MultirotorClient()
client.confirmConnection()
RunCmdList(client)

if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions Unity/AirLibWrapper/AirsimWrapper/Source/WorldSimApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ bool WorldSimApi::setObjectPose(const std::string& object_name, const WorldSimAp
return SetPose(airSimPose, false, object_name.c_str());
}

bool WorldSimApi::runConsoleCommand(const std::string& command)
{
throw std::invalid_argument(common_utils::Utils::stringf(
"simrunConsoleCommand is not supported on unity").c_str());
return false;
}

void WorldSimApi::enableWeather(bool enable)
{
unused(enable);
Expand Down
2 changes: 2 additions & 0 deletions Unity/AirLibWrapper/AirsimWrapper/Source/WorldSimApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase
virtual bool setObjectPose(const std::string& object_name, const Pose& pose, bool teleport) override;
virtual bool setObjectScale(const std::string& object_name, const Vector3r& scale) override;

virtual bool runConsoleCommand(const std::string& command) override;

//----------- Plotting APIs ----------/
virtual void simFlushPersistentMarkers() override;
virtual void simPlotPoints(const std::vector<Vector3r>& points, const std::vector<float>& color_rgba, float size, float duration, bool is_persistent) override;
Expand Down
8 changes: 8 additions & 0 deletions Unreal/Plugins/AirSim/Source/AirBlueprintLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,14 @@ UObject* UAirBlueprintLib::GetMeshFromRegistry(const std::string& load_object)
return LoadObject;
}

bool UAirBlueprintLib::RunConsoleCommand(const AActor* context, const FString& command)
{
auto* playerController = UGameplayStatics::GetPlayerController(context->GetWorld(), 0);;
if (playerController != nullptr)
playerController->ConsoleCommand(command, true);
return playerController != nullptr;
}

bool UAirBlueprintLib::HasObstacle(const AActor* actor, const FVector& start, const FVector& end, const AActor* ignore_actor, ECollisionChannel collision_channel)
{
FCollisionQueryParams trace_params;
Expand Down
3 changes: 3 additions & 0 deletions Unreal/Plugins/AirSim/Source/AirBlueprintLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class UAirBlueprintLib : public UBlueprintFunctionLibrary
static TArray<FName> ListWorldsInRegistry();
static UObject* GetMeshFromRegistry(const std::string& load_object);

UFUNCTION(BlueprintCallable, Category = "AirSim")
static bool RunConsoleCommand(const AActor* context, const FString& command);

static bool HasObstacle(const AActor* actor, const FVector& start, const FVector& end,
const AActor* ignore_actor = nullptr, ECollisionChannel collision_channel = ECC_Visibility);
static bool GetObstacle(const AActor* actor, const FVector& start, const FVector& end,
Expand Down
10 changes: 10 additions & 0 deletions Unreal/Plugins/AirSim/Source/WorldSimApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ std::vector<std::string> WorldSimApi::listSceneObjects(const std::string& name_r
return result;
}

bool WorldSimApi::runConsoleCommand(const std::string& command)
{
bool succeeded = false;
UAirBlueprintLib::RunCommandOnGameThread([this, &command, &succeeded]() {
FString fStringCommand(command.c_str());
succeeded = UAirBlueprintLib::RunConsoleCommand(simmode_, fStringCommand);
}, true);
return succeeded;
}

WorldSimApi::Pose WorldSimApi::getObjectPose(const std::string& object_name) const
{
Pose result;
Expand Down
1 change: 1 addition & 0 deletions Unreal/Plugins/AirSim/Source/WorldSimApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase {
virtual std::vector<std::string> listSceneObjects(const std::string& name_regex) const override;
virtual Pose getObjectPose(const std::string& object_name) const override;
virtual bool setObjectPose(const std::string& object_name, const Pose& pose, bool teleport) override;
virtual bool runConsoleCommand(const std::string& command) override;
virtual Vector3r getObjectScale(const std::string& object_name) const override;
virtual bool setObjectScale(const std::string& object_name, const Vector3r& scale) override;

Expand Down