diff --git a/examples/basic_usage.py b/examples/basic_usage.py index 9f81ff1..159e503 100644 --- a/examples/basic_usage.py +++ b/examples/basic_usage.py @@ -32,17 +32,28 @@ from rotorpy.sensors.external_mocap import MotionCapture # You can also specify a state estimator. This is optional. If no state estimator is supplied it will default to null. from rotorpy.estimators.wind_ukf import WindUKF +# Also, worlds are how we construct obstacles. The following class contains methods related to constructing these maps. +from rotorpy.world import World + # Reference the files above for more documentation. # Other useful imports import numpy as np # For array creation/manipulation import matplotlib.pyplot as plt # For plotting, although the simulator has a built in plotter from scipy.spatial.transform import Rotation # For doing conversions between different rotation descriptions, applying rotations, etc. +import os # For path generation """ Instantiation """ +# Obstacle maps can be loaded in from a JSON file using the World.from_file(path) method. Here we are loading in from +# an existing file under the rotorpy/worlds/ directory. However, you can create your own world by following the template +# provided (see rotorpy/worlds/README.md), and load that file anywhere using the appropriate path. +world = World.from_file(os.path.abspath(os.path.join(os.path.dirname(__file__),'..','rotorpy','worlds','double_pillar.json'))) + +# "world" is an optional argument. If you don't load a world it'll just provide an empty playground! + # An instance of the simulator can be generated as follows: sim_instance = Environment(vehicle=Multirotor(quad_params), # vehicle object, must be specified. controller=SE3Control(quad_params), # controller object, must be specified. @@ -52,7 +63,7 @@ sim_instance = Environment(vehicle=Multirotor(quad_params), # vehicle imu = None, # OPTIONAL: imu sensor object, if none is supplied it will choose a default IMU sensor. mocap = None, # OPTIONAL: mocap sensor object, if none is supplied it will choose a default mocap. estimator = None, # OPTIONAL: estimator object - world_fname = 'double_pillar', # OPTIONAL: the world, same name as the file in rotorpy/worlds/, default (None) is empty world + world = world, # OPTIONAL: the world, same name as the file in rotorpy/worlds/, default (None) is empty world safety_margin= 0.25 # OPTIONAL: defines the radius (in meters) of the sphere used for collision checking ) diff --git a/rotorpy/environments.py b/rotorpy/environments.py index ccfd45d..5611594 100644 --- a/rotorpy/environments.py +++ b/rotorpy/environments.py @@ -24,10 +24,10 @@ class Environment(): trajectory, # trajectory object, must be specified. wind_profile = None, # wind profile object, if none is supplied it will choose no wind. imu = None, # imu sensor object, if none is supplied it will choose a default IMU sensor. - mocap = None, # mocap sensor object, if none is supplied it will choose a default mocap. + mocap = None, # mocap sensor object, if none is supplied it will choose a default mocap. + world = None, # The world object estimator = None, # estimator object sim_rate = 100, # The update frequency of the simulator in Hz - world_fname = None, # The world filename, when specified it will load the file located in ../worlds safety_margin = 0.25, # The radius of the safety region around the robot. ): @@ -38,13 +38,13 @@ class Environment(): self.safety_margin = safety_margin - if world_fname is None: - # If no world JSON file is specified, assume that it means that the intended world is free space. + if world is None: + # If no world is specified, assume that it means that the intended world is free space. wbound = 3 self.world = World.empty((-wbound, wbound, -wbound, wbound, -wbound, wbound)) else: - self.world = World.from_file(os.path.abspath(os.path.join(os.path.dirname(__file__),'worlds',world_fname+'.json'))) + self.world = world if wind_profile is None: # If wind is not specified, default to no wind.