Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,24 @@ env/
# Simulink cache
**/slprj
*.slxc

# Jsbsim repository files
core_sim/jsbsim/

# temporary for Jonathan
physics/test/CMakeLists.txt
core_sim/test/CMakeLists.txt
unreal/Blocks/Plugins/InternalDevUseContent/
unreal/Blocks/Plugins/ProjectAirSim/SDK/
unreal/Blocks/Samples/

# Compilation with Visual Studio
# TODO: Make this cleaner. This is a temporary fix.
CMakeFiles/
CMakeCache.txt
CTestTestfile.cmake
*.vcxproj
*.filters
*.cmake
DartConfiguration.tcl
ProjectAirSimLibs.sln
61 changes: 61 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ set(SIMLIBS_TEST_DIR ${CMAKE_BINARY_DIR}/unit_tests)
set(UE_PLUGIN_SIMLIBS_DIR ${CMAKE_SOURCE_DIR}/unreal/Blocks/Plugins/ProjectAirSim/SimLibs)
set(UNITY_WRAPPER_DLL_DIR ${CMAKE_SOURCE_DIR}/unity/BlocksUnity/Assets/Plugins)
set(MATLAB_PHYSICS_DIR ${CMAKE_SOURCE_DIR}/physics/matlab_sfunc)
set(JSBSIM_CORESIM_DIR ${CMAKE_SOURCE_DIR}/core_sim/jsbsim)
set(MATLAB_CONTROL_DIR ${CMAKE_SOURCE_DIR}/vehicle_apis/multirotor_api/matlab_sfunc)
# set(UE_PLUGIN_CESIUM_NATIVE_DIR ${CMAKE_SOURCE_DIR}/unreal/Blocks/Plugins/ProjectAirSim/SimLibs)
# set(UE_CESIUM_PLUGIN_DIR ${CMAKE_SOURCE_DIR}/unreal/Blocks/Plugins/CesiumForUnreal/)
Expand Down Expand Up @@ -72,6 +73,66 @@ elseif(UNIX)
# set(CESIUM_LINUX_TOOLCHAIN ${UE_CESIUM_PLUGIN_DIR}/extern/unreal-linux-toolchain.cmake)
endif()

# Set up dependency: jsbsim
message("Setting up [jsbsim] dependency as an external project...")
# CMake external projects don't adopt the parent's CMAKE_MSVC_RUNTIME_LIBRARY setting,
# so to force /MD non-debug CRT to match UE, build Debug config as Relwithdebinfo and
# build Release as Release.
set(JSBSIM_BUILD_TYPE $<IF:$<CONFIG:Debug>,Relwithdebinfo,Release>)
set(JSBSIM_SRC_DIR ${CMAKE_BINARY_DIR}/_deps/jsbsim/src/jsbsim-repo)
set(JSBSIM_SHARED_LIB_DIR ${CMAKE_BINARY_DIR}/_deps/jsbsim-install/bin)
set(JSBSIM_STATIC_LIB_DIR ${CMAKE_BINARY_DIR}/_deps/jsbsim-install/lib)
set(JSBSIM_INCLUDE_DIR ${CMAKE_BINARY_DIR}/_deps/jsbsim-install/include/JSBSim ${CMAKE_BINARY_DIR}/_deps/jsbsim-install/include/JSBSim/math)
ExternalProject_Add(jsbsim-repo
GIT_REPOSITORY https://github.com/JSBSim-Team/jsbsim
GIT_TAG "v1.1.12"
GIT_CONFIG "advice.detachedHead=false"
PREFIX ${CMAKE_BINARY_DIR}/_deps/jsbsim
BUILD_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config ${JSBSIM_BUILD_TYPE}
INSTALL_COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config ${JSBSIM_BUILD_TYPE} --target install
UPDATE_COMMAND "" # disable update step
CMAKE_ARGS
# -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_POSITION_INDEPENDENT_CODE=True
-DCMAKE_BUILD_TYPE:STRING=${JSBSIM_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/_deps/jsbsim-install
-DBUILD_SHARED_LIBS=ON
-DBUILD_PYTHON_MODULE=OFF
-DBUILD_DOCS=OFF
TEST_COMMAND "" # disable test step
BUILD_BYPRODUCTS ${JSBSIM_SHARED_LIB_DIR}/JSBSim.dll ${JSBSIM_STATIC_LIB_DIR}/JSBSim.lib
BUILD_ALWAYS 1
)
ExternalProject_Add_Step(jsbsim-repo post-install
COMMAND ${CMAKE_COMMAND} -E echo "Copying [jsbsim] library to ${JSBSIM_CORESIM_DIR}"
COMMAND ${CMAKE_COMMAND} -E copy "${JSBSIM_SHARED_LIB_DIR}/JSBSim.dll" "${JSBSIM_CORESIM_DIR}/lib/$<IF:$<CONFIG:Release>,Release,Debug>/JSBSim.dll"
COMMAND ${CMAKE_COMMAND} -E copy "${JSBSIM_STATIC_LIB_DIR}/JSBSim.lib" "${JSBSIM_CORESIM_DIR}/lib/$<IF:$<CONFIG:Release>,Release,Debug>/JSBSim.lib"
#COMMAND ${CMAKE_COMMAND} -E copy "${JSBSIM_LIB_DIR}/JSBSim.pdb" "${JSBSIM_PHYSICS_DIR}/lib/$<IF:$<CONFIG:Release>,Release,Debug>/JSBSim.pdb"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${JSBSIM_INCLUDE_DIR}" "${JSBSIM_CORESIM_DIR}/include"
# Copy JSBSim models
COMMAND ${CMAKE_COMMAND} -E copy_directory "${JSBSIM_SRC_DIR}/aircraft" "${JSBSIM_CORESIM_DIR}/models/aircraft"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${JSBSIM_SRC_DIR}/engine" "${JSBSIM_CORESIM_DIR}/models/engine"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${JSBSIM_SRC_DIR}/systems" "${JSBSIM_CORESIM_DIR}/models/systems"
# TODO: take out if we are not going to use JSBSim scripts
COMMAND ${CMAKE_COMMAND} -E copy_directory "${JSBSIM_SRC_DIR}/scripts" "${JSBSIM_CORESIM_DIR}/models/scripts"
DEPENDEES install
)
# add jsbsim shared library
add_library(jsbsim SHARED IMPORTED)
if(WIN32)
set_target_properties(jsbsim PROPERTIES
IMPORTED_LOCATION ${JSBSIM_SHARED_LIB_DIR}/JSBSim.dll
IMPORTED_IMPLIB ${JSBSIM_STATIC_LIB_DIR}/JSBSim.lib
)
else()
set_target_properties(jsbsim PROPERTIES
IMPORTED_LOCATION ${JSBSIM_SHARED_LIB_DIR}/libjsbsim.so
IMPORTED_IMPLIB ${JSBSIM_STATIC_LIB_DIR}/libjsbsim.a
)
endif()



# Set up dependency: nlohmann JSON
# Directly download single include file json.hpp
Expand Down
151 changes: 151 additions & 0 deletions client/python/example_user_scripts/hello_fixed_wing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
"""
Copyright (C) Microsoft Corporation. All rights reserved.

Demonstrates flying a quadrotor drone with camera sensors.
"""

import asyncio
import math

from projectairsim import ProjectAirSimClient, Drone, World
from projectairsim.utils import projectairsim_log
from projectairsim.image_utils import ImageDisplay


# Async main function to wrap async drone commands
async def main():
# Create a Project AirSim client
client = ProjectAirSimClient()

# Initialize an ImageDisplay object to display camera sub-windows
image_display = ImageDisplay()

try:
# Connect to simulation environment
client.connect()

# Create a World object to interact with the sim world and load a scene
world = World(client, "scene_basic_fixed_wing.jsonc", delay_after_load_sec=2)

# Create a Drone object to interact with a drone in the loaded sim world
drone = Drone(client, world, "x8")
#
## ------------------------------------------------------------------------------
#
## Subscribe to chase camera sensor as a client-side pop-up window
#chase_cam_window = "ChaseCam"
#image_display.add_chase_cam(chase_cam_window)
#client.subscribe(
# drone.sensors["DownCamera"]["scene_camera"],
# lambda _, chase: image_display.receive(chase, chase_cam_window),
#)
#
## Subscribe to the downward-facing camera sensor's RGB and Depth images
#rgb_name = "RGB-Image"
#image_display.add_image(rgb_name, subwin_idx=0)
#client.subscribe(
# drone.sensors["DownCamera"]["scene_camera"],
# lambda _, rgb: image_display.receive(rgb, rgb_name),
#)
#
#depth_name = "Depth-Image"
#image_display.add_image(depth_name, subwin_idx=2)
#client.subscribe(
# drone.sensors["DownCamera"]["depth_camera"],
# lambda _, depth: image_display.receive(depth, depth_name),
#)
#
#image_display.start()
#
## ------------------------------------------------------------------------------
#
## Set the drone to be ready to fly
## JSBSim robot currently does not support control the drone at runtime
#drone.enable_api_control()
##set brakes to 1
#drone.set_brakes(1)
#drone.arm()
#
## ------------------------------------------------------------------------------
#
## set takeoff z to 120 meters
#drone.set_take_off_z(-120)
#
## ------------------------------------------------------------------------------
#
## Sleep for two seconds to
#await asyncio.sleep(2)
#
## release brakes
#drone.set_brakes(0)
#
#projectairsim_log().info("takeoff_async: starting")
#takeoff_task = (
# await drone.takeoff_async(timeout_sec=1200)
#) # schedule an async task to start the command
#
#await takeoff_task
#projectairsim_log().info("takeoff_async: completed")
#
#projectairsim_log().info("Waiting to stabilize altitude... (10 seconds)")
#await asyncio.sleep(10)
#
## ------------------------------------------------------------------------------
#
## Command the drone to move to position 1000,1000,-200
#move_up_task = await drone.move_to_position_async(
# north=1000, east=1000, down=-200, velocity=33.0, lookahead=100, timeout_sec=60
#)
#projectairsim_log().info("Move to position 1000,1000,-200 invoked")
#
#await move_up_task
#projectairsim_log().info("Move to position completed")
#
## ------------------------------------------------------------------------------
#
## Command vehicle to fly at a specific heading and speed
#projectairsim_log().info("Heading 90 invoked")
#heading_45_task = await drone.move_by_heading_async(
# heading=math.radians(90.0), speed=20.0, duration=10
#)
#await heading_45_task
#projectairsim_log().info("Heading 90 complete.")
#
## ------------------------------------------------------------------------------
#
## Command the drone to move to position 0,0,-100
#move_up_task = await drone.move_to_position_async(
# north=0, east=0, down=-100, velocity=33.0, lookahead=100, timeout_sec=60
#)
#projectairsim_log().info("Move to position 0,0,-100 invoked")
#
#await move_up_task
#projectairsim_log().info("Move to position completed")
## ------------------------------------------------------------------------------
#
#projectairsim_log().info("land_async: starting")
#land_task = await drone.land_async()
#await land_task
#projectairsim_log().info("land_async: completed")
## set brakes to 50%
#drone.set_brakes(0.5)

# ------------------------------------------------------------------------------

# Shut down the drone
drone.disarm()
drone.disable_api_control()

# logs exception on the console
except Exception as err:
projectairsim_log().error(f"Exception occurred: {err}", exc_info=True)

finally:
# Always disconnect from the simulation environment to allow next connection
client.disconnect()

image_display.stop()


if __name__ == "__main__":
asyncio.run(main()) # Runner for async main function
133 changes: 133 additions & 0 deletions client/python/example_user_scripts/hello_helicopter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
"""
Copyright (C) Microsoft Corporation. All rights reserved.

Demonstrates flying a quadrotor drone with camera sensors.
"""

import asyncio

from projectairsim import ProjectAirSimClient, Drone, World
from projectairsim.utils import projectairsim_log
from projectairsim.image_utils import ImageDisplay


# Async main function to wrap async drone commands
async def main():
# Create a Project AirSim client
client = ProjectAirSimClient()

# Initialize an ImageDisplay object to display camera sub-windows
image_display = ImageDisplay()

try:
# Connect to simulation environment
client.connect()

# Create a World object to interact with the sim world and load a scene
world = World(client, "scene_basic_helicopter.jsonc", delay_after_load_sec=2)

# Create a Drone object to interact with a drone in the loaded sim world
drone = Drone(client, world, "Drone1")

# ------------------------------------------------------------------------------

# Subscribe to chase camera sensor as a client-side pop-up window
chase_cam_window = "ChaseCam"
image_display.add_chase_cam(chase_cam_window)
client.subscribe(
drone.sensors["Chase"]["scene_camera"],
lambda _, chase: image_display.receive(chase, chase_cam_window),
)

# Subscribe to the downward-facing camera sensor's RGB and Depth images
rgb_name = "RGB-Image"
image_display.add_image(rgb_name, subwin_idx=0)
client.subscribe(
drone.sensors["DownCamera"]["scene_camera"],
lambda _, rgb: image_display.receive(rgb, rgb_name),
)

depth_name = "Depth-Image"
image_display.add_image(depth_name, subwin_idx=2)
client.subscribe(
drone.sensors["DownCamera"]["depth_camera"],
lambda _, depth: image_display.receive(depth, depth_name),
)

image_display.start()

# ------------------------------------------------------------------------------

# Set the drone to be ready to fly
# JSBSim robot currently does not support control the drone at runtime
# drone.enable_api_control()
# drone.arm()

# # ------------------------------------------------------------------------------

# projectairsim_log().info("takeoff_async: starting")
# takeoff_task = (
# await drone.takeoff_async()
# ) # schedule an async task to start the command

# # Example 1: Wait on the result of async operation using 'await' keyword
# await takeoff_task
# projectairsim_log().info("takeoff_async: completed")

# # ------------------------------------------------------------------------------

# # Command the drone to move up in NED coordinate system at 1 m/s for 4 seconds
# move_up_task = await drone.move_by_velocity_async(
# v_north=0.0, v_east=0.0, v_down=-1.0, duration=4.0
# )
# projectairsim_log().info("Move-Up invoked")

# await move_up_task
# projectairsim_log().info("Move-Up completed")

# # ------------------------------------------------------------------------------

# # Command the Drone to move down in NED coordinate system at 1 m/s for 4 seconds
# move_down_task = await drone.move_by_velocity_async(
# v_north=0.0, v_east=0.0, v_down=1.0, duration=4.0
# ) # schedule an async task to start the command
# projectairsim_log().info("Move-Down invoked")

# # Example 2: Wait for move_down_task to complete before continuing
# while not move_down_task.done():
# await asyncio.sleep(0.005)
# projectairsim_log().info("Move-Down completed")

# # ------------------------------------------------------------------------------

# projectairsim_log().info("land_async: starting")
# land_task = await drone.land_async()
# await land_task
# projectairsim_log().info("land_async: completed")

# # # ------------------------------------------------------------------------------



# ------------------------------------------------------------------------------
# sleep for 5 minutes to contiue seeing the camera images
await asyncio.sleep(300)


# Shut down the drone
#drone.disarm()
#drone.disable_api_control()

# logs exception on the console
except Exception as err:
projectairsim_log().error(f"Exception occurred: {err}", exc_info=True)

finally:
# Always disconnect from the simulation environment to allow next connection
client.disconnect()

image_display.stop()


if __name__ == "__main__":
asyncio.run(main()) # Runner for async main function
1 change: 0 additions & 1 deletion client/python/example_user_scripts/jsbsim_env_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"""
from projectairsim import ProjectAirSimClient, World, EnvActor
from projectairsim.utils import projectairsim_log
import asyncio


async def env_actor_motion_plan(env_actor: EnvActor, world: World):
Expand Down
Loading