diff --git a/.gitignore b/.gitignore
index aeaaa7793..00961ea0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,6 @@ runs/
outputs/
*.hydra*
/isaacgymenvs/wandb
+isaacgymenvs/tasks/drone_racing/assets/export
+.ipynb_checkpoints
+recorded_frames
diff --git a/README.md b/README.md
index e8c4660a8..a35073e62 100644
--- a/README.md
+++ b/README.md
@@ -343,4 +343,17 @@ Please cite this work as:
booktitle = {Robotics: Science and Systems},
year = {2023}
}
-```
\ No newline at end of file
+```
+
+**Note** if you use the drone racing implementations, please cite the following paper:
+```
+@misc{liu2024droneracing,
+ title={Learning Generalizable Policy for Obstacle-Aware Autonomous Drone Racing},
+ author={Yueqian Liu},
+ year={2024},
+ eprint={2411.04246},
+ archivePrefix={arXiv},
+ primaryClass={cs.RO},
+ url={https://arxiv.org/abs/2411.04246},
+}
+```
diff --git a/assets/urdf/aerial_gym_trees/README.md b/assets/urdf/aerial_gym_trees/README.md
new file mode 100644
index 000000000..8b053282b
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/README.md
@@ -0,0 +1,32 @@
+Asset source: [ntnu-arl/aerial_gym_simulator](https://github.com/ntnu-arl/aerial_gym_simulator/tree/main/resources/models/environment_assets/trees).
+
+```
+BSD 3-Clause License
+
+Copyright (c) 2023, Autonomous Robots Lab, Norwegian University of Science and Technology
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+```
diff --git a/assets/urdf/aerial_gym_trees/tree_0.urdf b/assets/urdf/aerial_gym_trees/tree_0.urdf
new file mode 100644
index 000000000..815215448
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_0.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_1.urdf b/assets/urdf/aerial_gym_trees/tree_1.urdf
new file mode 100644
index 000000000..304121b9f
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_1.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_10.urdf b/assets/urdf/aerial_gym_trees/tree_10.urdf
new file mode 100644
index 000000000..dff6db145
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_10.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_11.urdf b/assets/urdf/aerial_gym_trees/tree_11.urdf
new file mode 100644
index 000000000..9906f76c6
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_11.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_12.urdf b/assets/urdf/aerial_gym_trees/tree_12.urdf
new file mode 100644
index 000000000..cd78ec10a
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_12.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_13.urdf b/assets/urdf/aerial_gym_trees/tree_13.urdf
new file mode 100644
index 000000000..582d15a1e
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_13.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_14.urdf b/assets/urdf/aerial_gym_trees/tree_14.urdf
new file mode 100644
index 000000000..da9689163
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_14.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_15.urdf b/assets/urdf/aerial_gym_trees/tree_15.urdf
new file mode 100644
index 000000000..dff6833b8
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_15.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_16.urdf b/assets/urdf/aerial_gym_trees/tree_16.urdf
new file mode 100644
index 000000000..534d10e2f
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_16.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_17.urdf b/assets/urdf/aerial_gym_trees/tree_17.urdf
new file mode 100644
index 000000000..1542e4700
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_17.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_18.urdf b/assets/urdf/aerial_gym_trees/tree_18.urdf
new file mode 100644
index 000000000..5b2558402
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_18.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_19.urdf b/assets/urdf/aerial_gym_trees/tree_19.urdf
new file mode 100644
index 000000000..f0e5192b1
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_19.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_2.urdf b/assets/urdf/aerial_gym_trees/tree_2.urdf
new file mode 100644
index 000000000..b9bd52e5a
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_2.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_20.urdf b/assets/urdf/aerial_gym_trees/tree_20.urdf
new file mode 100644
index 000000000..c9f2862ae
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_20.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_21.urdf b/assets/urdf/aerial_gym_trees/tree_21.urdf
new file mode 100644
index 000000000..470d4e52f
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_21.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_22.urdf b/assets/urdf/aerial_gym_trees/tree_22.urdf
new file mode 100644
index 000000000..74dfc3c23
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_22.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_23.urdf b/assets/urdf/aerial_gym_trees/tree_23.urdf
new file mode 100644
index 000000000..07237a36c
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_23.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_24.urdf b/assets/urdf/aerial_gym_trees/tree_24.urdf
new file mode 100644
index 000000000..aeee1e7d3
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_24.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_25.urdf b/assets/urdf/aerial_gym_trees/tree_25.urdf
new file mode 100644
index 000000000..0ddd57d80
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_25.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_26.urdf b/assets/urdf/aerial_gym_trees/tree_26.urdf
new file mode 100644
index 000000000..63fe8ffc2
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_26.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_27.urdf b/assets/urdf/aerial_gym_trees/tree_27.urdf
new file mode 100644
index 000000000..6a4850810
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_27.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_28.urdf b/assets/urdf/aerial_gym_trees/tree_28.urdf
new file mode 100644
index 000000000..8c538f72a
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_28.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_29.urdf b/assets/urdf/aerial_gym_trees/tree_29.urdf
new file mode 100644
index 000000000..31ab3d8cb
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_29.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_3.urdf b/assets/urdf/aerial_gym_trees/tree_3.urdf
new file mode 100644
index 000000000..fb67b7158
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_3.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_30.urdf b/assets/urdf/aerial_gym_trees/tree_30.urdf
new file mode 100644
index 000000000..3332a93e6
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_30.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_31.urdf b/assets/urdf/aerial_gym_trees/tree_31.urdf
new file mode 100644
index 000000000..f3a606017
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_31.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_32.urdf b/assets/urdf/aerial_gym_trees/tree_32.urdf
new file mode 100644
index 000000000..3ad6f6087
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_32.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_33.urdf b/assets/urdf/aerial_gym_trees/tree_33.urdf
new file mode 100644
index 000000000..dcc4b7e18
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_33.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_34.urdf b/assets/urdf/aerial_gym_trees/tree_34.urdf
new file mode 100644
index 000000000..c25e34318
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_34.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_35.urdf b/assets/urdf/aerial_gym_trees/tree_35.urdf
new file mode 100644
index 000000000..8e84012da
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_35.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_36.urdf b/assets/urdf/aerial_gym_trees/tree_36.urdf
new file mode 100644
index 000000000..807819ec9
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_36.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_37.urdf b/assets/urdf/aerial_gym_trees/tree_37.urdf
new file mode 100644
index 000000000..46d91c2cd
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_37.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_38.urdf b/assets/urdf/aerial_gym_trees/tree_38.urdf
new file mode 100644
index 000000000..36b6d2bb5
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_38.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_39.urdf b/assets/urdf/aerial_gym_trees/tree_39.urdf
new file mode 100644
index 000000000..4e3fda8c3
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_39.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_4.urdf b/assets/urdf/aerial_gym_trees/tree_4.urdf
new file mode 100644
index 000000000..83004acd1
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_4.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_40.urdf b/assets/urdf/aerial_gym_trees/tree_40.urdf
new file mode 100644
index 000000000..db91af33b
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_40.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_41.urdf b/assets/urdf/aerial_gym_trees/tree_41.urdf
new file mode 100644
index 000000000..b31f24521
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_41.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_42.urdf b/assets/urdf/aerial_gym_trees/tree_42.urdf
new file mode 100644
index 000000000..4eff6aca0
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_42.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_43.urdf b/assets/urdf/aerial_gym_trees/tree_43.urdf
new file mode 100644
index 000000000..4f24e0e8d
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_43.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_44.urdf b/assets/urdf/aerial_gym_trees/tree_44.urdf
new file mode 100644
index 000000000..2766e3589
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_44.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_45.urdf b/assets/urdf/aerial_gym_trees/tree_45.urdf
new file mode 100644
index 000000000..1db580b1d
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_45.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_46.urdf b/assets/urdf/aerial_gym_trees/tree_46.urdf
new file mode 100644
index 000000000..1abc13e5e
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_46.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_47.urdf b/assets/urdf/aerial_gym_trees/tree_47.urdf
new file mode 100644
index 000000000..48f1b75d5
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_47.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_48.urdf b/assets/urdf/aerial_gym_trees/tree_48.urdf
new file mode 100644
index 000000000..c5df5734c
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_48.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_49.urdf b/assets/urdf/aerial_gym_trees/tree_49.urdf
new file mode 100644
index 000000000..32ec12b5f
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_49.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_5.urdf b/assets/urdf/aerial_gym_trees/tree_5.urdf
new file mode 100644
index 000000000..a8ca6acf5
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_5.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_50.urdf b/assets/urdf/aerial_gym_trees/tree_50.urdf
new file mode 100644
index 000000000..bd2925dbb
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_50.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_51.urdf b/assets/urdf/aerial_gym_trees/tree_51.urdf
new file mode 100644
index 000000000..cb71a67cb
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_51.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_52.urdf b/assets/urdf/aerial_gym_trees/tree_52.urdf
new file mode 100644
index 000000000..096d95055
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_52.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_53.urdf b/assets/urdf/aerial_gym_trees/tree_53.urdf
new file mode 100644
index 000000000..f5419f5be
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_53.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_54.urdf b/assets/urdf/aerial_gym_trees/tree_54.urdf
new file mode 100644
index 000000000..01466428d
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_54.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_55.urdf b/assets/urdf/aerial_gym_trees/tree_55.urdf
new file mode 100644
index 000000000..2261dbab8
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_55.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_56.urdf b/assets/urdf/aerial_gym_trees/tree_56.urdf
new file mode 100644
index 000000000..cf3681338
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_56.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_57.urdf b/assets/urdf/aerial_gym_trees/tree_57.urdf
new file mode 100644
index 000000000..07535698c
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_57.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_58.urdf b/assets/urdf/aerial_gym_trees/tree_58.urdf
new file mode 100644
index 000000000..802b7fd6d
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_58.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_59.urdf b/assets/urdf/aerial_gym_trees/tree_59.urdf
new file mode 100644
index 000000000..2f0b17c1d
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_59.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_6.urdf b/assets/urdf/aerial_gym_trees/tree_6.urdf
new file mode 100644
index 000000000..5ee5718b7
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_6.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_60.urdf b/assets/urdf/aerial_gym_trees/tree_60.urdf
new file mode 100644
index 000000000..f8cb09b0a
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_60.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_61.urdf b/assets/urdf/aerial_gym_trees/tree_61.urdf
new file mode 100644
index 000000000..d28d2ad15
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_61.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_62.urdf b/assets/urdf/aerial_gym_trees/tree_62.urdf
new file mode 100644
index 000000000..d79a384d5
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_62.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_63.urdf b/assets/urdf/aerial_gym_trees/tree_63.urdf
new file mode 100644
index 000000000..2bfc98806
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_63.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_64.urdf b/assets/urdf/aerial_gym_trees/tree_64.urdf
new file mode 100644
index 000000000..870e1adc2
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_64.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_65.urdf b/assets/urdf/aerial_gym_trees/tree_65.urdf
new file mode 100644
index 000000000..d15f923ac
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_65.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_66.urdf b/assets/urdf/aerial_gym_trees/tree_66.urdf
new file mode 100644
index 000000000..14bdb021e
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_66.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_67.urdf b/assets/urdf/aerial_gym_trees/tree_67.urdf
new file mode 100644
index 000000000..dc7c3b0e3
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_67.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_68.urdf b/assets/urdf/aerial_gym_trees/tree_68.urdf
new file mode 100644
index 000000000..7ca0030c4
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_68.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_69.urdf b/assets/urdf/aerial_gym_trees/tree_69.urdf
new file mode 100644
index 000000000..822cac327
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_69.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_7.urdf b/assets/urdf/aerial_gym_trees/tree_7.urdf
new file mode 100644
index 000000000..7a838abee
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_7.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_70.urdf b/assets/urdf/aerial_gym_trees/tree_70.urdf
new file mode 100644
index 000000000..6d1cd0761
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_70.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_71.urdf b/assets/urdf/aerial_gym_trees/tree_71.urdf
new file mode 100644
index 000000000..4e387789a
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_71.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_72.urdf b/assets/urdf/aerial_gym_trees/tree_72.urdf
new file mode 100644
index 000000000..14deb9b0f
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_72.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_73.urdf b/assets/urdf/aerial_gym_trees/tree_73.urdf
new file mode 100644
index 000000000..3e2fea38c
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_73.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_74.urdf b/assets/urdf/aerial_gym_trees/tree_74.urdf
new file mode 100644
index 000000000..876ee5394
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_74.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_75.urdf b/assets/urdf/aerial_gym_trees/tree_75.urdf
new file mode 100644
index 000000000..9f7c4e4a1
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_75.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_76.urdf b/assets/urdf/aerial_gym_trees/tree_76.urdf
new file mode 100644
index 000000000..47b98237c
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_76.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_77.urdf b/assets/urdf/aerial_gym_trees/tree_77.urdf
new file mode 100644
index 000000000..0f4f36170
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_77.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_78.urdf b/assets/urdf/aerial_gym_trees/tree_78.urdf
new file mode 100644
index 000000000..e8d8bf9f0
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_78.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_79.urdf b/assets/urdf/aerial_gym_trees/tree_79.urdf
new file mode 100644
index 000000000..f7db71cd3
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_79.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_8.urdf b/assets/urdf/aerial_gym_trees/tree_8.urdf
new file mode 100644
index 000000000..a48c0ff95
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_8.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_80.urdf b/assets/urdf/aerial_gym_trees/tree_80.urdf
new file mode 100644
index 000000000..b8c6d1ff7
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_80.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_81.urdf b/assets/urdf/aerial_gym_trees/tree_81.urdf
new file mode 100644
index 000000000..05a0b43c7
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_81.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_82.urdf b/assets/urdf/aerial_gym_trees/tree_82.urdf
new file mode 100644
index 000000000..b2b0f7372
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_82.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_83.urdf b/assets/urdf/aerial_gym_trees/tree_83.urdf
new file mode 100644
index 000000000..8812b93df
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_83.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_84.urdf b/assets/urdf/aerial_gym_trees/tree_84.urdf
new file mode 100644
index 000000000..72789bd7a
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_84.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_85.urdf b/assets/urdf/aerial_gym_trees/tree_85.urdf
new file mode 100644
index 000000000..c27c3b187
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_85.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_86.urdf b/assets/urdf/aerial_gym_trees/tree_86.urdf
new file mode 100644
index 000000000..1229f9c36
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_86.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_87.urdf b/assets/urdf/aerial_gym_trees/tree_87.urdf
new file mode 100644
index 000000000..2bf529545
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_87.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_88.urdf b/assets/urdf/aerial_gym_trees/tree_88.urdf
new file mode 100644
index 000000000..d038f8058
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_88.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_89.urdf b/assets/urdf/aerial_gym_trees/tree_89.urdf
new file mode 100644
index 000000000..2a48f9812
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_89.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_9.urdf b/assets/urdf/aerial_gym_trees/tree_9.urdf
new file mode 100644
index 000000000..567edcc4f
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_9.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_90.urdf b/assets/urdf/aerial_gym_trees/tree_90.urdf
new file mode 100644
index 000000000..dfe7434a5
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_90.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_91.urdf b/assets/urdf/aerial_gym_trees/tree_91.urdf
new file mode 100644
index 000000000..64c29e9f4
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_91.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_92.urdf b/assets/urdf/aerial_gym_trees/tree_92.urdf
new file mode 100644
index 000000000..5b4a8c83d
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_92.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_93.urdf b/assets/urdf/aerial_gym_trees/tree_93.urdf
new file mode 100644
index 000000000..964b10795
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_93.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_94.urdf b/assets/urdf/aerial_gym_trees/tree_94.urdf
new file mode 100644
index 000000000..c36853930
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_94.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_95.urdf b/assets/urdf/aerial_gym_trees/tree_95.urdf
new file mode 100644
index 000000000..6725ef6da
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_95.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_96.urdf b/assets/urdf/aerial_gym_trees/tree_96.urdf
new file mode 100644
index 000000000..e11965144
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_96.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_97.urdf b/assets/urdf/aerial_gym_trees/tree_97.urdf
new file mode 100644
index 000000000..03362dbed
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_97.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_98.urdf b/assets/urdf/aerial_gym_trees/tree_98.urdf
new file mode 100644
index 000000000..7cd24e79b
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_98.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/urdf/aerial_gym_trees/tree_99.urdf b/assets/urdf/aerial_gym_trees/tree_99.urdf
new file mode 100644
index 000000000..340cd95ae
--- /dev/null
+++ b/assets/urdf/aerial_gym_trees/tree_99.urdf
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/images/drone_racing_test_hard.png b/docs/images/drone_racing_test_hard.png
new file mode 100644
index 000000000..d03185f70
Binary files /dev/null and b/docs/images/drone_racing_test_hard.png differ
diff --git a/docs/images/drone_racing_test_no_obst.png b/docs/images/drone_racing_test_no_obst.png
new file mode 100644
index 000000000..d92d1e2dc
Binary files /dev/null and b/docs/images/drone_racing_test_no_obst.png differ
diff --git a/docs/images/drone_racing_test_obst.png b/docs/images/drone_racing_test_obst.png
new file mode 100644
index 000000000..20afb3101
Binary files /dev/null and b/docs/images/drone_racing_test_obst.png differ
diff --git a/docs/images/drone_racing_test_rand.png b/docs/images/drone_racing_test_rand.png
new file mode 100644
index 000000000..7c092e3c9
Binary files /dev/null and b/docs/images/drone_racing_test_rand.png differ
diff --git a/docs/images/drone_racing_test_splits_turns.png b/docs/images/drone_racing_test_splits_turns.png
new file mode 100644
index 000000000..c4f60cebd
Binary files /dev/null and b/docs/images/drone_racing_test_splits_turns.png differ
diff --git a/docs/images/drone_racing_train_rand.png b/docs/images/drone_racing_train_rand.png
new file mode 100644
index 000000000..50a934faa
Binary files /dev/null and b/docs/images/drone_racing_train_rand.png differ
diff --git a/docs/rl_examples.md b/docs/rl_examples.md
index eaad4a289..e51dbf744 100644
--- a/docs/rl_examples.md
+++ b/docs/rl_examples.md
@@ -30,6 +30,7 @@ List of Examples
* [DeXtreme](#dextreme-transfer-of-agile-in-hand-manipulation-from-simulation-to-reality)
* [DexPBT](#dexpbt-scaling-up-dexterous-manipulation-for-hand-arm-systems-with-population-based-training)
* [IndustReal](#industreal-transferring-contact-rich-assembly-tasks-from-simulation-to-reality)
+* [Drone Racing](#drone-racing-obstacle-free-and-obstacle-aware-autonomous-drone-racing)
### Ant [ant.py](../isaacgymenvs/tasks/ant.py)
@@ -561,3 +562,93 @@ Also note that the simulation methods, original environments, and low-level cont
year = {2022}
}
```
+
+### Drone Racing: Obstacle-Free and Obstacle-Aware Autonomous Drone Racing
+
+#### Installation
+
+Running drone racing tasks requires additional packages,
+we recommend installing them altogether using the environment file provided in the task directory.
+
+```bash
+# install dependencies
+conda env create -f isaacgymenvs/tasks/drone_racing/rlgpu.yaml
+conda activate rlgpu
+
+# install rerun urdf support
+pip install git+https://github.com/rerun-io/rerun-loader-python-example-urdf.git@539252acc50771829f7e2aacef27d6cb2cbd7928
+
+# install isaac gym
+cd $ISAACGYM_DIR/python
+pip install -e .
+
+# install this repo
+cd $ISAACGYMENV_DIR
+pip install -e .
+
+# update LD_LIBRARY_PATH before using Isaac Gym
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/$CONDA_DIR/envs/rlgpu/lib
+```
+
+#### Overview
+
+Task implementations are in ``isaacgymenvs/tasks/drone_racing/tasks``.
+
+In ``isaacgymenvs/tasks/drone_racing/demos`` you can find executable Python scripts.
+Some scripts are for testing, some are for demonstrating environments, and some are for processing experiment logs.
+
+We use scripts instead of multiple configuration files to specify different tasks.
+These scripts override fields in the configuration files.
+Scripts for training and testing policies are in ``isaacgymenvs/tasks/drone_racing/demos/sh``.
+There you can also find scripts for plotting figures, sweeping hyperparams, and testing simulation
+performance.
+
+Some pre-trained network weights are in ``isaacgymenvs/tasks/drone_racing/demos/checkpoints``.
+
+#### Scripts
+
+**``train_rand_dr.sh`` & ``train_rand_naive.sh``:** train in random environments with obstacles, cameras are enabled. DR means enabling racing track domain randomization for every rollout. Naive means the opposite.
+
+
+
+**``train_rand_no_obstcale_no_cam.sh``:** train in random environments without obstacles, cameras are disabled. No track domain randomization for every rollout.
+
+
+
+**``train_splits_no_cam.sh``:** train on track Split-S, cameras are disabled.
+
+
+
+**``collection_cam_asset_hard.sh``:** test on hard racing tracks with obstacles.
+
+
+
+**``collection_cam_asset_no_obst.sh``:** test on tracks without obstacles, cameras are enabled.
+
+
+
+**``collection_cam_asset_obst.sh``:** test on tracks with obstacles, cameras are enabled.
+
+
+
+**``collection_cam_rand.sh``:** test on random tracks with obstacles, cameras are enabled.
+
+
+
+**``test_no_cam_splits.sh`` & ``test_no_cam_turns.sh``:** test on Split-S and Turns with cameras disabled.
+
+
+
+#### Citing
+
+```
+@misc{liu2024droneracing,
+ title={Learning Generalizable Policy for Obstacle-Aware Autonomous Drone Racing},
+ author={Yueqian Liu},
+ year={2024},
+ eprint={2411.04246},
+ archivePrefix={arXiv},
+ primaryClass={cs.RO},
+ url={https://arxiv.org/abs/2411.04246},
+}
+```
diff --git a/isaacgymenvs/cfg/task/DRAsset.yaml b/isaacgymenvs/cfg/task/DRAsset.yaml
new file mode 100644
index 000000000..16de1edba
--- /dev/null
+++ b/isaacgymenvs/cfg/task/DRAsset.yaml
@@ -0,0 +1,39 @@
+name: DRAsset
+
+defaults:
+ - DRBase
+ - _self_
+
+env:
+ numEnvs: ${resolve_default:16384,${...num_envs}}
+ numObservations: 56 # 18 [p, R, v, w] + 17 * 2 [waypoint] + 4 [action]
+ obsImgMode: empty
+ maxEpisodeLength: 250 # step 25 Hz, episode max 10 s
+ enableCameraSensors: False
+ groundOffset: -10.0
+ disableGround: False
+ appendWpDist: 10.0
+
+assetName: splits
+sjtu_track:
+ type_id: 0
+ num_obstacles: 16
+
+initRandOpt:
+ randDroneOptions:
+ next_wp_id_max: 1
+ dist_along_line_min: 0.0
+ dist_along_line_max: 0.0
+ drone_rotation_x_max: 0.0
+ dist_to_line_max: 0.0
+ lin_vel_x_max: 0.0 # m/s
+ lin_vel_y_max: 0.0
+ lin_vel_z_max: 0.0
+ ang_vel_x_max: 0.0 # rad/s
+ ang_vel_y_max: 0.0
+ ang_vel_z_max: 0.0
+ aileron_max: 0.0
+ elevator_max: 0.0
+ rudder_max: 0.0
+ throttle_min: -1.0
+ throttle_max: -1.0
diff --git a/isaacgymenvs/cfg/task/DRBase.yaml b/isaacgymenvs/cfg/task/DRBase.yaml
new file mode 100644
index 000000000..8c4db7b58
--- /dev/null
+++ b/isaacgymenvs/cfg/task/DRBase.yaml
@@ -0,0 +1,186 @@
+# base configuration for drone racing including:
+# sim, env, rand opts for drone and camera, drone control and sim
+# common observation and default reward calculation
+
+name: DRBase
+
+physics_engine: ${..physics_engine}
+
+sim:
+ # SimParams, Simulation Tuning
+ dt: 0.004 # physics simulation dt, default is 0.0167, we use 250Hz to show motor dynamics
+ substeps: 1 # 2
+ up_axis: "z" # UpAxis.UP_AXIS_Y
+ gravity: [ 0.0, 0.0, -9.81 ] # [0.0, -9.8, 0.0]
+ use_gpu_pipeline: ${eq:${...pipeline},"gpu"} # False
+ num_client_threads: 0
+ physx:
+ always_use_articulations: False
+ bounce_threshold_velocity: 0.2 # 0.2
+ contact_collection: 1 # 0: none, 1: CC_LAST_SUBSTEP, 2: CC_ALL_SUBSTEPS
+ contact_offset: 0.02
+ default_buffer_size_multiplier: 2.0
+ friction_correlation_distance: 0.025
+ friction_offset_threshold: 0.04
+ max_depenetration_velocity: 1.0
+ max_gpu_contact_pairs: 1048576
+ num_position_iterations: 4
+ num_subscenes: ${....num_subscenes} # 0
+ num_threads: ${....num_threads} # 0
+ num_velocity_iterations: 1
+ rest_offset: 0.001
+ solver_type: ${....solver_type} # 1
+ use_gpu: ${contains:"cuda",${....sim_device}} # False
+
+env:
+ numEnvs: ${resolve_default:256,${...num_envs}}
+ numActions: 4 # 4 channels AETR
+ numAgents: 1
+ numObservations: 120 # 18 [p, R, v, w] + 17 * 2 [waypoint] + 4 [action] + 64 [image encoded]
+ controlFrequencyInv: 10 # physics steps per action, this makes policy frequency running @ 25Hz
+ obsImgMode: dce
+ maxEpisodeLength: 100 # step 25 Hz, episode max 4 s
+ enableStrictCollision: False # if False, crashing and waypoint passing are allowed to happen at the same time
+ enableDebugVis: False # enable waypoint visualization, which also appears in camera sensors
+ enableVirtualWalls: True
+ enableCameraSensors: True
+ cameraEnableTensors: True
+ cameraWidth: 480
+ cameraHeight: 270
+ cameraHfov: 90
+ cameraBodyPos: [ 0.08, 0.0, 0.015 ]
+ cameraAngleDeg: 30
+ cameraDepthMax: 20
+ logging:
+ enable: False
+ experimentName: ${...name}
+ logMainCam: False # if True, enableCameraSensors and logging.enable should be True
+ logExtraCams: False # if True, enableCameraSensors and logging.enable should be True
+ maxNumEpisodes: 10
+ numStepsPerSave: 50
+ extraCameraWidth: 256
+ extraCameraHeight: 256
+ extraCameraHfov: 90
+ viewer:
+ camPos: [ -20, -20, 30 ]
+ camTarget: [ 20, 20, 10 ]
+
+initRandOpt:
+ randDroneOptions:
+ next_wp_id_max: 1
+ dist_along_line_min: 0.0
+ dist_along_line_max: 0.1
+ drone_rotation_x_max: 3.14
+ dist_to_line_max: 1.0
+ lin_vel_x_max: 1.0 # m/s
+ lin_vel_y_max: 1.0
+ lin_vel_z_max: 1.0
+ ang_vel_x_max: 1.0 # rad/s
+ ang_vel_y_max: 1.0
+ ang_vel_z_max: 1.0
+ aileron_max: 0.25
+ elevator_max: 0.25
+ rudder_max: 0.25
+ throttle_min: -1.0
+ throttle_max: -0.5
+ randCameraOptions:
+ d_x_max: 0.01 # 1 cm
+ d_y_max: 0
+ d_z_max: 0.01 # 1 cm
+ d_angle_max: 5 # deg
+
+mdp:
+ observation:
+ dim_action: ${...env.numActions}
+ pos_max: 40.0
+ vel_max: 20.0
+ ang_vel_max: 12 # should be synced with betaflight max rate
+ dist_to_corner_max: 20.0
+ reward:
+ k_progress: 1.0
+ k_perception: 0.02
+ k_cam_dev: -10.0
+ k_cmd_ang_vel: -4e-4
+ k_cmd_diff: -2e-4
+ k_collision: -10.0
+ k_guidance: 1.0 # or 0.0
+ k_rejection: 2.0
+ k_waypoint: 5.0
+ k_timeout: -10.0
+ guidance_x_thresh: 3.0
+ guidance_tol: 0.2
+ enable_normalization: False
+ extra_reward:
+ k_vel_lateral: -1e-3
+ k_vel_backward: -5e-3
+
+droneSim:
+ num_rotors: 4
+ rotors_x: [ -0.078665, 0.078665, -0.078665, 0.078665 ]
+ rotors_y: [ 0.097143, 0.097143, -0.097143, -0.097143 ]
+ rotors_dir: [ 1, -1, -1, 1 ]
+ drone_asset_options:
+ arm_length_front: 0.125
+ arm_length_back: 0.125
+ arm_thickness: 0.01
+ arm_front_angle: 1.780236
+ motor_diameter: 0.023
+ motor_height: 0.006
+ central_body_pos: [ 0.0, 0.0, 0.015 ]
+ central_body_dim: [ 0.15, 0.05, 0.05 ]
+ propeller_diameter: 0.12954
+ propeller_height: 0.01
+ mass: 0.76
+ center_of_mass: [ 0.0, 0.0, 0.0 ]
+ diagonal_inertia: [ 0.0025, 0.0021, 0.0043 ]
+ principle_axes_q: [ 1.0, 0.0, 0.0, 0.0 ]
+ disable_visuals: False
+ simpleBetaflight:
+ dt: ${...sim.dt}
+ center_sensitivity: [ 100.0, 100.0, 100.0 ]
+ max_rate: [ 670.0, 670.0, 670.0 ]
+ rate_expo: [ 0.0, 0.0, 0.0 ]
+ kp: [ 70.0, 70.0, 125.0 ]
+ ki: [ 0.5, 0.5, 25.0 ]
+ kd: [ 1.0, 1.0, 0.0 ]
+ kff: [ 0.0, 0.0, 0.0 ]
+ iterm_lim: [ 5.0, 5.0, 5.0 ]
+ pid_sum_lim: [ 1000.0, 1000.0, 1000.0 ]
+ dterm_lpf_cutoff: 1000
+ rotors_x: ${..rotors_x}
+ rotors_y: ${..rotors_y}
+ rotors_dir: ${..rotors_dir}
+ pid_sum_mixer_scale: 1000.0
+ output_idle: 0.05
+ throttle_boost_gain: 0.0 # disable throttle boost
+ throttle_boost_freq: 125.0
+ thrust_linearization_gain: 0.4
+ rotorPolyLag:
+ dt: ${...sim.dt}
+ num_rotors: ${..num_rotors}
+ rotors_dir: ${..rotors_dir}
+ spinup_time_constant: 0.033
+ slowdown_time_constant: 0.033
+ k_rpm_quadratic: -13421.95
+ k_rpm_linear: 37877.42
+ rotor_diagonal_inertia: [ 0.0, 0.0, 9.3575e-6 ]
+ rotor_principle_axes_q: [ 1.0, 0.0, 0.0, 0.0 ]
+ propellerPoly:
+ num_props: ${..num_rotors}
+ k_force_quadratic: 2.1549e-8
+ k_force_linear: -4.5101e-5
+ k_torque_quadratic: 4.74078e-10
+ k_torque_linear: -9.92222e-7
+ bodyDragPoly:
+ air_density: 1.204
+ a_trans: [ 1.5e-2, 1.5e-2, 3.0e-2 ]
+ k_trans_quadratic: [ 1.04, 1.04, 1.04 ]
+ k_trans_linear: [ 0.0, 0.0, 0.0 ]
+ a_rot: [ 1e-2, 1e-2, 1e-2 ]
+ k_rot_quadratic: [ 0.0, 0.0, 0.0 ]
+ k_rot_linear: [ 0.0, 0.0, 0.0 ]
+ wrenchSum:
+ num_positions: ${..num_rotors}
+ position_x: ${..rotors_x}
+ position_y: ${..rotors_y}
+ position_z: [ 0.0, 0.0, 0.0, 0.0 ]
diff --git a/isaacgymenvs/cfg/task/DRRandom.yaml b/isaacgymenvs/cfg/task/DRRandom.yaml
new file mode 100644
index 000000000..55c81f311
--- /dev/null
+++ b/isaacgymenvs/cfg/task/DRRandom.yaml
@@ -0,0 +1,99 @@
+name: DRRandom
+
+defaults:
+ - DRBase
+ - _self_
+
+envCreator:
+ env_size: 40.0
+ backstage_z_offset: 20.0
+ ground_color: [ 0.25, 0.25, 0.25 ]
+ ground_len_z: 0.3
+ gate_bar_len_x: [ 0.15 ] # thick
+ gate_bar_len_y: [ 2.0 ] # length
+ gate_bar_len_z: [ 0.225 ] # wide
+ gate_color: [ 1.0, 0.5, 0.3 ]
+ disable_tqdm: False
+ # drone asset options
+ drone_asset_options: ${..droneSim.drone_asset_options}
+ # random boxes, params: [size_x, size_y, size_z]
+ num_box_actors: 5
+ num_box_assets: 5
+ box_params_min: [ 0.3, 0.3, 0.3 ]
+ box_params_max: [ 2.0, 2.0, 2.0 ]
+ box_color: [ 0.12156862745098039, 0.4666666666666667, 0.7058823529411765 ]
+ # random capsules, params: [radius, length]
+ num_capsule_actors: 5
+ num_capsule_assets: 5
+ capsule_params_min: [ 0.3, 0.3 ]
+ capsule_params_max: [ 1.0, 1.0 ]
+ capsule_color: [ 0.7294117647058823, 0.21176470588235294, 0.3411764705882353 ]
+ # random cuboid wireframes, params: [size_x, size_y, size_z, weight]
+ num_cuboid_wireframe_actors: 0
+ num_cuboid_wireframe_assets: 0
+ cuboid_wireframe_params_min: [ 0.3, 0.3, 0.3, 0.2 ]
+ cuboid_wireframe_params_max: [ 2.0, 2.0, 2.0, 0.4 ]
+ cuboid_wireframe_color: [ 0.5803921568627451, 0.403921568627451, 0.7411764705882353 ]
+ # random cylinders, params: [radius, length]
+ num_cylinder_actors: 5
+ num_cylinder_assets: 5
+ cylinder_params_min: [ 0.1, 0.2 ]
+ cylinder_params_max: [ 1.0, 2.0 ]
+ cylinder_color: [ 0.5490196078431373, 0.33725490196078434, 0.29411764705882354 ]
+ # random hollow cuboids, params: [length_x, inner_length_y, inner_length_z, diff_length_y, diff_length_z]
+ num_hollow_cuboid_actors: 0
+ num_hollow_cuboid_assets: 0
+ hollow_cuboid_params_min: [ 0.10, 0.5, 0.5, 0.2, 0.2 ]
+ hollow_cuboid_params_max: [ 0.25, 1.4, 1.4, 0.6, 0.6 ]
+ hollow_cuboid_color: [ 0.8901960784313725, 0.4666666666666667, 0.7607843137254902 ]
+ # random spheres, params: [radius]
+ num_sphere_actors: 5
+ num_sphere_assets: 5
+ sphere_params_min: [ 0.3 ]
+ sphere_params_max: [ 1.0 ]
+ sphere_color: [ 0.7372549019607844, 0.7411764705882353, 0.13333333333333333 ]
+ # random trees, params: none
+ num_tree_actors: 0
+ num_tree_assets: 0
+ tree_color: [ 0.4196078431372549, 0.5411764705882353, 0.47843137254901963 ]
+ # random walls, params: [size_x, size_y, size_z]
+ num_wall_actors: 5
+ num_wall_assets: 5
+ wall_params_min: [ 0.2, 1.5, 1.5 ]
+ wall_params_max: [ 0.2, 2.5, 2.5 ]
+ wall_color: [ 0.09019607843137255, 0.7450980392156863, 0.8117647058823529 ]
+
+disableObstacleManager: False
+
+waypointGenerator:
+ num_waypoints: 4
+ num_gate_x_lens: 1 # check envCreator.gate_bar_len_x
+ num_gate_weights: 1 # check envCreator.gate_bar_len_z
+ gate_weight_max: 0.225 # check envCreator.gate_bar_len_z
+ fixed_waypoint_id: 1
+ fixed_waypoint_position: [ 0.0, 0.0, 20.0 ]
+
+initRandOpt:
+ randWaypointOptions:
+ wp_size_min: 1.2 # check gate_bar_len_y
+ wp_size_max: 2.0
+ init_roll_max: 0.5
+ init_pitch_max: 0.5
+ init_yaw_max: 3.14
+ psi_max: 1.57
+ theta_max: 0.79
+ alpha_max: 3.14
+ gamma_max: 0.5
+ r_min: 0.0
+ r_max: 20.0
+ force_gate_flag: 1
+ same_track: False
+ randObstacleOptions:
+ extra_clearance: 1.42
+ orbit_density: 0.05
+ tree_density: 0.05
+ wall_density: 0.05
+ wall_dist_scale: 1.0
+ std_dev_scale: 1.0
+ gnd_distance_min: 1.0
+ gnd_distance_max: 10.0
diff --git a/isaacgymenvs/cfg/train/DRAssetPPO.yaml b/isaacgymenvs/cfg/train/DRAssetPPO.yaml
new file mode 100644
index 000000000..c9af557c7
--- /dev/null
+++ b/isaacgymenvs/cfg/train/DRAssetPPO.yaml
@@ -0,0 +1,66 @@
+params:
+ seed: ${...seed}
+
+ algo:
+ name: a2c_continuous
+
+ model:
+ name: continuous_a2c_logstd
+
+ network:
+ name: actor_critic
+ separate: False
+ space:
+ continuous:
+ mu_activation: None
+ sigma_activation: None
+ mu_init:
+ name: default
+ sigma_init:
+ name: const_initializer
+ val: 0
+ fixed_sigma: True
+ mlp:
+ units: [ 256, 128, 128, 64 ]
+ activation: elu
+ d2rl: False
+ initializer:
+ name: default
+ regularizer:
+ name: None
+
+ load_checkpoint: ${if:${...checkpoint},True,False} # flag which sets whether to load the checkpoint
+ load_path: ${...checkpoint} # path to the checkpoint to load
+
+ config:
+ name: ${resolve_default:DRAsset,${....experiment}}
+ full_experiment_name: ${.name}
+ env_name: rlgpu
+ multi_gpu: ${....multi_gpu}
+ ppo: True
+ mixed_precision: False
+ normalize_input: False # already normalized in env
+ normalize_value: True
+ num_actors: ${....task.env.numEnvs}
+ reward_shaper:
+ scale_value: 0.1
+ normalize_advantage: True
+ gamma: 0.99
+ tau: 0.95
+ learning_rate: 1e-3
+ lr_schedule: adaptive
+ kl_threshold: 0.016
+ score_to_win: 20000
+ max_epochs: ${resolve_default:500,${....max_iterations}}
+ save_best_after: 50
+ save_frequency: 50
+ grad_norm: 1.0
+ entropy_coef: 0.0
+ truncate_grads: True
+ e_clip: 0.2
+ horizon_length: 100
+ minibatch_size: 102400
+ mini_epochs: 8
+ critic_coef: 2
+ clip_value: True
+ bounds_loss_coef: 0.0001
diff --git a/isaacgymenvs/cfg/train/DRRandomPPO.yaml b/isaacgymenvs/cfg/train/DRRandomPPO.yaml
new file mode 100644
index 000000000..6849f8d62
--- /dev/null
+++ b/isaacgymenvs/cfg/train/DRRandomPPO.yaml
@@ -0,0 +1,66 @@
+params:
+ seed: ${...seed}
+
+ algo:
+ name: a2c_continuous
+
+ model:
+ name: continuous_a2c_logstd
+
+ network:
+ name: actor_critic
+ separate: False
+ space:
+ continuous:
+ mu_activation: None
+ sigma_activation: None
+ mu_init:
+ name: default
+ sigma_init:
+ name: const_initializer
+ val: 0
+ fixed_sigma: True
+ mlp:
+ units: [ 256, 128, 128, 64 ]
+ activation: elu
+ d2rl: False
+ initializer:
+ name: default
+ regularizer:
+ name: None
+
+ load_checkpoint: ${if:${...checkpoint},True,False} # flag which sets whether to load the checkpoint
+ load_path: ${...checkpoint} # path to the checkpoint to load
+
+ config:
+ name: ${resolve_default:DRRandom,${....experiment}}
+ full_experiment_name: ${.name}
+ env_name: rlgpu
+ multi_gpu: ${....multi_gpu}
+ ppo: True
+ mixed_precision: False
+ normalize_input: False # already normalized in env
+ normalize_value: True
+ num_actors: ${....task.env.numEnvs}
+ reward_shaper:
+ scale_value: 0.1
+ normalize_advantage: True
+ gamma: 0.99
+ tau: 0.95
+ learning_rate: 1e-3
+ lr_schedule: adaptive
+ kl_threshold: 0.016
+ score_to_win: 20000
+ max_epochs: ${resolve_default:500,${....max_iterations}}
+ save_best_after: 50
+ save_frequency: 50
+ grad_norm: 1.0
+ entropy_coef: 0.0
+ truncate_grads: True
+ e_clip: 0.2
+ horizon_length: 100
+ minibatch_size: 25600
+ mini_epochs: 8
+ critic_coef: 2
+ clip_value: True
+ bounds_loss_coef: 0.0001
diff --git a/isaacgymenvs/learning/dr_agent.py b/isaacgymenvs/learning/dr_agent.py
new file mode 100644
index 000000000..21334c5a6
--- /dev/null
+++ b/isaacgymenvs/learning/dr_agent.py
@@ -0,0 +1,463 @@
+import os
+import time
+
+import numpy as np
+import torch
+import torch.distributed as dist
+from rl_games.algos_torch import torch_ext
+from rl_games.algos_torch.a2c_continuous import A2CAgent
+from rl_games.common.a2c_common import print_statistics, swap_and_flatten01
+from typing import Optional
+from tqdm import tqdm
+
+
+class DRAgent(A2CAgent):
+
+ def __init__(self, base_name, params):
+ print("+++ DRAgent")
+
+ self.dones: Optional[torch.Tensor] = None
+ self.current_rewards: Optional[torch.Tensor] = None
+ self.current_shaped_rewards: Optional[torch.Tensor] = None
+ self.current_lengths: Optional[torch.Tensor] = None
+ self.current_rewards_progress: Optional[torch.Tensor] = None
+ self.current_rewards_perception: Optional[torch.Tensor] = None
+ self.current_rewards_cmd: Optional[torch.Tensor] = None
+ self.current_rewards_collision: Optional[torch.Tensor] = None
+ self.current_rewards_guidance: Optional[torch.Tensor] = None
+ self.current_rewards_waypoint: Optional[torch.Tensor] = None
+ self.current_rewards_timeout: Optional[torch.Tensor] = None
+ self.current_rewards_lin_vel: Optional[torch.Tensor] = None
+
+ super().__init__(base_name, params)
+
+ # we want to track separate reward terms
+ self.game_rewards_progress = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+ self.game_rewards_perception = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+ self.game_rewards_cmd = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+ self.game_rewards_collision = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+ self.game_rewards_guidance = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+ self.game_rewards_waypoint = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+ self.game_rewards_timeout = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+ self.game_rewards_lin_vel = torch_ext.AverageMeter(
+ self.value_size, self.games_to_track
+ ).to(self.ppo_device)
+
+ print(self.model)
+
+ def train(self):
+ self.init_tensors()
+ self.last_mean_rewards = -100500
+ total_time = 0
+ # NOTE: reset before every rollout
+ # self.obs = self.env_reset()
+ self.curr_frames = self.batch_size_envs
+
+ if self.multi_gpu:
+ print("+++ broadcasting parameters")
+ model_params = [self.model.state_dict()]
+ dist.broadcast_object_list(model_params, 0)
+ self.model.load_state_dict(model_params[0])
+
+ while True:
+ # Note: reset before every rollout
+ # TODO: enable from cfg?
+ print("DRAgent: resetting envs")
+ self.obs = self.env_reset()
+ epoch_num = self.update_epoch()
+ (
+ step_time,
+ play_time,
+ update_time,
+ sum_time,
+ a_losses,
+ c_losses,
+ b_losses,
+ entropies,
+ kls,
+ last_lr,
+ lr_mul,
+ ) = self.train_epoch()
+ total_time += sum_time
+ frame = self.frame // self.num_agents
+
+ # cleaning memory to optimize space
+ self.dataset.update_values_dict(None)
+ should_exit = False
+
+ if self.global_rank == 0:
+ self.diagnostics.epoch(self, current_epoch=epoch_num)
+ # do we need scaled_time?
+ scaled_time = self.num_agents * sum_time
+ scaled_play_time = self.num_agents * play_time
+ curr_frames = (
+ self.curr_frames * self.world_size
+ if self.multi_gpu
+ else self.curr_frames
+ )
+ self.frame += curr_frames
+
+ print_statistics(
+ self.print_stats,
+ curr_frames,
+ step_time,
+ scaled_play_time,
+ scaled_time,
+ epoch_num,
+ self.max_epochs,
+ frame,
+ self.max_frames,
+ )
+
+ self.write_stats(
+ total_time,
+ epoch_num,
+ step_time,
+ play_time,
+ update_time,
+ a_losses,
+ c_losses,
+ entropies,
+ kls,
+ last_lr,
+ lr_mul,
+ frame,
+ scaled_time,
+ scaled_play_time,
+ curr_frames,
+ )
+
+ if len(b_losses) > 0:
+ self.writer.add_scalar(
+ "losses/bounds_loss",
+ torch_ext.mean_list(b_losses).item(),
+ frame,
+ )
+
+ if self.has_soft_aug:
+ raise NotImplementedError
+
+ mean_rewards = None
+ if self.game_rewards.current_size > 0:
+ mean_rewards = self.game_rewards.get_mean()
+ mean_shaped_rewards = self.game_shaped_rewards.get_mean()
+ mean_lengths = self.game_lengths.get_mean()
+ self.mean_rewards = mean_rewards[0]
+
+ for i in range(self.value_size):
+ rewards_name = "rewards" if i == 0 else "rewards{0}".format(i)
+ self.writer.add_scalar(
+ rewards_name + "/step".format(i), mean_rewards[i], frame
+ )
+ self.writer.add_scalar(
+ rewards_name + "/iter".format(i), mean_rewards[i], epoch_num
+ )
+ self.writer.add_scalar(
+ rewards_name + "/time".format(i),
+ mean_rewards[i],
+ total_time,
+ )
+ self.writer.add_scalar(
+ "shaped_" + rewards_name + "/step".format(i),
+ mean_shaped_rewards[i],
+ frame,
+ )
+ self.writer.add_scalar(
+ "shaped_" + rewards_name + "/iter".format(i),
+ mean_shaped_rewards[i],
+ epoch_num,
+ )
+ self.writer.add_scalar(
+ "shaped_" + rewards_name + "/time".format(i),
+ mean_shaped_rewards[i],
+ total_time,
+ )
+
+ # NOTE: add more entries to writer
+ # TODO: better place to put all these?
+ self.writer.add_scalar(
+ "rewards/progress/step",
+ self.game_rewards_progress.get_mean()[0],
+ frame,
+ )
+ self.writer.add_scalar(
+ "rewards/perception/step",
+ self.game_rewards_perception.get_mean()[0],
+ frame,
+ )
+ self.writer.add_scalar(
+ "rewards/cmd/step",
+ self.game_rewards_cmd.get_mean()[0],
+ frame,
+ )
+ self.writer.add_scalar(
+ "rewards/collision/step",
+ self.game_rewards_collision.get_mean()[0],
+ frame,
+ )
+ self.writer.add_scalar(
+ "rewards/guidance/step",
+ self.game_rewards_guidance.get_mean()[0],
+ frame,
+ )
+ self.writer.add_scalar(
+ "rewards/waypoint/step",
+ self.game_rewards_waypoint.get_mean()[0],
+ frame,
+ )
+ self.writer.add_scalar(
+ "rewards/collision/step",
+ self.game_rewards_collision.get_mean()[0],
+ frame,
+ )
+ self.writer.add_scalar(
+ "rewards/lin_vel/step",
+ self.game_rewards_lin_vel.get_mean()[0],
+ frame,
+ )
+
+ self.writer.add_scalar("episode_lengths/step", mean_lengths, frame)
+ self.writer.add_scalar(
+ "episode_lengths/iter", mean_lengths, epoch_num
+ )
+ self.writer.add_scalar(
+ "episode_lengths/time", mean_lengths, total_time
+ )
+
+ if self.has_self_play_config:
+ self.self_play_manager.update(self)
+
+ checkpoint_name = (
+ self.config["name"]
+ + "_ep_"
+ + str(epoch_num)
+ + "_rew_"
+ + str(mean_rewards[0])
+ )
+
+ if self.save_freq > 0:
+ if epoch_num % self.save_freq == 0:
+ self.save(
+ os.path.join(self.nn_dir, "last_" + checkpoint_name)
+ )
+
+ if (
+ mean_rewards[0] > self.last_mean_rewards
+ and epoch_num >= self.save_best_after
+ ):
+ print("saving next best rewards: ", mean_rewards)
+ self.last_mean_rewards = mean_rewards[0]
+ self.save(os.path.join(self.nn_dir, self.config["name"]))
+
+ if "score_to_win" in self.config:
+ if self.last_mean_rewards > self.config["score_to_win"]:
+ print("Maximum reward achieved. Network won!")
+ self.save(os.path.join(self.nn_dir, checkpoint_name))
+ should_exit = True
+
+ if epoch_num >= self.max_epochs != -1:
+ if self.game_rewards.current_size == 0:
+ print(
+ "WARNING: Max epochs reached before any env terminated at least once"
+ )
+ mean_rewards = -np.inf
+
+ self.save(
+ os.path.join(
+ self.nn_dir,
+ "last_"
+ + self.config["name"]
+ + "_ep_"
+ + str(epoch_num)
+ + "_rew_"
+ + str(mean_rewards).replace("[", "_").replace("]", "_"),
+ )
+ )
+ print("MAX EPOCHS NUM!")
+ should_exit = True
+
+ if self.frame >= self.max_frames != -1:
+ if self.game_rewards.current_size == 0:
+ print(
+ "WARNING: Max frames reached before any env terminated at least once"
+ )
+ mean_rewards = -np.inf
+
+ self.save(
+ os.path.join(
+ self.nn_dir,
+ "last_"
+ + self.config["name"]
+ + "_frame_"
+ + str(self.frame)
+ + "_rew_"
+ + str(mean_rewards).replace("[", "_").replace("]", "_"),
+ )
+ )
+ print("MAX FRAMES NUM!")
+ should_exit = True
+
+ if self.multi_gpu:
+ should_exit_t = torch.tensor(should_exit, device=self.device).float()
+ dist.broadcast(should_exit_t, 0)
+ should_exit = should_exit_t.float().item()
+ if should_exit:
+ return self.last_mean_rewards, epoch_num
+
+ if should_exit:
+ return self.last_mean_rewards, epoch_num
+
+ def init_tensors(self):
+ super().init_tensors()
+ self.current_rewards_progress = torch.zeros_like(self.current_rewards)
+ self.current_rewards_perception = torch.zeros_like(self.current_rewards)
+ self.current_rewards_cmd = torch.zeros_like(self.current_rewards)
+ self.current_rewards_collision = torch.zeros_like(self.current_rewards)
+ self.current_rewards_guidance = torch.zeros_like(self.current_rewards)
+ self.current_rewards_waypoint = torch.zeros_like(self.current_rewards)
+ self.current_rewards_timeout = torch.zeros_like(self.current_rewards)
+ self.current_rewards_lin_vel = torch.zeros_like(self.current_rewards)
+
+ def play_steps(self):
+ update_list = self.update_list
+
+ step_time = 0.0
+
+ for n in tqdm(range(self.horizon_length)):
+ if self.use_action_masks:
+ masks = self.vec_env.get_action_masks()
+ res_dict = self.get_masked_action_values(self.obs, masks)
+ else:
+ res_dict = self.get_action_values(self.obs)
+ self.experience_buffer.update_data("obses", n, self.obs["obs"])
+ self.experience_buffer.update_data("dones", n, self.dones)
+
+ for k in update_list:
+ self.experience_buffer.update_data(k, n, res_dict[k])
+ if self.has_central_value:
+ self.experience_buffer.update_data("states", n, self.obs["states"])
+
+ step_time_start = time.time()
+ self.obs, rewards, self.dones, infos = self.env_step(res_dict["actions"])
+ step_time_end = time.time()
+
+ step_time += step_time_end - step_time_start
+
+ shaped_rewards = self.rewards_shaper(rewards)
+ if self.value_bootstrap and "time_outs" in infos:
+ shaped_rewards += (
+ self.gamma
+ * res_dict["values"]
+ * self.cast_obs(infos["time_outs"]).unsqueeze(1).float()
+ )
+
+ self.experience_buffer.update_data("rewards", n, shaped_rewards)
+
+ self.current_rewards += rewards
+ self.current_rewards_progress += infos["reward_progress"].unsqueeze(1)
+ self.current_rewards_perception += infos["reward_perception"].unsqueeze(1)
+ self.current_rewards_cmd += infos["reward_cmd"].unsqueeze(1)
+ self.current_rewards_collision += infos["reward_collision"].unsqueeze(1)
+ self.current_rewards_guidance += infos["reward_guidance"].unsqueeze(1)
+ self.current_rewards_waypoint += infos["reward_waypoint"].unsqueeze(1)
+ self.current_rewards_timeout += infos["reward_timeout"].unsqueeze(1)
+ self.current_rewards_lin_vel += infos["reward_lin_vel"].unsqueeze(1)
+ self.current_shaped_rewards += shaped_rewards
+ self.current_lengths += 1
+ all_done_indices = self.dones.nonzero(as_tuple=False)
+ env_done_indices = all_done_indices[:: self.num_agents]
+
+ self.game_rewards.update(self.current_rewards[env_done_indices])
+ self.game_rewards_progress.update(
+ self.current_rewards_progress[env_done_indices]
+ )
+ self.game_rewards_perception.update(
+ self.current_rewards_perception[env_done_indices]
+ )
+ self.game_rewards_cmd.update(self.current_rewards_cmd[env_done_indices])
+ self.game_rewards_collision.update(
+ self.current_rewards_collision[env_done_indices]
+ )
+ self.game_rewards_guidance.update(
+ self.current_rewards_guidance[env_done_indices]
+ )
+ self.game_rewards_waypoint.update(
+ self.current_rewards_waypoint[env_done_indices]
+ )
+ self.game_rewards_timeout.update(
+ self.current_rewards_timeout[env_done_indices]
+ )
+ self.game_rewards_lin_vel.update(
+ self.current_rewards_lin_vel[env_done_indices]
+ )
+ self.game_shaped_rewards.update(
+ self.current_shaped_rewards[env_done_indices]
+ )
+ self.game_lengths.update(self.current_lengths[env_done_indices])
+ self.algo_observer.process_infos(infos, env_done_indices)
+
+ not_dones = 1.0 - self.dones.float()
+ not_dones_un_sq = not_dones.unsqueeze(1)
+
+ self.current_rewards = self.current_rewards * not_dones_un_sq
+ self.current_rewards_progress = (
+ self.current_rewards_progress * not_dones_un_sq
+ )
+ self.current_rewards_perception = (
+ self.current_rewards_perception * not_dones_un_sq
+ )
+ self.current_rewards_cmd = self.current_rewards_cmd * not_dones_un_sq
+ self.current_rewards_collision = (
+ self.current_rewards_collision * not_dones_un_sq
+ )
+ self.current_rewards_guidance = (
+ self.current_rewards_guidance * not_dones_un_sq
+ )
+ self.current_rewards_waypoint = (
+ self.current_rewards_waypoint * not_dones_un_sq
+ )
+ self.current_rewards_timeout = (
+ self.current_rewards_timeout * not_dones_un_sq
+ )
+ self.current_rewards_lin_vel = (
+ self.current_rewards_lin_vel * not_dones_un_sq
+ )
+ self.current_shaped_rewards = self.current_shaped_rewards * not_dones_un_sq
+ self.current_lengths = self.current_lengths * not_dones
+
+ last_values = self.get_values(self.obs)
+
+ fdones = self.dones.float()
+ mb_fdones = self.experience_buffer.tensor_dict["dones"].float()
+ mb_values = self.experience_buffer.tensor_dict["values"]
+ mb_rewards = self.experience_buffer.tensor_dict["rewards"]
+ mb_advs = self.discount_values(
+ fdones, last_values, mb_fdones, mb_values, mb_rewards
+ )
+ mb_returns = mb_advs + mb_values
+
+ batch_dict = self.experience_buffer.get_transformed_list(
+ swap_and_flatten01, self.tensor_list
+ )
+ batch_dict["returns"] = swap_and_flatten01(mb_returns)
+ batch_dict["played_frames"] = self.batch_size
+ batch_dict["step_time"] = step_time
+
+ return batch_dict
+
+ def play_steps_rnn(self):
+ raise NotImplementedError("Not tested")
diff --git a/isaacgymenvs/tasks/__init__.py b/isaacgymenvs/tasks/__init__.py
index 0efd35b86..19df4d4b6 100644
--- a/isaacgymenvs/tasks/__init__.py
+++ b/isaacgymenvs/tasks/__init__.py
@@ -56,6 +56,7 @@
from .industreal.industreal_task_pegs_insert import IndustRealTaskPegsInsert
from .industreal.industreal_task_gears_insert import IndustRealTaskGearsInsert
+from .drone_racing.tasks import DRAsset, DRRandom
def resolve_allegro_kuka(cfg, *args, **kwargs):
subtask_name: str = cfg["env"]["subtask"]
@@ -96,6 +97,8 @@ def resolve_allegro_kuka_two_arms(cfg, *args, **kwargs):
"AnymalTerrain": AnymalTerrain,
"BallBalance": BallBalance,
"Cartpole": Cartpole,
+ "DRAsset": DRAsset,
+ "DRRandom": DRRandom,
"FactoryTaskGears": FactoryTaskGears,
"FactoryTaskInsertion": FactoryTaskInsertion,
"FactoryTaskNutBoltPick": FactoryTaskNutBoltPick,
diff --git a/isaacgymenvs/tasks/drone_racing/assets/__init__.py b/isaacgymenvs/tasks/drone_racing/assets/__init__.py
new file mode 100644
index 000000000..5a4ab1bbd
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/__init__.py
@@ -0,0 +1,9 @@
+"""
+Package containing functions for creating procedural assets.
+"""
+
+from .collections import *
+from .drones import *
+from .geometries import *
+from .tracks import *
+from .utils import *
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/__init__.py b/isaacgymenvs/tasks/drone_racing/assets/collections/__init__.py
new file mode 100644
index 000000000..38f9cadd1
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/__init__.py
@@ -0,0 +1,10 @@
+from .box import CollectionBoxOptions, CollectionBox
+from .capsule import CollectionCapsuleOptions, CollectionCapsule
+from .cuboid_wireframe import (
+ CollectionCuboidWireframeOptions,
+ CollectionCuboidWireframe,
+)
+from .cylinder import CollectionCylinderOptions, CollectionCylinder
+from .hollow_cuboid import CollectionHollowCuboidOptions, CollectionHollowCuboid
+from .sphere import CollectionSphereOptions, CollectionSphere
+from .tree import CollectionTreeOptions, CollectionTree
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/base.py b/isaacgymenvs/tasks/drone_racing/assets/collections/base.py
new file mode 100644
index 000000000..15025e505
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/base.py
@@ -0,0 +1,101 @@
+import abc
+from dataclasses import dataclass
+from typing import List, Optional
+
+import torch
+from tqdm import tqdm
+
+from isaacgym.gymapi import Gym, Sim, Asset, AssetOptions
+
+
+@dataclass
+class CollectionBaseOptions:
+ # number of envs
+ num_envs: int = 64
+
+ # number of assets per env
+ num_assets: int = 10
+
+ # number of total random blueprints
+ num_blueprints: int = 100
+
+ # asset options
+ asset_options: AssetOptions = AssetOptions()
+
+ # if true, the process of loading assets won't be printed
+ disable_tqdm: bool = False
+
+ # minimum value of params
+ params_min: Optional[List[float]] = None
+
+ # maximum value of params
+ params_max: Optional[List[float]] = None
+
+
+class CollectionBase:
+ def __init__(self, gym: Gym, sim: Sim, options: CollectionBaseOptions):
+ self.gym = gym
+ self.sim = sim
+ self.options: CollectionBaseOptions = options
+
+ self.params_rand: Optional[List[List[float]]] = None
+ self.ids_rand: Optional[List[List[int]]] = None
+ self.generate_rand()
+
+ self.assets: Optional[List[List[Asset]]] = None
+ self.load_assets()
+
+ def generate_rand(self):
+ # random params for blueprints
+ if self.options.params_min is not None and self.options.params_max is not None:
+ assert len(self.options.params_min) == len(self.options.params_max)
+ num_params = len(self.options.params_min)
+
+ p_min = torch.tensor(self.options.params_min)
+ p_min.clamp_(min=0.01)
+ p_max = torch.tensor(self.options.params_max)
+ p_max.clamp_(min=p_min)
+ p_range = p_max - p_min
+
+ p_rand = torch.rand(self.options.num_blueprints, num_params)
+ p_rand = p_rand * p_range + p_min
+
+ self.params_rand = p_rand.tolist()
+
+ else:
+ self.params_rand = []
+
+ # random ids for selecting blueprints
+ if self.options.num_assets > 0:
+ self.ids_rand = torch.randint(
+ 0,
+ self.options.num_blueprints,
+ (self.options.num_envs, self.options.num_assets),
+ ).tolist()
+ else:
+ self.ids_rand = []
+
+ def load_assets(self):
+ # create blueprints
+ blueprints = []
+ for i in tqdm(
+ range(self.options.num_blueprints), disable=self.options.disable_tqdm
+ ):
+ blueprints.append(self.create_asset(i))
+
+ # fill the assets list
+ self.assets = []
+ for i in range(self.options.num_envs):
+ env_assets = []
+ for j in range(self.options.num_assets):
+ index = self.ids_rand[i][j]
+ env_assets.append(blueprints[index])
+ self.assets.append(env_assets)
+
+ @abc.abstractmethod
+ def create_asset(self, blueprint_id: int) -> Asset:
+ """
+ This method loads assets into the list ``assets``.
+ """
+
+ raise NotImplementedError
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/box.py b/isaacgymenvs/tasks/drone_racing/assets/collections/box.py
new file mode 100644
index 000000000..d12f336b8
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/box.py
@@ -0,0 +1,21 @@
+from dataclasses import dataclass
+
+from isaacgym.gymapi import Asset
+from .base import CollectionBaseOptions, CollectionBase
+
+
+@dataclass
+class CollectionBoxOptions(CollectionBaseOptions):
+ """
+ Params: [``size_x``, ``size_y``, ``size_z``]
+ """
+
+ params_min = [0.2, 0.2, 0.2]
+ params_max = [2.0, 2.0, 2.0]
+
+
+class CollectionBox(CollectionBase):
+ def create_asset(self, blueprint_id: int) -> Asset:
+ x, y, z = self.params_rand[blueprint_id]
+ asset = self.gym.create_box(self.sim, x, y, z, self.options.asset_options)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/capsule.py b/isaacgymenvs/tasks/drone_racing/assets/collections/capsule.py
new file mode 100644
index 000000000..d579238e9
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/capsule.py
@@ -0,0 +1,23 @@
+from dataclasses import dataclass
+
+from isaacgym.gymapi import Asset
+from .base import CollectionBaseOptions, CollectionBase
+
+
+@dataclass
+class CollectionCapsuleOptions(CollectionBaseOptions):
+ """
+ Params definition: [``radius``, ``length``]
+ """
+
+ params_min = [0.1, 0.2]
+ params_max = [1.0, 1.0]
+
+
+class CollectionCapsule(CollectionBase):
+ def create_asset(self, blueprint_id: int) -> Asset:
+ radius, length = self.params_rand[blueprint_id]
+ asset = self.gym.create_capsule(
+ self.sim, radius, length, self.options.asset_options
+ )
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/cuboid_wireframe.py b/isaacgymenvs/tasks/drone_racing/assets/collections/cuboid_wireframe.py
new file mode 100644
index 000000000..cdcc331cc
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/cuboid_wireframe.py
@@ -0,0 +1,29 @@
+from dataclasses import dataclass
+
+from isaacgym.gymapi import Asset
+from .base import CollectionBaseOptions, CollectionBase
+from ..geometries import GeomCuboidWireframeOptions, create_geom_cuboid_wireframe
+
+
+@dataclass
+class CollectionCuboidWireframeOptions(CollectionBaseOptions):
+ """
+ Params: [``size_x``, ``size_y``, ``size_z``, ``weight``]
+ """
+
+ params_min = [0.4, 0.4, 0.4, 0.1]
+ params_max = [2.0, 2.0, 2.0, 0.4]
+
+
+class CollectionCuboidWireframe(CollectionBase):
+ def create_asset(self, blueprint_id: int) -> Asset:
+ x, y, z, w = self.params_rand[blueprint_id]
+ min_xyz = min(x, y, z)
+ if w > min_xyz / 2:
+ w = min_xyz / 2
+ opts = GeomCuboidWireframeOptions()
+ opts.size = [x, y, z]
+ opts.weight = w
+ opts.asset_options = self.options.asset_options
+ asset = create_geom_cuboid_wireframe(self.gym, self.sim, opts)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/cylinder.py b/isaacgymenvs/tasks/drone_racing/assets/collections/cylinder.py
new file mode 100644
index 000000000..7cba8a447
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/cylinder.py
@@ -0,0 +1,26 @@
+from dataclasses import dataclass
+
+from isaacgym.gymapi import Asset
+from .base import CollectionBaseOptions, CollectionBase
+from ..geometries import GeomCylinderOptions, create_geom_cylinder
+
+
+@dataclass
+class CollectionCylinderOptions(CollectionBaseOptions):
+ """
+ Params: [``radius``, ``length``]
+ """
+
+ params_min = [0.1, 0.2]
+ params_max = [1.0, 2.0]
+
+
+class CollectionCylinder(CollectionBase):
+ def create_asset(self, blueprint_id: int) -> Asset:
+ radius, length = self.params_rand[blueprint_id]
+ opts = GeomCylinderOptions()
+ opts.radius = radius
+ opts.length = length
+ opts.asset_options = self.options.asset_options
+ asset = create_geom_cylinder(self.gym, self.sim, opts)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/hollow_cuboid.py b/isaacgymenvs/tasks/drone_racing/assets/collections/hollow_cuboid.py
new file mode 100644
index 000000000..258def758
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/hollow_cuboid.py
@@ -0,0 +1,26 @@
+from isaacgym.gymapi import Asset
+from .base import CollectionBaseOptions, CollectionBase
+from ..geometries import GeomHollowCuboidOptions, create_geom_hollow_cuboid
+
+
+class CollectionHollowCuboidOptions(CollectionBaseOptions):
+ """
+ Params: [``length_x``, ``inner_length_y``, ``inner_length_z``, ``diff_length_y``, ``diff_length_z``]
+ """
+
+ params_min = [0.05, 0.5, 0.5, 0.2, 0.2]
+ params_max = [0.2, 1.5, 1.5, 0.8, 0.8]
+
+
+class CollectionHollowCuboid(CollectionBase):
+ def create_asset(self, blueprint_id: int) -> Asset:
+ x, in_y, in_z, d_y, d_z = self.params_rand[blueprint_id]
+ opts = GeomHollowCuboidOptions()
+ opts.length_x = x
+ opts.inner_length_y = in_y
+ opts.inner_length_z = in_z
+ opts.outer_length_y = in_y + d_y
+ opts.outer_length_z = in_z + d_z
+ opts.asset_options = self.options.asset_options
+ asset = create_geom_hollow_cuboid(self.gym, self.sim, opts)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/sphere.py b/isaacgymenvs/tasks/drone_racing/assets/collections/sphere.py
new file mode 100644
index 000000000..5f3cfe2cc
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/sphere.py
@@ -0,0 +1,21 @@
+from dataclasses import dataclass
+
+from isaacgym.gymapi import Asset
+from .base import CollectionBaseOptions, CollectionBase
+
+
+@dataclass
+class CollectionSphereOptions(CollectionBaseOptions):
+ """
+ Params: [``radius``]
+ """
+
+ params_min = [0.1]
+ params_max = [1.0]
+
+
+class CollectionSphere(CollectionBase):
+ def create_asset(self, blueprint_id: int) -> Asset:
+ r = self.params_rand[blueprint_id][0]
+ asset = self.gym.create_sphere(self.sim, r, self.options.asset_options)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/collections/tree.py b/isaacgymenvs/tasks/drone_racing/assets/collections/tree.py
new file mode 100644
index 000000000..47aa37dd3
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/collections/tree.py
@@ -0,0 +1,26 @@
+import os
+from dataclasses import dataclass
+
+from isaacgym.gymapi import Asset
+from .base import CollectionBaseOptions, CollectionBase
+
+
+@dataclass
+class CollectionTreeOptions(CollectionBaseOptions):
+ params_min = None
+ params_max = None
+
+
+class CollectionTree(CollectionBase):
+ def create_asset(self, blueprint_id: int) -> Asset:
+ asset_dir: str = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "../../../../../assets/urdf/aerial_gym_trees",
+ )
+ asset = self.gym.load_asset(
+ self.sim,
+ asset_dir,
+ "tree_" + str(blueprint_id) + ".urdf",
+ self.options.asset_options,
+ )
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/drones/__init__.py b/isaacgymenvs/tasks/drone_racing/assets/drones/__init__.py
new file mode 100644
index 000000000..9bd1db31a
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/drones/__init__.py
@@ -0,0 +1 @@
+from .quadcopter import DroneQuadcopterOptions, create_drone_quadcopter
diff --git a/isaacgymenvs/tasks/drone_racing/assets/drones/quadcopter.py b/isaacgymenvs/tasks/drone_racing/assets/drones/quadcopter.py
new file mode 100644
index 000000000..08e305b60
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/drones/quadcopter.py
@@ -0,0 +1,291 @@
+import math
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+import numpy as np
+import urdfpy
+from scipy.spatial.transform import Rotation
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils.urdf_utils import export_urdf
+
+
+@dataclass
+class DroneQuadcopterOptions:
+ """
+ Configuration for the quadcopter in FLU body frame convention.
+
+ The center of body frame is the crossing point of the arms,
+ on the upper surface of the arm plate.
+
+ Collision shape is the minimum bounding box of the quadcopter,
+ and is automatically computed.
+ """
+
+ # file name
+ file_name: str = "drone_quadcopter"
+
+ # length of the two front arms [m]
+ arm_length_front: float = 0.125
+
+ # length of the two back arms [m]
+ arm_length_back: float = 0.125
+
+ # thickness of the arm plate [m]
+ arm_thickness: float = 0.01
+
+ # separation angle between two front arms [rad]
+ arm_front_angle: float = 1.780236
+
+ # diameter of the motor cylinder [m]
+ motor_diameter: float = 0.023
+
+ # height of the motor cylinder [m]
+ motor_height: float = 0.006
+
+ # central body cuboid position in body frame [m]
+ central_body_pos: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.015])
+
+ # central body cuboid dimension [m]
+ central_body_dim: List[float] = field(default_factory=lambda: [0.15, 0.05, 0.05])
+
+ # propeller cylinder diameter [m]
+ propeller_diameter: float = 0.12954
+
+ # propeller cylinder height [m]
+ propeller_height: float = 0.01
+
+ # mass of the whole quadcopter treated as a rigid body
+ mass: float = 0.752
+
+ # center of mass position in body frame [m]
+ center_of_mass: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.0])
+
+ # diagonal inertia in [kg m^2]
+ diagonal_inertia: List[float] = field(
+ default_factory=lambda: [0.0025, 0.0021, 0.0043]
+ )
+
+ # quaternion representing the principle axes matrix [w, x, y, z]
+ principle_axes_q: List[float] = field(default_factory=lambda: [1.0, 0.0, 0.0, 0.0])
+
+ # options for importing into Isaac Gym
+ asset_options: AssetOptions = AssetOptions()
+
+ # disable visuals to avoid blocking camera sensors
+ disable_visuals: bool = False
+
+
+def create_drone_quadcopter(
+ gym: Gym, sim: Sim, options: DroneQuadcopterOptions
+) -> Asset:
+ """
+ Create a quadcopter asset.
+
+ Args:
+ gym: returned by ``acquire_gym``.
+ sim: simulation handle.
+ options: options for visual, collision, inertia, and importing.
+
+ Returns:
+ - An asset object as the return of calling ``load_asset``.
+ """
+
+ # ========== inertial ==========
+
+ principle_axes_r = Rotation.from_quat(
+ np.array(options.principle_axes_q)[[1, 2, 3, 0]]
+ )
+ inertial_origin = np.zeros((4, 4))
+ inertial_origin[:3, :3] = principle_axes_r.as_matrix()
+ inertial_origin[:3, -1] = options.center_of_mass
+ inertial_origin[-1, -1] = 1
+ inertial = urdfpy.Inertial(
+ mass=options.mass,
+ inertia=np.diag(options.diagonal_inertia),
+ origin=inertial_origin,
+ )
+
+ # ========== collisions ==========
+
+ collisions: List[urdfpy.Collision] = []
+
+ collision_box_pos, collision_box_dim = _get_collision_box(options)
+ collision_geometry = urdfpy.Geometry(box=urdfpy.Box(collision_box_dim))
+ collision_origin = urdfpy.xyz_rpy_to_matrix(collision_box_pos + [0, 0, 0])
+ collision = urdfpy.Collision(
+ name=None, origin=collision_origin, geometry=collision_geometry
+ )
+ collisions.append(collision)
+
+ # ========== visuals ==========
+
+ visuals: List[urdfpy.Visual] = []
+
+ # central body
+ central_body_geometry = urdfpy.Geometry(box=urdfpy.Box(options.central_body_dim))
+ central_body_origin = urdfpy.xyz_rpy_to_matrix(options.central_body_pos + [0, 0, 0])
+ central_body_visual = urdfpy.Visual(
+ geometry=central_body_geometry, origin=central_body_origin
+ )
+ visuals.append(central_body_visual)
+
+ # arm 1, 4
+ arm_offset = (
+ options.arm_length_front + options.arm_length_back
+ ) / 2 - options.arm_length_back
+ arm_14_geometry = urdfpy.Geometry(
+ box=urdfpy.Box(
+ [
+ options.arm_length_front + options.arm_length_back,
+ options.motor_diameter,
+ options.arm_thickness,
+ ]
+ )
+ )
+ arm_14_xyz = [
+ math.cos(options.arm_front_angle / 2) * arm_offset,
+ math.sin(options.arm_front_angle / 2) * arm_offset,
+ -options.arm_thickness / 2,
+ ]
+
+ arm_14_rpy = [0, 0, options.arm_front_angle / 2]
+ arm_14_origin = urdfpy.xyz_rpy_to_matrix(arm_14_xyz + arm_14_rpy)
+ arm_14_visual = urdfpy.Visual(geometry=arm_14_geometry, origin=arm_14_origin)
+ visuals.append(arm_14_visual)
+
+ # arm 2, 3
+ arm_23_geometry = arm_14_geometry
+ arm_23_xyz = [
+ math.cos(options.arm_front_angle / 2) * arm_offset,
+ -math.sin(options.arm_front_angle / 2) * arm_offset,
+ -options.arm_thickness / 2,
+ ]
+
+ arm_23_rpy = [0, 0, -options.arm_front_angle / 2]
+ arm_23_origin = urdfpy.xyz_rpy_to_matrix(arm_23_xyz + arm_23_rpy)
+ arm_23_visual = urdfpy.Visual(geometry=arm_23_geometry, origin=arm_23_origin)
+ visuals.append(arm_23_visual)
+
+ # rotors
+ rotor_angles = [
+ options.arm_front_angle / 2 + math.pi,
+ -options.arm_front_angle / 2,
+ -options.arm_front_angle / 2 + math.pi,
+ options.arm_front_angle / 2,
+ ]
+ for i in [1, 2, 3, 4]:
+ if i == 1 or i == 3:
+ arm_length = options.arm_length_back
+ else:
+ arm_length = options.arm_length_front
+ # motor
+ motor_geometry = urdfpy.Geometry(
+ cylinder=urdfpy.Cylinder(
+ radius=options.motor_diameter / 2,
+ length=options.motor_height + options.arm_thickness,
+ )
+ )
+ motor_xyz = [
+ math.cos(rotor_angles[i - 1]) * arm_length,
+ math.sin(rotor_angles[i - 1]) * arm_length,
+ (options.motor_height + options.arm_thickness) / 2 - options.arm_thickness,
+ ]
+
+ motor_origin = urdfpy.xyz_rpy_to_matrix(motor_xyz + [0, 0, 0])
+ motor_visual = urdfpy.Visual(geometry=motor_geometry, origin=motor_origin)
+ visuals.append(motor_visual)
+ # propeller
+ propeller_geometry = urdfpy.Geometry(
+ cylinder=urdfpy.Cylinder(
+ radius=options.propeller_diameter / 2,
+ length=options.propeller_height,
+ )
+ )
+ propeller_xyz = [
+ math.cos(rotor_angles[i - 1]) * arm_length,
+ math.sin(rotor_angles[i - 1]) * arm_length,
+ options.propeller_height / 2 + options.motor_height,
+ ]
+
+ propeller_origin = urdfpy.xyz_rpy_to_matrix(propeller_xyz + [0, 0, 0])
+ propeller_material = None
+ if i == 2 or i == 4:
+ propeller_material = urdfpy.Material("red", color=[1.0, 0.0, 0.0, 1.0])
+ propeller_visual = urdfpy.Visual(
+ geometry=propeller_geometry,
+ origin=propeller_origin,
+ material=propeller_material,
+ )
+ visuals.append(propeller_visual)
+
+ # ========== quad ==========
+
+ if options.disable_visuals:
+ visuals = []
+ link = urdfpy.Link(
+ name="base", inertial=inertial, visuals=visuals, collisions=collisions
+ )
+ links: List[urdfpy.Link] = [link]
+
+ quad = urdfpy.URDF(name=options.file_name, links=links)
+
+ # ========== create file ==========
+
+ file_dir, file_name_ext = export_urdf(quad)
+
+ # ========== load asset ==========
+
+ asset = gym.load_asset(sim, file_dir, file_name_ext, options.asset_options)
+ return asset
+
+
+def _get_collision_box(
+ options: DroneQuadcopterOptions,
+) -> Tuple[List[float], List[float]]:
+ positive_x_extend = max(
+ options.central_body_pos[0] + options.central_body_dim[0] / 2,
+ options.arm_length_front * math.cos(options.arm_front_angle / 2)
+ + options.propeller_diameter / 2,
+ )
+ negative_x_extend = -min(
+ options.central_body_pos[0] - options.central_body_dim[0] / 2,
+ options.arm_length_back * math.cos(options.arm_front_angle / 2 + math.pi)
+ - options.propeller_diameter / 2,
+ )
+ collision_bbox_length_x = positive_x_extend + negative_x_extend
+ collision_bbox_center_x = -negative_x_extend + collision_bbox_length_x / 2
+
+ positive_y_extend = max(
+ options.central_body_pos[1] + options.central_body_dim[1] / 2,
+ options.arm_length_front * math.sin(options.arm_front_angle / 2)
+ + options.propeller_diameter / 2,
+ options.arm_length_back * math.sin(math.pi - options.arm_front_angle / 2)
+ + options.propeller_diameter / 2,
+ )
+ collision_bbox_length_y = 2 * positive_y_extend
+ collision_bbox_center_y = 0.0
+
+ positive_z_extend = max(
+ options.central_body_pos[2] + options.central_body_dim[2] / 2,
+ options.motor_height + options.propeller_height,
+ )
+ negative_z_extend = -min(
+ options.central_body_pos[2] - options.central_body_dim[2] / 2,
+ -options.arm_thickness,
+ )
+ collision_bbox_length_z = positive_z_extend + negative_z_extend
+ collision_bbox_center_z = -negative_z_extend + collision_bbox_length_z / 2
+
+ position = [
+ collision_bbox_center_x,
+ collision_bbox_center_y,
+ collision_bbox_center_z,
+ ]
+ dimension = [
+ collision_bbox_length_x,
+ collision_bbox_length_y,
+ collision_bbox_length_z,
+ ]
+
+ return position, dimension
diff --git a/isaacgymenvs/tasks/drone_racing/assets/geometries/__init__.py b/isaacgymenvs/tasks/drone_racing/assets/geometries/__init__.py
new file mode 100644
index 000000000..6a0da7f78
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/geometries/__init__.py
@@ -0,0 +1,3 @@
+from .cuboid_wireframe import GeomCuboidWireframeOptions, create_geom_cuboid_wireframe
+from .cylinder import GeomCylinderOptions, create_geom_cylinder
+from .hollow_cuboid import GeomHollowCuboidOptions, create_geom_hollow_cuboid
diff --git a/isaacgymenvs/tasks/drone_racing/assets/geometries/cuboid_wireframe.py b/isaacgymenvs/tasks/drone_racing/assets/geometries/cuboid_wireframe.py
new file mode 100644
index 000000000..06f25be75
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/geometries/cuboid_wireframe.py
@@ -0,0 +1,26 @@
+from dataclasses import dataclass, field
+from typing import List
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils.urdf_utils import cuboid_wireframe_link, export_urdf
+
+
+@dataclass
+class GeomCuboidWireframeOptions:
+ file_name: str = "geom_cuboid_wireframe"
+ size: List[float] = field(default_factory=lambda: [1.0, 1.0, 1.0])
+ weight: float = 0.1
+ color: List[float] = field(default_factory=lambda: [1.0, 1.0, 1.0, 1.0])
+ asset_options: AssetOptions = AssetOptions()
+
+
+def create_geom_cuboid_wireframe(
+ gym: Gym, sim: Sim, options: GeomCuboidWireframeOptions
+) -> Asset:
+ link = cuboid_wireframe_link("base", options.size, options.weight, options.color)
+ urdf = urdfpy.URDF(options.file_name, [link])
+ file_dir, file_name_ext = export_urdf(urdf)
+ asset = gym.load_asset(sim, file_dir, file_name_ext, options.asset_options)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/geometries/cylinder.py b/isaacgymenvs/tasks/drone_racing/assets/geometries/cylinder.py
new file mode 100644
index 000000000..901aac0a3
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/geometries/cylinder.py
@@ -0,0 +1,22 @@
+from dataclasses import dataclass
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils.urdf_utils import cylinder_link, export_urdf
+
+
+@dataclass
+class GeomCylinderOptions:
+ file_name: str = "geom_cylinder"
+ radius: float = 0.5
+ length: float = 1.0
+ asset_options: AssetOptions = AssetOptions()
+
+
+def create_geom_cylinder(gym: Gym, sim: Sim, options: GeomCylinderOptions) -> Asset:
+ link = cylinder_link("base", options.radius, options.length)
+ urdf = urdfpy.URDF(options.file_name, [link])
+ file_dir, file_name_ext = export_urdf(urdf)
+ asset = gym.load_asset(sim, file_dir, file_name_ext, options.asset_options)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/geometries/hollow_cuboid.py b/isaacgymenvs/tasks/drone_racing/assets/geometries/hollow_cuboid.py
new file mode 100644
index 000000000..9909b0f9f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/geometries/hollow_cuboid.py
@@ -0,0 +1,37 @@
+from dataclasses import dataclass, field
+from typing import List
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils.urdf_utils import hollow_cuboid_link, export_urdf
+
+
+@dataclass
+class GeomHollowCuboidOptions:
+ file_name: str = "geom_hollow_cuboid"
+ length_x: float = 0.15
+ inner_length_y: float = 1.0
+ outer_length_y: float = 1.3
+ inner_length_z: float = 1.0
+ outer_length_z: float = 1.3
+ color: List[float] = field(default_factory=lambda: [1.0, 1.0, 1.0, 1.0])
+ asset_options: AssetOptions = AssetOptions()
+
+
+def create_geom_hollow_cuboid(
+ gym: Gym, sim: Sim, options: GeomHollowCuboidOptions
+) -> Asset:
+ link = hollow_cuboid_link(
+ "base",
+ options.length_x,
+ options.inner_length_y,
+ options.outer_length_y,
+ options.inner_length_z,
+ options.outer_length_z,
+ options.color,
+ )
+ urdf = urdfpy.URDF(options.file_name, [link])
+ file_dir, file_name_ext = export_urdf(urdf)
+ asset = gym.load_asset(sim, file_dir, file_name_ext, options.asset_options)
+ return asset
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/__init__.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/__init__.py
new file mode 100644
index 000000000..0e1a6b355
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/__init__.py
@@ -0,0 +1,12 @@
+from .geom_kebab import TrackGeomKebabOptions, create_track_geom_kebab
+from .multistory import TrackMultiStoryOptions, create_track_multistory
+from .planar_circle import TrackPlanarCircleOptions, create_track_planar_circle
+from .rmua import TrackRmuaOptions, create_track_rmua
+from .simple_stick import TrackSimpleStickOptions, create_track_simple_stick
+from .splits import TrackSplitsOptions, create_track_splits
+from .turns import TrackTurnsOptions, create_track_turns
+from .walls import TrackWallsOptions, create_track_walls
+from .wavy_eight import TrackWavyEightOptions, create_track_wavy_eight
+from .sjtu_3dc import TrackSjtu3dcOptions, create_track_sjtu_3dc
+from .sjtu_ell import TrackSjtuEllOptions, create_track_sjtu_ell
+from .sjtu_str import TrackSjtuStrOptions, create_track_sjtu_str
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/geom_kebab.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/geom_kebab.py
new file mode 100644
index 000000000..a685d4e30
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/geom_kebab.py
@@ -0,0 +1,153 @@
+from dataclasses import dataclass
+from math import radians
+from typing import List, Tuple
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import (
+ cylinder_link,
+ cuboid_wireframe_link,
+ sphere_link,
+ cuboid_link,
+)
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackGeomKebabOptions:
+ file_name: str = "track_geom_kebab"
+ track_options: TrackOptions = TrackOptions()
+ asset_options: AssetOptions = AssetOptions()
+ add_obstacles: bool = True
+
+
+def create_track_geom_kebab(
+ gym: Gym, sim: Sim, options: TrackGeomKebabOptions
+) -> Tuple[Asset, List[Waypoint]]:
+ """
+ Create a track that is almost straight with obstacles in between.
+
+ Args:
+ gym: returned by ``acquire_gym``.
+ sim: simulation handle.
+ options: options for the asset, and importing.
+
+ Returns:
+ - An asset object as the return of calling ``load_asset``.
+ - A list of ``Waypoint`` instances.
+ """
+
+ waypoints = _define_waypoints()
+
+ obstacle_links = []
+ obstacle_origins = []
+ if options.add_obstacles:
+ obstacle_links, obstacle_origins = _define_obstacles()
+
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ obstacle_links,
+ obstacle_origins,
+ [False] * len(obstacle_links),
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
+
+
+def _define_waypoints() -> List[Waypoint]:
+ return [
+ Waypoint(
+ index=0,
+ xyz=[-18.0, 0.0, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.8,
+ length_z=1.8,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[-10.0, 1.0, 1.6],
+ rpy=[45.0, 0.0, 10.0],
+ length_y=1.6,
+ length_z=1.6,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[-1.0, -1.0, 1.8],
+ rpy=[-0.0, -0.0, 0.0],
+ length_y=1.8,
+ length_z=1.8,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[9.0, 1.3, 1.5],
+ rpy=[-30.0, 10.0, 20.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[18.0, -1.0, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=2,
+ length_z=2,
+ gate=True,
+ ),
+ ]
+
+
+def _define_obstacles() -> Tuple[List[urdfpy.Link], List[List[float]]]:
+ obstacle_links = []
+ obstacle_origins = []
+
+ # cylinders
+ obstacle_links.append(cylinder_link("obstacle_0", 0.3, 2.0))
+ obstacle_origins.append([-14.0, -1.0, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_1", 0.3, 3.0))
+ obstacle_origins.append([-13.0, 0.0, 1.5, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_2", 0.3, 1.5))
+ obstacle_origins.append([-15.0, 0.5, 1.0, 0.0, 0.0, 0.0])
+
+ # cuboids
+ obstacle_links.append(cuboid_link("obstacle_3", [1.0, 1.0, 1.0]))
+ obstacle_origins.append([-6.0, 1.25, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_4", [0.3, 2, 3.0]))
+ obstacle_origins.append([-4.0, 1.5, 1.5, radians(45.0), 0.0, radians(15.0)])
+
+ obstacle_links.append(cuboid_link("obstacle_5", [0.3, 2, 2.0]))
+ obstacle_origins.append([-6.0, -1.5, 1.5, 0.0, 0.0, radians(-15.0)])
+
+ obstacle_links.append(cuboid_link("obstacle_6", [0.6, 1.2, 0.9]))
+ obstacle_origins.append([-5.0, -0.4, 2.5, 0.0, 20.0, radians(-15.0)])
+
+ # cuboid wireframes
+ obstacle_links.append(cuboid_wireframe_link("obstacle_7", [1.3, 1.3, 1.3], 0.5))
+ obstacle_origins.append([4.5, -1, -0.5, 0.0, 0.0, radians(-30.0)])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_8", [2.5, 2.5, 2.5], 0.33))
+ obstacle_origins.append([4, 1.0, 2.0, 45.0, 0.0, radians(45.0)])
+
+ # spheres
+ obstacle_links.append(sphere_link("obstacle_9", 1.0))
+ obstacle_origins.append([13.5, 0.0, 2, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(sphere_link("obstacle_10", 0.6))
+ obstacle_origins.append([13, 1.5, 1, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(sphere_link("obstacle_11", 0.8))
+ obstacle_origins.append([14, 2.75, 2, 0.0, 0.0, 0.0])
+
+ return obstacle_links, obstacle_origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/multistory.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/multistory.py
new file mode 100644
index 000000000..32d0cc350
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/multistory.py
@@ -0,0 +1,285 @@
+from dataclasses import dataclass
+from math import sin, cos, radians
+from typing import List, Tuple
+
+import numpy as np
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import cuboid_link, cylinder_link
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackMultiStoryOptions:
+ # file name
+ file_name: str = "track_multistory"
+
+ # common options for racing tracks
+ track_options: TrackOptions = TrackOptions()
+
+ # options for importing into Isaac Gym
+ asset_options: AssetOptions = AssetOptions()
+
+ # number of random cylinders
+ num_cylinders: int = 40
+
+ # radius of cylinders
+ radius_cylinders: float = 0.25
+
+ # no obstacle exists within waypoint clearance
+ waypoint_clearance: float = 2.0
+
+ # minimum distance between two cylinders
+ min_dist_cylinders: float = 2.0
+
+ # maximum attempts for sampling a new cylinder
+ max_num_attempts: int = 100
+
+
+def create_track_multistory(
+ gym: Gym, sim: Sim, options: TrackMultiStoryOptions
+) -> Tuple[Asset, List[Waypoint]]:
+ """
+ Create the Multi-story Arena track with random cylinder obstacles.
+
+ References
+ - https://github.com/uzh-rpg/sb_min_time_quadrotor_planning
+
+ Args:
+ gym: returned by ``acquire_gym``.
+ sim: simulation handle.
+ options: options for the asset, and importing.
+
+ Returns:
+ - An asset object as the return of calling ``load_asset``.
+ - A list of ``Waypoint`` instances.
+ """
+
+ waypoints, obstacle_links, obstacle_origins, obstacle_flags = _define_track(options)
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ obstacle_links,
+ obstacle_origins,
+ obstacle_flags,
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
+
+
+def _define_track(options: TrackMultiStoryOptions) -> Tuple[
+ List[Waypoint],
+ List[urdfpy.Link],
+ List[List[float]],
+ List[bool],
+]:
+ waypoints = _define_waypoints()
+ obstacle_links, obstacle_origins = _define_obstacles()
+ obstacle_flags = [False] * len(obstacle_links)
+ _add_random_obstacles(waypoints, obstacle_links, obstacle_origins, options)
+ obstacle_flags += [True] * (len(obstacle_links) - len(obstacle_flags))
+
+ return waypoints, obstacle_links, obstacle_origins, obstacle_flags
+
+
+def _define_waypoints() -> List[Waypoint]:
+ waypoints = [
+ Waypoint(
+ index=0,
+ xyz=[-7.0, 2.5, 1.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[7.17 * cos(radians(202)), 7.17 * sin(radians(202)), 1.2],
+ rpy=[0.0, 0.0, -69.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[0.07, -2.75, 2.8],
+ rpy=[0.0, -90.0, 90.0],
+ length_y=2.0,
+ length_z=1.68,
+ gate=False,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[1.4, -0.6, 4.1],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[-1.25, 2.95, 2.8],
+ rpy=[0.0, 90.0, 90.0],
+ length_y=2.0,
+ length_z=1.68,
+ gate=False,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[10.95 * cos(radians(127.7)), 10.95 * sin(radians(127.7)), 1.2],
+ rpy=[0.0, 0.0, 70.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=6,
+ xyz=[9.88 * cos(radians(68.5)), 9.88 * sin(radians(68.5)), 1.2],
+ rpy=[0.0, 0.0, -37.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=7,
+ xyz=[6.4, 1.55, 2.8],
+ rpy=[0.0, -90.0, -90.0],
+ length_y=2.0,
+ length_z=3.36,
+ gate=False,
+ ),
+ Waypoint(
+ index=8,
+ xyz=[6.0, 6.67 * sin(radians(-21)), 4.1],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=9,
+ xyz=[6.4, -4.7, 2.8],
+ rpy=[0.0, 90.0, 90.0],
+ length_y=2.0,
+ length_z=1.68,
+ gate=False,
+ ),
+ Waypoint(
+ index=10,
+ xyz=[6.67 * cos(radians(-21)), 6.67 * sin(radians(-21)), 1.2],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=11,
+ xyz=[4.28 * cos(radians(81)), 4.28 * sin(radians(81)), 1.2],
+ rpy=[0.0, 0.0, 162.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ ]
+
+ return waypoints
+
+
+def _define_obstacles() -> Tuple[List[urdfpy.Link], List[List[float]]]:
+ obstacle_links = []
+ obstacle_origins = []
+
+ obstacle_links.append(cuboid_link("obstacle_0", [4.2, 20.0, 0.15]))
+ obstacle_origins.append([3.25, 3.0, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_1", [2.0, 20.0, 0.15]))
+ obstacle_origins.append([8.5, 3.0, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_2", [2.2, 1.4, 0.15]))
+ obstacle_origins.append([6.4, -6.3, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_3", [2.2, 3.6, 0.15]))
+ obstacle_origins.append([6.4, -2.0, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_4", [2.2, 9.75, 0.15]))
+ obstacle_origins.append([6.4, 8.125, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_5", [2.2, 9.75, 0.15]))
+ obstacle_origins.append([6.4, 8.125, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_6", [8.1, 20.0, 0.15]))
+ obstacle_origins.append([-6.4, 3.0, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_7", [4.0, 9.15, 0.15]))
+ obstacle_origins.append([-0.8, 8.425, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_8", [4.0, 3.3, 0.15]))
+ obstacle_origins.append([-0.8, -5.35, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_9", [4.0, 3.9, 0.15]))
+ obstacle_origins.append([-0.8, 0.1, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_10", [2.0, 2.0, 0.15]))
+ obstacle_origins.append([0.8, 2.95, 2.8, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_11", [2.0, 2.0, 0.15]))
+ obstacle_origins.append([-2.0, -2.75, 2.8, 0.0, 0.0, 0.0])
+
+ return obstacle_links, obstacle_origins
+
+
+def _add_random_obstacles(
+ waypoints: List[Waypoint],
+ obstacle_links: List[urdfpy.Link],
+ obstacle_origins: List[List[float]],
+ options: TrackMultiStoryOptions,
+):
+ rng = np.random.default_rng()
+
+ random_obstacle_id = 0
+ random_obstacle_links = []
+ random_obstacle_origins = []
+ num_attempts = 0
+ while len(random_obstacle_links) < options.num_cylinders:
+ if num_attempts > options.max_num_attempts:
+ break
+ random_xy = rng.uniform(-1, 1, 2) * 9.5 + np.array([-1, 3])
+ random_xyz = np.array([random_xy[0], random_xy[1], 1.0])
+ # check distance to waypoint center
+ xyz_is_valid = True
+ for waypoint in waypoints:
+ distance = np.linalg.norm(np.array(waypoint.xyz) - random_xyz)
+ if distance < options.waypoint_clearance:
+ xyz_is_valid = False
+ break
+ # check distance to other cylinders
+ for random_obstacle_origin in random_obstacle_origins:
+ distance = np.linalg.norm(np.array(random_obstacle_origin[:3]) - random_xyz)
+ if distance < options.min_dist_cylinders:
+ xyz_is_valid = False
+ break
+ if not xyz_is_valid:
+ num_attempts += 1
+ continue
+ else:
+ random_obstacle_links.append(
+ cylinder_link(
+ "random_obstacle_" + str(random_obstacle_id),
+ options.radius_cylinders,
+ 2.0,
+ )
+ )
+ random_obstacle_origins.append(
+ [random_xy[0], random_xy[1], 1.0, 0.0, 0.0, 0.0]
+ )
+ random_obstacle_id += 1
+ num_attempts = 0
+
+ obstacle_links += random_obstacle_links
+ obstacle_origins += random_obstacle_origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/planar_circle.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/planar_circle.py
new file mode 100644
index 000000000..715503bbb
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/planar_circle.py
@@ -0,0 +1,154 @@
+from dataclasses import dataclass
+from math import sqrt, radians
+from typing import List, Tuple
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import cuboid_link
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackPlanarCircleOptions:
+ file_name: str = "track_planar_circle"
+ track_options: TrackOptions = TrackOptions()
+ asset_options: AssetOptions = AssetOptions()
+ add_obstacles: bool = False
+
+
+def create_track_planar_circle(
+ gym: Gym, sim: Sim, options: TrackPlanarCircleOptions
+) -> Tuple[Asset, List[Waypoint]]:
+ """
+ Create a track with obstacles shaped as a planar circle.
+
+ Args:
+ gym: returned by ``acquire_gym``.
+ sim: simulation handle.
+ options: options for the asset, and importing.
+
+ Returns:
+ - An asset object as the return of calling ``load_asset``.
+ - A list of ``Waypoint`` instances.
+ """
+ waypoints = _define_waypoints()
+
+ obstacle_links = []
+ obstacle_origins = []
+ if options.add_obstacles:
+ obstacle_links, obstacle_origins = _define_obstacles()
+
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ obstacle_links,
+ obstacle_origins,
+ [False] * len(obstacle_links),
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
+
+
+def _define_waypoints() -> List[Waypoint]:
+ r = 15
+ l = r / sqrt(2)
+ h = 1.5
+ g = 1.75
+
+ return [
+ Waypoint(
+ index=0,
+ xyz=[0.0, r, h],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=g,
+ length_z=g,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[l, l, h],
+ rpy=[0.0, 0.0, -45.0],
+ length_y=g,
+ length_z=g,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[r, 0, h],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[l, -l, h],
+ rpy=[0.0, 0.0, -135.0],
+ length_y=g,
+ length_z=g,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[0, -r, h],
+ rpy=[0.0, 0.0, -180.0],
+ length_y=g,
+ length_z=g,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[-l, -l, h],
+ rpy=[0.0, 0.0, -225.0],
+ length_y=g,
+ length_z=g,
+ gate=True,
+ ),
+ Waypoint(
+ index=6,
+ xyz=[-r, 0, h],
+ rpy=[0.0, 0.0, -270.0],
+ length_y=g,
+ length_z=g,
+ gate=True,
+ ),
+ Waypoint(
+ index=7,
+ xyz=[-l, l, h],
+ rpy=[0.0, 0.0, -315.0],
+ length_y=g,
+ length_z=g,
+ gate=True,
+ ),
+ Waypoint(
+ index=8,
+ xyz=[0, r, h],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=g,
+ length_z=g,
+ gate=True,
+ ),
+ ]
+
+
+def _define_obstacles() -> Tuple[List[urdfpy.Link], List[List[float]]]:
+ obstacle_links = []
+ obstacle_origins = []
+
+ # cuboids
+ obstacle_links.append(cuboid_link("obstacle_0", [0.5, 38.0, 1.5]))
+ obstacle_origins.append([0.0, 0.0, 1.5, radians(-2.5), 0.0, radians(-22.5)])
+
+ obstacle_links.append(cuboid_link("obstacle_1", [0.5, 38.0, 1.5]))
+ obstacle_origins.append([0.0, 0.0, 1.5, radians(+2.5), 0.0, radians(-67.5)])
+
+ obstacle_links.append(cuboid_link("obstacle_2", [0.5, 30.0, 5.0]))
+ obstacle_origins.append([0.0, 0.0, 1.5, 0.0, 0.0, radians(67.5)])
+
+ return obstacle_links, obstacle_origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/rmua.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/rmua.py
new file mode 100644
index 000000000..94a947d1e
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/rmua.py
@@ -0,0 +1,430 @@
+import math
+from dataclasses import dataclass
+from typing import List, Tuple
+
+import torch
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset, get_line_segment
+from ..utils.urdf_utils import (
+ cuboid_wireframe_link,
+ cuboid_link,
+ cylinder_link,
+ random_geometries_link,
+)
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackRmuaOptions:
+ # file name
+ file_name: str = "track_rmua"
+
+ # common options for racing tracks
+ track_options: TrackOptions = TrackOptions()
+
+ # options for importing into Isaac Gym
+ asset_options: AssetOptions = AssetOptions()
+
+ # flag to enable waypoint randomization
+ enable_waypoint_randomization: bool = False
+
+ # flag to enable additional random obstacles
+ enable_additional_obstacles: bool = False
+
+
+def create_track_rmua(
+ gym: Gym,
+ sim: Sim,
+ options: TrackRmuaOptions,
+) -> Tuple[Asset, List[Waypoint]]:
+ """
+ Create the RMUA 2023 racing track with gate pose randomization and additional obstacles.
+
+ References
+ - https://www.robomaster.com/zh-CN/resource/pages/announcement/1644
+
+ Args:
+ gym: returned by ``acquire_gym``.
+ sim: simulation handle.
+ options: options for the asset, and importing.
+
+ Returns:
+ - An asset object as the return of calling ``load_asset``.
+ - A list of ``Waypoint`` instances.
+ """
+
+ waypoints, obstacle_links, obstacle_origins, obstacle_flags = _define_track(options)
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ obstacle_links,
+ obstacle_origins,
+ obstacle_flags,
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
+
+
+def _define_track(
+ options: TrackRmuaOptions,
+) -> Tuple[List[Waypoint], List[urdfpy.Link], List[List[float]], List[bool]]:
+ waypoints = _define_waypoints()
+ obstacle_links, obstacle_origins = _define_obstacles()
+ obstacle_flags = [False] * len(obstacle_links)
+
+ if options.enable_waypoint_randomization:
+ _modify_waypoints(waypoints)
+
+ if options.enable_additional_obstacles:
+ _add_random_obstacles(waypoints, obstacle_links, obstacle_origins)
+ obstacle_flags += [True] * (len(obstacle_links) - len(obstacle_flags))
+
+ return waypoints, obstacle_links, obstacle_origins, obstacle_flags
+
+
+def _define_waypoints() -> List[Waypoint]:
+ waypoints = [
+ Waypoint(
+ index=0,
+ xyz=[0.0, 0.0, 1.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[-4.0, -0.5, 1.5],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[-10.0, -0.25, 1.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[-12.25, 5.25, 1.1],
+ rpy=[0.0, 0.0, 45.0],
+ length_y=1.5,
+ length_z=1.8,
+ gate=False,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[-7.5, 4.25, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[-3.5, 5.0, 0.9],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.6,
+ gate=False,
+ ),
+ Waypoint(
+ index=6,
+ xyz=[1.0, 4.25, 0.65],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=7,
+ xyz=[6.5, 5.6, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=8,
+ xyz=[6.5, 0.0, 6.5],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=9,
+ xyz=[6.5, 5.5, 8.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=10,
+ xyz=[8.0, 0.2, 1.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=11,
+ xyz=[2.0, 0.2, 0.75],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.2,
+ length_z=1.2,
+ gate=False,
+ ),
+ ]
+
+ return waypoints
+
+
+def _define_obstacles() -> Tuple[List[urdfpy.Link], List[List[float]]]:
+ obstacle_links = []
+ obstacle_origins = []
+
+ obstacle_links.append(cuboid_link("obstacle_0", [0.6, 1.8, 2.1]))
+ obstacle_origins.append([-11.35, 3.75, 1.05, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_1", [0.6, 1.2, 2.1]))
+ obstacle_origins.append([-13.2, 6.45, 1.05, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_2", [1.0, 1.5, 15.0]))
+ obstacle_origins.append([6.5, 4.0, 6.0, math.radians(45.0), 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_3", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.5, 4.0, 0.325, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_4", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.5, 6.0, 0.325, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_5", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.5, 6.25, 0.975, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_6", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.25, 4.0, 0.975, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_7", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.75, 6.0, 1.625, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_8", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.5, 4.0, 1.625, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_9", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.5, 4.5, 2.275, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_10", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.5, 5.15, 2.275, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_11", [0.6, 0.6, 0.6], 0.05))
+ obstacle_origins.append([-3.5, 5.8, 2.275, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_12", [0.6, 0.6, 2.0]))
+ obstacle_origins.append([4.0, 5.0, 1.0, 0.0, 0.0, math.radians(45)])
+
+ obstacle_links.append(cylinder_link("obstacle_13", 0.1, 2.0))
+ obstacle_origins.append([6.0, -0.7, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_14", 0.1, 2.0))
+ obstacle_origins.append([6.0, 1.1, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_15", 0.1, 2.0))
+ obstacle_origins.append([2.0, -0.7, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_16", 0.1, 2.0))
+ obstacle_origins.append([2.0, 1.1, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_17", 0.1, 2.0))
+ obstacle_origins.append([4.0, 0.0, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_18", 0.1, 1.0))
+ obstacle_origins.append([5.6, -0.8, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_19", 0.1, 1.0))
+ obstacle_origins.append([6.3, -1.05, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_20", 0.1, 1.0))
+ obstacle_origins.append([6.3, -0.28, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_21", 0.1, 1.0))
+ obstacle_origins.append([5.6, 0.8, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_22", 0.1, 1.0))
+ obstacle_origins.append([6.3, 0.67, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_23", 0.1, 1.0))
+ obstacle_origins.append([6.3, 1.4, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_24", 0.1, 1.0))
+ obstacle_origins.append([3.5, 0.0, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_25", 0.1, 1.0))
+ obstacle_origins.append([4.2, -0.3, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_26", 0.1, 1.0))
+ obstacle_origins.append([4.2, 0.3, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_27", 0.1, 1.0))
+ obstacle_origins.append([1.6, -0.8, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_28", 0.1, 1.0))
+ obstacle_origins.append([2.3, -1.05, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_29", 0.1, 1.0))
+ obstacle_origins.append([2.3, -0.28, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_30", 0.1, 1.0))
+ obstacle_origins.append([1.6, 0.8, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_31", 0.1, 1.0))
+ obstacle_origins.append([2.3, 0.67, 2.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_32", 0.1, 1.0))
+ obstacle_origins.append([2.3, 1.4, 2.0, 0.0, 0.0, 0.0])
+
+ return obstacle_links, obstacle_origins
+
+
+def _modify_waypoints(waypoints: List[Waypoint]):
+ num_waypoints = len(waypoints)
+ scale = torch.zeros(num_waypoints, 6)
+ offset = torch.zeros(num_waypoints, 6)
+ rand_gen = torch.rand(num_waypoints, 6)
+ rand = rand_gen * 2 - 1 # [-1, 1)
+
+ # waypoint 1
+ scale[1] = torch.tensor([1.0, 1.0, 0.5, 10.0, 10.0, 10.0])
+
+ # waypoint 2
+ scale[2] = torch.tensor([1.0, 1.0, 0.5, 20.0, 20.0, 20.0])
+ offset[2] = torch.tensor([0.0, 0.0, 0.5, 0.0, 0.0, 0.0])
+
+ # waypoint 4
+ scale[4] = torch.tensor([0.0, 1.0, 0.5, 20.0, 10.0, 20.0])
+ offset[4] = torch.tensor([0.0, 1.0, 0.0, 0.0, 0.0, 0.0])
+
+ # waypoint 6
+ scale[6] = torch.tensor([0.5, 0.5, 0.5, 20.0, 10.0, 20.0])
+ offset[6] = torch.tensor([-0.5, 0.5, 0.5, 0.0, 0.0, 0.0])
+
+ # waypoint 7
+ scale[7] = torch.tensor([0.5, 1.0, 0.0, 20.0, 20.0, 20.0])
+ offset[7] = torch.tensor([0.5, -0.5, 0.0, 0.0, 0.0, 0.0])
+
+ # waypoint 8
+ scale[8] = torch.tensor([1.0, 1.0, 1.0, 20.0, 20.0, 20.0])
+
+ # waypoint 9
+ scale[9] = torch.tensor([1.0, 1.0, 1.0, 20.0, 20.0, 20.0])
+
+ # waypoint 10
+ scale[10] = torch.tensor([1.0, 1.0, 0.5, 20.0, 20.0, 20.0])
+ offset[10] = torch.tensor([1.0, 0.0, 0.5, 0.0, 0.0, 0.0])
+
+ mod = rand * scale + offset
+ for i in range(num_waypoints):
+ waypoint = waypoints[i]
+ waypoint.xyz = (torch.tensor(waypoint.xyz) + mod[i, :3]).tolist()
+ waypoint.rpy = (torch.tensor(waypoint.rpy) + mod[i, 3:]).tolist()
+
+
+def _add_random_obstacles(
+ waypoints: List[Waypoint],
+ obstacle_links: List[urdfpy.Link],
+ obstacle_origins: List[List[float]],
+):
+ # between waypoint 1, 2
+ xyz_rpy, length = get_line_segment(waypoints[1].xyz, waypoints[2].xyz)
+ obstacle_links.append(
+ random_geometries_link(
+ "random_obstacle_0",
+ 6,
+ [max(2.0, length - 3), 3, 3],
+ [0.0, 0.0, 0.0],
+ 0.25,
+ 0.75,
+ )
+ )
+ obstacle_origins.append(xyz_rpy)
+
+ # between waypoint 2, 3
+ xyz_rpy, length = get_line_segment(waypoints[2].xyz, waypoints[3].xyz)
+ obstacle_links.append(
+ random_geometries_link(
+ "random_obstacle_1",
+ 10,
+ [max(2.0, length - 2), 4, 3],
+ [0.0, 2.0, 0.0],
+ 0.25,
+ 0.75,
+ )
+ )
+ obstacle_origins.append(xyz_rpy)
+
+ # between waypoint 3, 4
+ xyz_rpy, length = get_line_segment(waypoints[3].xyz, waypoints[4].xyz)
+ obstacle_links.append(
+ random_geometries_link(
+ "random_obstacle_2",
+ 5,
+ [max(2.0, length - 3), 2, 2],
+ [0.0, 1.0, 0.0],
+ 0.25,
+ 0.5,
+ )
+ )
+ obstacle_origins.append(xyz_rpy)
+
+ # between waypoint 6, 7
+ xyz_rpy, length = get_line_segment(waypoints[6].xyz, waypoints[7].xyz)
+ obstacle_links.append(
+ random_geometries_link(
+ "random_obstacle_3",
+ 5,
+ [max(1.0, length - 4), 2, 2],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 1.0,
+ )
+ )
+ obstacle_origins.append(xyz_rpy)
+
+ # between waypoint 7, 8
+ xyz_rpy, length = get_line_segment(waypoints[7].xyz, waypoints[8].xyz)
+ obstacle_links.append(
+ random_geometries_link(
+ "random_obstacle_4",
+ 20,
+ [max(2.0, length - 2), 5, 3],
+ [0.0, 3.0, 0.0],
+ 0.25,
+ 0.75,
+ )
+ )
+ obstacle_origins.append(xyz_rpy)
+
+ # between waypoint 8, 9
+ xyz_rpy, length = get_line_segment(waypoints[8].xyz, waypoints[9].xyz)
+ obstacle_links.append(
+ random_geometries_link(
+ "random_obstacle_5",
+ 20,
+ [max(2.0, length - 2), 6, 6],
+ [0.0, 3.0, 0.0],
+ 0.25,
+ 0.75,
+ )
+ )
+ obstacle_origins.append(xyz_rpy)
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/simple_stick.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/simple_stick.py
new file mode 100644
index 000000000..5eaaca99d
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/simple_stick.py
@@ -0,0 +1,97 @@
+from dataclasses import dataclass
+from math import radians
+from typing import List, Tuple
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import cuboid_wireframe_link, sphere_link, cuboid_link
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackSimpleStickOptions:
+ file_name: str = "track_simple_stick"
+ track_options: TrackOptions = TrackOptions()
+ asset_options: AssetOptions = AssetOptions()
+ add_obstacles: bool = True
+
+
+def create_track_simple_stick(
+ gym: Gym, sim: Sim, options: TrackSimpleStickOptions
+) -> Tuple[Asset, List[Waypoint]]:
+
+ waypoints = [
+ Waypoint(
+ index=0,
+ xyz=[-18.0, -18.0, 1.5],
+ rpy=[0.0, 0.0, 45.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[-10.0, -10.0, 1.4],
+ rpy=[0.0, 0.0, 45.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[-2.0, -2.0, 1.5],
+ rpy=[0.0, 0.0, 45.0],
+ length_y=1.6,
+ length_z=2.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[6, 6, 1.6],
+ rpy=[0.0, 0.0, 45.0],
+ length_y=1.8,
+ length_z=1.8,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[14, 14, 1.5],
+ rpy=[0.0, 0.0, 45.0],
+ length_y=2.0,
+ length_z=2.0,
+ gate=True,
+ ),
+ ]
+
+ obstacle_links = []
+ obstacle_origins = []
+ if options.add_obstacles:
+ obstacle_links.append(
+ cuboid_wireframe_link("obstacle_0", [2.3, 2.3, 2.3], 0.33)
+ )
+ obstacle_origins.append([-14, -14, 1.5, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(sphere_link("obstacle_1", 0.75))
+ obstacle_origins.append([-6, -6, 1.5, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_2", [0.2, 2.0, 2]))
+ obstacle_origins.append([2.0, 2, 1.5, 0.0, 0.0, radians(45)])
+
+ obstacle_links.append(
+ cuboid_wireframe_link("obstacle_3", [3.3, 3.3, 3.3], 0.33)
+ )
+ obstacle_origins.append([10.0, 10, 1.5, 0.0, 0.0, radians(45)])
+
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ obstacle_links,
+ obstacle_origins,
+ [False] * len(obstacle_links),
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_3dc.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_3dc.py
new file mode 100644
index 000000000..ac2a9cfb9
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_3dc.py
@@ -0,0 +1,212 @@
+from dataclasses import dataclass
+from typing import List, Tuple
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import random_cylinders_link
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackSjtu3dcOptions:
+ file_name: str = "track_sjtu_3dc"
+ track_options: TrackOptions = TrackOptions()
+ asset_options: AssetOptions = AssetOptions()
+ type_id: int = 0
+ num_obstacles: int = 16
+
+
+def create_track_sjtu_3dc(
+ gym: Gym,
+ sim: Sim,
+ options: TrackSjtu3dcOptions,
+) -> Tuple[Asset, List[Waypoint]]:
+ wp = _define_wp(options.type_id)
+ obs_links, obs_origins = _define_obs(options.num_obstacles)
+
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ wp,
+ obs_links,
+ obs_origins,
+ [False] * len(obs_links),
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, wp
+
+
+def _define_wp(type_id: int) -> List[Waypoint]:
+ wp = []
+ track_wps = [
+ Waypoint(
+ index=0,
+ xyz=[4.0, 4.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[8.0, 0.0, 2.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[5.0, -4.0, 1.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[1.0, -1.0, 1.0],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ ]
+ if type_id == 0:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[2.0, 2.0, 1.0],
+ rpy=[0.0, 0.0, 45.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[0], 1),
+ _mod_wp_id(track_wps[1], 2),
+ _mod_wp_id(track_wps[2], 3),
+ _mod_wp_id(track_wps[3], 4),
+ ]
+ elif type_id == 1:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[6.0, 2.0, 1.5],
+ rpy=[0.0, 0.0, -45.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[1], 1),
+ _mod_wp_id(track_wps[2], 2),
+ _mod_wp_id(track_wps[3], 3),
+ _mod_wp_id(track_wps[0], 4),
+ ]
+ elif type_id == 2:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[6.0, -2.0, 1.5],
+ rpy=[0.0, 0.0, -100.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[2], 1),
+ _mod_wp_id(track_wps[3], 2),
+ _mod_wp_id(track_wps[0], 3),
+ _mod_wp_id(track_wps[1], 4),
+ ]
+ elif type_id == 3:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[2.0, -2.0, 1.0],
+ rpy=[0.0, 0.0, 135.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[3], 1),
+ _mod_wp_id(track_wps[0], 2),
+ _mod_wp_id(track_wps[1], 3),
+ _mod_wp_id(track_wps[2], 4),
+ ]
+ return wp
+
+
+def _mod_wp_id(wp: Waypoint, id: int):
+ return Waypoint(
+ index=id,
+ xyz=wp.xyz,
+ rpy=wp.rpy,
+ length_y=wp.length_y,
+ length_z=wp.length_z,
+ gate=wp.gate,
+ )
+
+
+def _define_obs(num_obstacles: int):
+ links = []
+ origins = []
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_0",
+ num_obstacles // 4,
+ [4.0, 3.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([3.0, 2.5, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_1",
+ num_obstacles // 4,
+ [3.0, 4.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([6.5, 2.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_2",
+ num_obstacles // 4,
+ [4.0, 4.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([6.0, -2.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_3",
+ num_obstacles // 4,
+ [3.0, 5.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([2.5, -1.5, 1.0, 0.0, 0.0, 0.0])
+
+ return links, origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_ell.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_ell.py
new file mode 100644
index 000000000..15ee9d33f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_ell.py
@@ -0,0 +1,265 @@
+from dataclasses import dataclass
+from typing import List, Tuple
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import random_cylinders_link
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackSjtuEllOptions:
+ file_name: str = "track_sjtu_ell"
+ track_options: TrackOptions = TrackOptions()
+ asset_options: AssetOptions = AssetOptions()
+ type_id: int = 0
+ num_obstacles: int = 24
+
+
+def create_track_sjtu_ell(
+ gym: Gym,
+ sim: Sim,
+ options: TrackSjtuEllOptions,
+) -> Tuple[Asset, List[Waypoint]]:
+ wp = _define_wp(options.type_id)
+ obs_links, obs_origins = _define_obs(options.num_obstacles)
+
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ wp,
+ obs_links,
+ obs_origins,
+ [False] * len(obs_links),
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, wp
+
+
+def _define_wp(type_id: int) -> List[Waypoint]:
+ wp = []
+ track_wps = [
+ Waypoint(
+ index=0,
+ xyz=[4.0, 2.0, 1.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[2.0, 0.0, 1.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[4.0, -2.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[8.0, -2.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[10.0, 0.0, 1.0],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[8.0, 2.0, 1.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ ]
+
+ if type_id == 0:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[2.0, 2.0, 1.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[1], 1),
+ _mod_wp_id(track_wps[2], 2),
+ _mod_wp_id(track_wps[3], 3),
+ _mod_wp_id(track_wps[4], 4),
+ _mod_wp_id(track_wps[5], 5),
+ _mod_wp_id(track_wps[0], 6),
+ ]
+ elif type_id == 1:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[2.0, -2.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[2], 1),
+ _mod_wp_id(track_wps[3], 2),
+ _mod_wp_id(track_wps[4], 3),
+ _mod_wp_id(track_wps[5], 4),
+ _mod_wp_id(track_wps[0], 5),
+ _mod_wp_id(track_wps[1], 6),
+ ]
+ elif type_id == 2:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[10.0, -2.0, 1.0],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[4], 1),
+ _mod_wp_id(track_wps[5], 2),
+ _mod_wp_id(track_wps[0], 3),
+ _mod_wp_id(track_wps[1], 4),
+ _mod_wp_id(track_wps[2], 5),
+ _mod_wp_id(track_wps[3], 6),
+ ]
+ elif type_id == 3:
+ wp = [
+ Waypoint(
+ index=0,
+ xyz=[10.0, 2.0, 1.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ _mod_wp_id(track_wps[5], 1),
+ _mod_wp_id(track_wps[0], 2),
+ _mod_wp_id(track_wps[1], 3),
+ _mod_wp_id(track_wps[2], 4),
+ _mod_wp_id(track_wps[3], 5),
+ _mod_wp_id(track_wps[4], 6),
+ ]
+ return wp
+
+
+def _mod_wp_id(wp: Waypoint, id: int):
+ return Waypoint(
+ index=id,
+ xyz=wp.xyz,
+ rpy=wp.rpy,
+ length_y=wp.length_y,
+ length_z=wp.length_z,
+ gate=wp.gate,
+ )
+
+
+def _define_obs(num_obstacles: int):
+ links = []
+ origins = []
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_0",
+ num_obstacles // 6,
+ [2.0, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([3.0, 1.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_1",
+ num_obstacles // 6,
+ [2.0, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([3.0, -1.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_2",
+ num_obstacles // 6,
+ [4.0, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([6.0, -1.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_3",
+ num_obstacles // 6,
+ [2.0, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([9.0, -1.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_4",
+ num_obstacles // 6,
+ [2.0, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([9.0, 1.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_5",
+ num_obstacles // 6,
+ [4.0, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([6.0, 1.0, 1.0, 0.0, 0.0, 0.0])
+
+ return links, origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_str.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_str.py
new file mode 100644
index 000000000..9196a91a4
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/sjtu_str.py
@@ -0,0 +1,139 @@
+from dataclasses import dataclass
+from typing import List, Tuple
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import random_cylinders_link
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackSjtuStrOptions:
+ file_name: str = "track_sjtu_str"
+ track_options: TrackOptions = TrackOptions()
+ asset_options: AssetOptions = AssetOptions()
+ num_obstacles: int = 12
+
+
+def create_track_sjtu_str(
+ gym: Gym,
+ sim: Sim,
+ options: TrackSjtuStrOptions,
+) -> Tuple[Asset, List[Waypoint]]:
+ wp = _define_wp()
+ obs_links, obs_origins = _define_obs(options.num_obstacles)
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ wp,
+ obs_links,
+ obs_origins,
+ [False] * len(obs_links),
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, wp
+
+
+def _define_wp() -> List[Waypoint]:
+ return [
+ Waypoint(
+ index=0,
+ xyz=[1.0, 0.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[3.0, 0.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[6.0, -1.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[9.0, 1.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[12.0, 0.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[14.0, 0.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=True,
+ ),
+ ]
+
+
+def _define_obs(num_obstacles: int):
+ links = []
+ origins = []
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_0",
+ num_obstacles // 3,
+ [1.5, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([8.5 / 2, 0.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_1",
+ num_obstacles // 3,
+ [1.5, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([14.5 / 2, 0.0, 1.0, 0.0, 0.0, 0.0])
+
+ links.append(
+ random_cylinders_link(
+ "random_cylinders_2",
+ num_obstacles // 3,
+ [1.5, 2.0, 0.0],
+ [0.0, 0.0, 0.0],
+ 0.1,
+ 0.15,
+ 3.0,
+ 3.0,
+ )
+ )
+ origins.append([20.5 / 2, 0.0, 1.0, 0.0, 0.0, 0.0])
+
+ return links, origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/splits.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/splits.py
new file mode 100644
index 000000000..4418a3e7f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/splits.py
@@ -0,0 +1,150 @@
+from dataclasses import dataclass
+from typing import List, Tuple
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackSplitsOptions:
+ # file name
+ file_name: str = "track_splits"
+
+ # common options for racing tracks
+ track_options: TrackOptions = TrackOptions()
+
+ # options for importing into Isaac Gym
+ asset_options: AssetOptions = AssetOptions()
+
+
+def create_track_splits(
+ gym: Gym,
+ sim: Sim,
+ options: TrackSplitsOptions,
+) -> Tuple[Asset, List[Waypoint]]:
+ """
+ Create the Split-S track.
+
+ References
+ - https://arxiv.org/abs/2403.12203
+
+ Args:
+ gym: returned by ``acquire_gym``.
+ sim: simulation handle.
+ options: options for the asset, and importing.
+
+ Returns:
+ - An asset object as the return of calling ``load_asset``.
+ - A list of ``Waypoint`` instances.
+ """
+
+ waypoints, obstacle_links, obstacle_origins, obstacle_flags = _define_track()
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ obstacle_links,
+ obstacle_origins,
+ obstacle_flags,
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
+
+
+def _define_track() -> Tuple[
+ List[Waypoint],
+ List[urdfpy.Link],
+ List[List[float]],
+ List[bool],
+]:
+ waypoints = _define_waypoints()
+ obstacle_links = []
+ obstacle_origins = []
+ obstacle_flags = []
+
+ return waypoints, obstacle_links, obstacle_origins, obstacle_flags
+
+
+def _define_waypoints() -> List[Waypoint]:
+ waypoints = [
+ Waypoint(
+ index=0,
+ xyz=[-5.0, 4.75, 1.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[-0.5, -1.0, 3.25],
+ rpy=[0.0, 0.0, -18.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[9.6, 6.25, 1.1],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[9.5, -3.8, 1.1],
+ rpy=[0.0, 0.0, 226.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[-4.5, -5.1, 3.25],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[-4.5, -5.1, 1.2],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=6,
+ xyz=[4.9, -0.5, 1.1],
+ rpy=[0.0, 0.0, 79.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=7,
+ xyz=[-2.0, 6.6, 1.1],
+ rpy=[0.0, 0.0, 208.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=8,
+ xyz=[-0.5, -1.0, 3.25],
+ rpy=[0.0, 0.0, -18.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=False,
+ ),
+ ]
+
+ return waypoints
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/turns.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/turns.py
new file mode 100644
index 000000000..5ab2727f1
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/turns.py
@@ -0,0 +1,129 @@
+from dataclasses import dataclass
+from typing import List, Tuple
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackTurnsOptions:
+ # file name
+ file_name: str = "track_turns"
+
+ # common options for racing tracks
+ track_options: TrackOptions = TrackOptions()
+
+ # options for importing into Isaac Gym
+ asset_options: AssetOptions = AssetOptions()
+
+
+def create_track_turns(
+ gym: Gym,
+ sim: Sim,
+ options: TrackTurnsOptions,
+) -> Tuple[Asset, List[Waypoint]]:
+
+ waypoints: List[Waypoint] = [
+ Waypoint(
+ index=0,
+ xyz=[-10.0, -15.0, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[-0.0, -15.0, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[10, -15.0, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[15, -7.5, 1.5],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[10, 0.0, 1.5],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[0, 0.0, 1.5],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=6,
+ xyz=[-10, 0.0, 1.5],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=7,
+ xyz=[-15, 7.5, 1.5],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=8,
+ xyz=[-10, 15, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=9,
+ xyz=[-0, 15, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=10,
+ xyz=[10, 15, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ ]
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ [],
+ [],
+ [],
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/walls.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/walls.py
new file mode 100644
index 000000000..8e8b38102
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/walls.py
@@ -0,0 +1,167 @@
+from dataclasses import dataclass
+from typing import List, Tuple
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import (
+ cuboid_link,
+)
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackWallsOptions:
+ # file name
+ file_name: str = "track_walls"
+
+ # common options for racing tracks
+ track_options: TrackOptions = TrackOptions()
+
+ # options for importing into Isaac Gym
+ asset_options: AssetOptions = AssetOptions()
+
+
+def create_track_walls(
+ gym: Gym, sim: Sim, options: TrackWallsOptions
+) -> Tuple[Asset, List[Waypoint]]:
+ """
+ Create the racing track with wall shaped obstacles.
+
+ References
+ - https://arxiv.org/abs/2203.15052
+
+ Args:
+ gym: returned by ``acquire_gym``.
+ sim: simulation handle.
+ options: options for the asset, and importing.
+
+ Returns:
+ - An asset object as the return of calling ``load_asset``.
+ - A list of ``Waypoint`` instances.
+ """
+
+ waypoints, obstacle_links, obstacle_origins, obstacle_flags = _define_track()
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ waypoints,
+ obstacle_links,
+ obstacle_origins,
+ obstacle_flags,
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
+
+
+def _define_track() -> Tuple[
+ List[Waypoint],
+ List[urdfpy.Link],
+ List[List[float]],
+ List[bool],
+]:
+ waypoints = _define_waypoints()
+ obstacle_links, obstacle_origins = _define_obstacles()
+ obstacle_flags = [False] * len(obstacle_links)
+
+ return waypoints, obstacle_links, obstacle_origins, obstacle_flags
+
+
+def _define_waypoints() -> List[Waypoint]:
+ waypoints = [
+ Waypoint(
+ index=0,
+ xyz=[-8.0, 3.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.0,
+ length_z=1.0,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[-4.0, 3.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[0.0, 3.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[3.0, 3.0, 1.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[4.0, -1.0, 1.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[0.0, -3.0, 1.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=6,
+ xyz=[0.0, -3.0, 3.0],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ Waypoint(
+ index=7,
+ xyz=[-4.0, -1.0, 3.0],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=1.7,
+ length_z=1.7,
+ gate=True,
+ ),
+ ]
+
+ return waypoints
+
+
+def _define_obstacles() -> Tuple[List[urdfpy.Link], List[List[float]]]:
+ obstacle_links = []
+ obstacle_origins = []
+
+ obstacle_links.append(cuboid_link("obstacle_0", [4.0, 0.1, 2.0]))
+ obstacle_origins.append([-4.0, 2.0, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_1", [0.1, 2.0, 2.0]))
+ obstacle_origins.append([-2.0, 3.0, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_2", [0.1, 2.0, 2.0]))
+ obstacle_origins.append([2.0, 4.0, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_3", [2.0, 0.1, 2.0]))
+ obstacle_origins.append([3.0, 0.0, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_4", [2.0, 0.1, 2.0]))
+ obstacle_origins.append([5.0, -2.0, 1.0, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_link("obstacle_5", [0.1, 2.0, 2.0]))
+ obstacle_origins.append([1.0, -2.0, 1.0, 0.0, 0.0, 0.0])
+
+ return obstacle_links, obstacle_origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/tracks/wavy_eight.py b/isaacgymenvs/tasks/drone_racing/assets/tracks/wavy_eight.py
new file mode 100644
index 000000000..69b7ab586
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/tracks/wavy_eight.py
@@ -0,0 +1,167 @@
+from dataclasses import dataclass
+from math import radians
+from typing import List, Tuple
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from ..utils import TrackOptions
+from ..utils.track_utils import create_track_asset
+from ..utils.urdf_utils import (
+ cylinder_link,
+ cuboid_wireframe_link,
+ hollow_cuboid_link,
+)
+from ...waypoint import Waypoint
+
+
+@dataclass
+class TrackWavyEightOptions:
+ file_name: str = "track_wavy_eight"
+ track_options: TrackOptions = TrackOptions()
+ asset_options: AssetOptions = AssetOptions()
+ add_obstacles: bool = False
+
+
+def create_track_wavy_eight(
+ gym: Gym, sim: Sim, options: TrackWavyEightOptions
+) -> Tuple[Asset, List[Waypoint]]:
+ waypoints = _define_waypoints()
+
+ obstacle_links = []
+ obstacle_origins = []
+ if options.add_obstacles:
+ obstacle_links, obstacle_origins = _define_obstacles()
+
+ asset = create_track_asset(
+ options.file_name,
+ options.track_options,
+ _define_waypoints(),
+ obstacle_links,
+ obstacle_origins,
+ [False] * len(obstacle_links),
+ options.asset_options,
+ gym,
+ sim,
+ )
+ return asset, waypoints
+
+
+def _define_waypoints() -> List[Waypoint]:
+ r = 8
+ gate_size = 1.7
+ return [
+ Waypoint(
+ index=0,
+ xyz=[0.0, 0.0, 2.25],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=False,
+ ),
+ Waypoint(
+ index=1,
+ xyz=[r, 0.0, 3.0],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=2,
+ xyz=[2 * r, r, 4.5],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=3,
+ xyz=[r, 2 * r, 4.5],
+ rpy=[0.0, 0.0, 180.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=4,
+ xyz=[0, r, 6.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=5,
+ xyz=[0, -r, 6.0],
+ rpy=[0.0, 0.0, -90.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=6,
+ xyz=[-r, -2 * r, 4.5],
+ rpy=[0.0, 0.0, -180.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=7,
+ xyz=[-2 * r, -r, 3.0],
+ rpy=[0.0, 0.0, 90.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=8,
+ xyz=[-r, 0, 1.5],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=True,
+ ),
+ Waypoint(
+ index=9,
+ xyz=[0, 0, 2.25],
+ rpy=[0.0, 0.0, 0.0],
+ length_y=gate_size,
+ length_z=gate_size,
+ gate=False,
+ ),
+ ]
+
+
+def _define_obstacles() -> Tuple[List[urdfpy.Link], List[List[float]]]:
+ obstacle_links = []
+ obstacle_origins = []
+
+ r = 8
+
+ # cuboid wireframes
+ obstacle_links.append(cuboid_wireframe_link("obstacle_0", [5.5, 5.5, 5.5], 0.5))
+ obstacle_origins.append([0.0, 0.0, 2.75, 0.0, radians(45.0), 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_1", [6, 6, 4], 1.0))
+ obstacle_origins.append([2 * r, r, 4.5, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cuboid_wireframe_link("obstacle_2", [6, 6, 4], 1.0))
+ obstacle_origins.append([-2 * r, -r, 3.0, 0.0, 0.0, 0.0])
+
+ # cylinders
+ obstacle_links.append(cylinder_link("obstacle_3", 0.3, 3.0))
+ obstacle_origins.append([2 * r, r + 3, 4.5, 0.0, 0.0, 0.0])
+
+ obstacle_links.append(cylinder_link("obstacle_4", 0.3, 3.0))
+ obstacle_origins.append([-2 * r, -r - 3, 3.0, 0.0, 0.0, 0.0])
+
+ # hollow cuboids
+ obstacle_links.append(hollow_cuboid_link("obstacle_5", 1.0, 2.0, 4.0, 2.0, 4.0))
+ obstacle_origins.append([1, 15, 5.0, 0.0, 0.0, radians(45)])
+
+ obstacle_links.append(hollow_cuboid_link("obstacle_6", 1.0, 2.0, 4.0, 2.0, 4.0))
+ obstacle_origins.append([-1, -15, 5.0, 0.0, 0.0, radians(45)])
+
+ return obstacle_links, obstacle_origins
diff --git a/isaacgymenvs/tasks/drone_racing/assets/utils/__init__.py b/isaacgymenvs/tasks/drone_racing/assets/utils/__init__.py
new file mode 100644
index 000000000..354e3582c
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/utils/__init__.py
@@ -0,0 +1 @@
+from .track_options import TrackOptions
diff --git a/isaacgymenvs/tasks/drone_racing/assets/utils/track_options.py b/isaacgymenvs/tasks/drone_racing/assets/utils/track_options.py
new file mode 100644
index 000000000..2226a6b9a
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/utils/track_options.py
@@ -0,0 +1,33 @@
+from dataclasses import dataclass, field
+from typing import List
+
+
+@dataclass
+class TrackOptions:
+ # flag to enable debugging visualization
+ enable_debug_visualization: bool = False
+
+ # difference of gate outer and inner length
+ gate_size: float = 0.3
+
+ # x-axis length of the hollow cuboid representing the gates
+ gate_length_x: float = 0.15
+
+ # gate color
+ gate_color: List[float] = field(default_factory=lambda: [1.0, 0.5, 0.3, 1.0])
+
+ # additional obstacle color
+ additional_obstacle_color: List[float] = field(
+ default_factory=lambda: [0.0, 0.75, 1.0, 1.0]
+ )
+
+ # radius for the cylinder used to show line segments in debug
+ debug_cylinder_radius: float = 0.05
+
+ # waypoint x-axis length in debug
+ debug_waypoint_length_x: float = 0.025
+
+ # color of debug visualization
+ debug_visual_color: List[float] = field(
+ default_factory=lambda: [0.0, 1.0, 0.0, 1.0]
+ )
diff --git a/isaacgymenvs/tasks/drone_racing/assets/utils/track_utils.py b/isaacgymenvs/tasks/drone_racing/assets/utils/track_utils.py
new file mode 100644
index 000000000..e7173d98b
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/utils/track_utils.py
@@ -0,0 +1,168 @@
+import math
+from typing import List, Tuple
+
+import urdfpy
+
+from isaacgym.gymapi import Gym, Sim, AssetOptions, Asset
+from .track_options import TrackOptions
+from .urdf_utils import (
+ hollow_cuboid_link,
+ cylinder_link,
+ sphere_link,
+ fixed_joint,
+ cuboid_link,
+ set_link_color,
+ export_urdf,
+)
+from ...waypoint import Waypoint
+
+
+def create_track_asset(
+ name: str,
+ track_options: TrackOptions,
+ waypoints: List[Waypoint],
+ obstacle_links: List[urdfpy.Link],
+ obstacle_origins: List[List[float]],
+ obstacle_flags: List[bool],
+ asset_options: AssetOptions,
+ gym: Gym,
+ sim: Sim,
+) -> Asset:
+ # urdf
+ track_urdf = create_track_urdf(
+ name, track_options, waypoints, obstacle_links, obstacle_origins, obstacle_flags
+ )
+
+ # file
+ file_dir, file_name_ext = export_urdf(track_urdf)
+
+ # asset
+ asset_options.fix_base_link = True
+ asset_options.collapse_fixed_joints = True
+ asset = gym.load_asset(sim, file_dir, file_name_ext, asset_options)
+
+ return asset
+
+
+def create_track_urdf(
+ name: str,
+ options: TrackOptions,
+ waypoints: List[Waypoint],
+ obstacle_links: List[urdfpy.Link],
+ obstacle_origins: List[List[float]],
+ obstacle_flags: List[bool],
+) -> urdfpy.URDF:
+ links: List[urdfpy.Link] = []
+ joints: List[urdfpy.Joint] = []
+
+ # dummy base link
+ links.append(urdfpy.Link("base", None, None, None))
+
+ # obstacle links and joints
+ assert len(obstacle_links) == len(obstacle_origins) == len(obstacle_flags)
+ num_obstacles = len(obstacle_links)
+ for i in range(num_obstacles):
+ if obstacle_flags[i]:
+ set_link_color(obstacle_links[i], options.additional_obstacle_color)
+ links.append(obstacle_links[i])
+ joints.append(fixed_joint("base", obstacle_links[i].name, obstacle_origins[i]))
+
+ # gate links and joints
+ for waypoint in waypoints:
+ if waypoint.gate:
+ gate_link = hollow_cuboid_link(
+ name="gate_" + str(waypoint.index),
+ length_x=options.gate_length_x,
+ inner_length_y=waypoint.length_y,
+ outer_length_y=waypoint.length_y + options.gate_size,
+ inner_length_z=waypoint.length_z,
+ outer_length_z=waypoint.length_z + options.gate_size,
+ color=options.gate_color,
+ )
+ xyz_rpy = waypoint.xyz + waypoint.rpy_rad()
+ links.append(gate_link)
+ joints.append(fixed_joint("base", gate_link.name, xyz_rpy))
+
+ # debug links and joints
+ if options.enable_debug_visualization:
+ num_waypoints = len(waypoints)
+ for i in range(num_waypoints):
+ # line segments
+ if not i == num_waypoints - 1:
+ origin_xyz_rpy, length = get_line_segment(
+ waypoints[i].xyz, waypoints[i + 1].xyz
+ )
+ line_link = cylinder_link(
+ "line_" + str(i),
+ options.debug_cylinder_radius,
+ length,
+ True,
+ [0.0, 0.0, 0.0],
+ options.debug_visual_color,
+ )
+ links.append(line_link)
+ joints.append(fixed_joint("base", line_link.name, origin_xyz_rpy))
+
+ # waypoint centers
+ center_link = sphere_link(
+ "center_" + str(i),
+ options.debug_cylinder_radius,
+ options.debug_visual_color,
+ )
+ links.append(center_link)
+ joints.append(
+ fixed_joint("base", center_link.name, waypoints[i].xyz + [0, 0, 0])
+ )
+
+ # waypoint directions
+ direction_link = cylinder_link(
+ "direction_" + str(i),
+ options.debug_cylinder_radius,
+ 0.3,
+ True,
+ [0.15, 0.0, 0.0],
+ options.gate_color,
+ )
+ links.append(direction_link)
+ joints.append(
+ fixed_joint(
+ "base",
+ direction_link.name,
+ waypoints[i].xyz + waypoints[i].rpy_rad(),
+ )
+ )
+
+ # waypoint cuboids
+ region_link = cuboid_link(
+ "region_" + str(i),
+ [
+ options.debug_waypoint_length_x,
+ waypoints[i].length_y,
+ waypoints[i].length_z,
+ ],
+ options.debug_visual_color,
+ )
+ links.append(region_link)
+ joints.append(
+ fixed_joint(
+ "base", region_link.name, waypoints[i].xyz + waypoints[i].rpy_rad()
+ )
+ )
+
+ urdf = urdfpy.URDF(name=name, links=links, joints=joints)
+ return urdf
+
+
+def get_line_segment(
+ xyz_a: List[float], xyz_b: List[float]
+) -> Tuple[List[float], float]:
+ x_a, y_a, z_a = xyz_a
+ x_b, y_b, z_b = xyz_b
+ x_d = x_b - x_a
+ y_d = y_b - y_a
+ z_d = z_b - z_a
+ dist = (x_d**2 + y_d**2 + z_d**2) ** 0.5
+ yaw = math.atan2(y_d, x_d)
+ pitch = -math.atan2(z_d, (x_d**2 + y_d**2) ** 0.5)
+ xyz_rpy = [0.5 * (x_a + x_b), 0.5 * (y_a + y_b), 0.5 * (z_a + z_b), 0.0, pitch, yaw]
+ return xyz_rpy, dist
diff --git a/isaacgymenvs/tasks/drone_racing/assets/utils/urdf_utils.py b/isaacgymenvs/tasks/drone_racing/assets/utils/urdf_utils.py
new file mode 100644
index 000000000..5fdf86022
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/assets/utils/urdf_utils.py
@@ -0,0 +1,462 @@
+import math
+import os
+from typing import List, Tuple
+
+import torch
+import urdfpy
+
+
+def cuboid_link(name: str, size: List[float], color: List[float] = None) -> urdfpy.Link:
+ if color is None:
+ color = [1.0, 1.0, 1.0, 1.0]
+ geometry = urdfpy.Geometry(box=urdfpy.Box(size))
+ link = urdfpy.Link(
+ name=name,
+ inertial=None,
+ visuals=[urdfpy.Visual(geometry=geometry)],
+ collisions=[urdfpy.Collision(name=None, origin=None, geometry=geometry)],
+ )
+ set_link_color(link, color)
+
+ return link
+
+
+def cylinder_link(
+ name: str,
+ radius: float,
+ length: float,
+ align_x: bool = False,
+ offset: List[float] = None,
+ color: List[float] = None,
+) -> urdfpy.Link:
+ if offset is None:
+ offset = [0.0, 0.0, 0.0]
+ if color is None:
+ color = [1.0, 1.0, 1.0, 1.0]
+ geometry = urdfpy.Geometry(cylinder=urdfpy.Cylinder(radius=radius, length=length))
+ if align_x:
+ origin = urdfpy.xyz_rpy_to_matrix(offset + [0.0, math.radians(90), 0.0])
+ else:
+ origin = urdfpy.xyz_rpy_to_matrix(offset + [0.0, 0.0, 0.0])
+ link = urdfpy.Link(
+ name=name,
+ inertial=None,
+ visuals=[urdfpy.Visual(geometry=geometry, origin=origin)],
+ collisions=[urdfpy.Collision(name=None, origin=origin, geometry=geometry)],
+ )
+ set_link_color(link, color)
+
+ return link
+
+
+def sphere_link(name: str, radius: float, color: List[float] = None) -> urdfpy.Link:
+ if color is None:
+ color = [1.0, 1.0, 1.0, 1.0]
+ geometry = urdfpy.Geometry(sphere=urdfpy.Sphere(radius=radius))
+ link = urdfpy.Link(
+ name=name,
+ inertial=None,
+ visuals=[urdfpy.Visual(geometry=geometry)],
+ collisions=[urdfpy.Collision(name=None, origin=None, geometry=geometry)],
+ )
+ set_link_color(link, color)
+
+ return link
+
+
+def hollow_cuboid_link(
+ name: str,
+ length_x: float,
+ inner_length_y: float,
+ outer_length_y: float,
+ inner_length_z: float,
+ outer_length_z: float,
+ color: List[float] = None,
+) -> urdfpy.Link:
+ if color is None:
+ color = [1.0, 1.0, 1.0, 1.0]
+
+ # geometry
+ horizontal_bar_geometry = urdfpy.Geometry(
+ box=urdfpy.Box(
+ [length_x, outer_length_y, (outer_length_z - inner_length_z) / 2]
+ )
+ )
+ vertical_bar_geometry = urdfpy.Geometry(
+ box=urdfpy.Box(
+ [length_x, (outer_length_y - inner_length_y) / 2, outer_length_z]
+ )
+ )
+
+ # origin
+ top_bar_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, 0, (outer_length_z + inner_length_z) / 4, 0, 0, 0]
+ )
+ bottom_bar_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, 0, -(outer_length_z + inner_length_z) / 4, 0, 0, 0]
+ )
+ left_bar_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, (outer_length_y + inner_length_y) / 4, 0, 0, 0, 0]
+ )
+ right_bar_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, -(outer_length_y + inner_length_y) / 4, 0, 0, 0, 0]
+ )
+
+ # visual
+ top_bar_visual = urdfpy.Visual(
+ geometry=horizontal_bar_geometry, origin=top_bar_origin
+ )
+ bottom_bar_visual = urdfpy.Visual(
+ geometry=horizontal_bar_geometry, origin=bottom_bar_origin
+ )
+ left_bar_visual = urdfpy.Visual(
+ geometry=vertical_bar_geometry, origin=left_bar_origin
+ )
+ right_bar_visual = urdfpy.Visual(
+ geometry=vertical_bar_geometry, origin=right_bar_origin
+ )
+
+ # collision
+ top_bar_collision = urdfpy.Collision(
+ name=None, geometry=horizontal_bar_geometry, origin=top_bar_origin
+ )
+ bottom_bar_collision = urdfpy.Collision(
+ name=None, geometry=horizontal_bar_geometry, origin=bottom_bar_origin
+ )
+ left_bar_collision = urdfpy.Collision(
+ name=None, geometry=vertical_bar_geometry, origin=left_bar_origin
+ )
+ right_bar_collision = urdfpy.Collision(
+ name=None, geometry=vertical_bar_geometry, origin=right_bar_origin
+ )
+
+ # link
+ link = urdfpy.Link(
+ name=name,
+ inertial=None,
+ visuals=[top_bar_visual, bottom_bar_visual, left_bar_visual, right_bar_visual],
+ collisions=[
+ top_bar_collision,
+ bottom_bar_collision,
+ left_bar_collision,
+ right_bar_collision,
+ ],
+ )
+ set_link_color(link, color)
+
+ return link
+
+
+def cuboid_wireframe_link(
+ name: str,
+ size: List[float],
+ weight: float,
+ color: List[float] = None,
+) -> urdfpy.Link:
+ if color is None:
+ color = [1.0, 1.0, 1.0, 1.0]
+
+ # geometry
+ geometry_x = urdfpy.Geometry(box=urdfpy.Box([size[0] + weight, weight, weight]))
+ geometry_y = urdfpy.Geometry(box=urdfpy.Box([weight, size[1] + weight, weight]))
+ geometry_z = urdfpy.Geometry(box=urdfpy.Box([weight, weight, size[2] + weight]))
+
+ # origin
+ x_bar_upper_left_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, size[1] / 2, size[2] / 2, 0, 0, 0]
+ )
+ x_bar_lower_left_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, size[1] / 2, -size[2] / 2, 0, 0, 0]
+ )
+ x_bar_upper_right_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, -size[1] / 2, size[2] / 2, 0, 0, 0]
+ )
+ x_bar_lower_right_origin = urdfpy.xyz_rpy_to_matrix(
+ [0, -size[1] / 2, -size[2] / 2, 0, 0, 0]
+ )
+
+ y_bar_upper_front_origin = urdfpy.xyz_rpy_to_matrix(
+ [size[0] / 2, 0, size[2] / 2, 0, 0, 0]
+ )
+ y_bar_lower_front_origin = urdfpy.xyz_rpy_to_matrix(
+ [size[0] / 2, 0, -size[2] / 2, 0, 0, 0]
+ )
+ y_bar_upper_back_origin = urdfpy.xyz_rpy_to_matrix(
+ [-size[0] / 2, 0, size[2] / 2, 0, 0, 0]
+ )
+ y_bar_lower_back_origin = urdfpy.xyz_rpy_to_matrix(
+ [-size[0] / 2, 0, -size[2] / 2, 0, 0, 0]
+ )
+
+ z_bar_front_left_origin = urdfpy.xyz_rpy_to_matrix(
+ [size[0] / 2, size[1] / 2, 0, 0, 0, 0]
+ )
+ z_bar_front_right_origin = urdfpy.xyz_rpy_to_matrix(
+ [size[0] / 2, -size[1] / 2, 0, 0, 0, 0]
+ )
+ z_bar_back_left_origin = urdfpy.xyz_rpy_to_matrix(
+ [-size[0] / 2, size[1] / 2, 0, 0, 0, 0]
+ )
+ z_bar_back_right_origin = urdfpy.xyz_rpy_to_matrix(
+ [-size[0] / 2, -size[1] / 2, 0, 0, 0, 0]
+ )
+
+ # visual
+ x_bar_upper_left_visual = urdfpy.Visual(
+ geometry=geometry_x, origin=x_bar_upper_left_origin
+ )
+ x_bar_lower_left_visual = urdfpy.Visual(
+ geometry=geometry_x, origin=x_bar_lower_left_origin
+ )
+ x_bar_upper_right_visual = urdfpy.Visual(
+ geometry=geometry_x, origin=x_bar_upper_right_origin
+ )
+ x_bar_lower_right_visual = urdfpy.Visual(
+ geometry=geometry_x, origin=x_bar_lower_right_origin
+ )
+
+ y_bar_upper_front_visual = urdfpy.Visual(
+ geometry=geometry_y, origin=y_bar_upper_front_origin
+ )
+ y_bar_lower_front_visual = urdfpy.Visual(
+ geometry=geometry_y, origin=y_bar_lower_front_origin
+ )
+ y_bar_upper_back_visual = urdfpy.Visual(
+ geometry=geometry_y, origin=y_bar_upper_back_origin
+ )
+ y_bar_lower_back_visual = urdfpy.Visual(
+ geometry=geometry_y, origin=y_bar_lower_back_origin
+ )
+
+ z_bar_front_left_visual = urdfpy.Visual(
+ geometry=geometry_z, origin=z_bar_front_left_origin
+ )
+ z_bar_front_right_visual = urdfpy.Visual(
+ geometry=geometry_z, origin=z_bar_front_right_origin
+ )
+ z_bar_back_left_visual = urdfpy.Visual(
+ geometry=geometry_z, origin=z_bar_back_left_origin
+ )
+ z_bar_back_right_visual = urdfpy.Visual(
+ geometry=geometry_z, origin=z_bar_back_right_origin
+ )
+
+ # collision
+ x_bar_upper_left_collision = urdfpy.Collision(
+ name=None, geometry=geometry_x, origin=x_bar_upper_left_origin
+ )
+ x_bar_lower_left_collision = urdfpy.Collision(
+ name=None, geometry=geometry_x, origin=x_bar_lower_left_origin
+ )
+ x_bar_upper_right_collision = urdfpy.Collision(
+ name=None, geometry=geometry_x, origin=x_bar_upper_right_origin
+ )
+ x_bar_lower_right_collision = urdfpy.Collision(
+ name=None, geometry=geometry_x, origin=x_bar_lower_right_origin
+ )
+
+ y_bar_upper_front_collision = urdfpy.Collision(
+ name=None, geometry=geometry_y, origin=y_bar_upper_front_origin
+ )
+ y_bar_lower_front_collision = urdfpy.Collision(
+ name=None, geometry=geometry_y, origin=y_bar_lower_front_origin
+ )
+ y_bar_upper_back_collision = urdfpy.Collision(
+ name=None, geometry=geometry_y, origin=y_bar_upper_back_origin
+ )
+ y_bar_lower_back_collision = urdfpy.Collision(
+ name=None, geometry=geometry_y, origin=y_bar_lower_back_origin
+ )
+
+ z_bar_front_left_collision = urdfpy.Collision(
+ name=None, geometry=geometry_z, origin=z_bar_front_left_origin
+ )
+ z_bar_front_right_collision = urdfpy.Collision(
+ name=None, geometry=geometry_z, origin=z_bar_front_right_origin
+ )
+ z_bar_back_left_collision = urdfpy.Collision(
+ name=None, geometry=geometry_z, origin=z_bar_back_left_origin
+ )
+ z_bar_back_right_collision = urdfpy.Collision(
+ name=None, geometry=geometry_z, origin=z_bar_back_right_origin
+ )
+
+ # link
+ link = urdfpy.Link(
+ name=name,
+ inertial=None,
+ visuals=[
+ x_bar_upper_left_visual,
+ x_bar_lower_left_visual,
+ x_bar_upper_right_visual,
+ x_bar_lower_right_visual,
+ y_bar_upper_front_visual,
+ y_bar_lower_front_visual,
+ y_bar_upper_back_visual,
+ y_bar_lower_back_visual,
+ z_bar_front_left_visual,
+ z_bar_front_right_visual,
+ z_bar_back_left_visual,
+ z_bar_back_right_visual,
+ ],
+ collisions=[
+ x_bar_upper_left_collision,
+ x_bar_lower_left_collision,
+ x_bar_upper_right_collision,
+ x_bar_lower_right_collision,
+ y_bar_upper_front_collision,
+ y_bar_lower_front_collision,
+ y_bar_upper_back_collision,
+ y_bar_lower_back_collision,
+ z_bar_front_left_collision,
+ z_bar_front_right_collision,
+ z_bar_back_left_collision,
+ z_bar_back_right_collision,
+ ],
+ )
+ set_link_color(link, color)
+
+ return link
+
+
+def random_geometries_link(
+ name: str,
+ num_geometries: int,
+ space_dim: List[float],
+ space_offset: List[float],
+ min_geometry_size: float,
+ max_geometry_size: float,
+ color: List[float] = None,
+) -> urdfpy.Link:
+ if color is None:
+ color = [1.0, 1.0, 1.0, 1.0]
+
+ # generate a random tensor
+ # geometry type (1) + xyz_rpy (6) + size (3)
+ # for box the size represent edge lengths
+ # for cylinder the size represent diameter and length, 1 value unused
+ # for sphere only the first value represent diameter
+ random_tensor = torch.rand(num_geometries, 1 + 6 + 3)
+ random_tensor[:, 0] //= 1 / 3
+ random_tensor[:, 1] = (
+ random_tensor[:, 1] * space_dim[0] - space_dim[0] / 2 + space_offset[0]
+ )
+ random_tensor[:, 2] = (
+ random_tensor[:, 2] * space_dim[1] - space_dim[1] / 2 + space_offset[1]
+ )
+ random_tensor[:, 3] = (
+ random_tensor[:, 3] * space_dim[2] - space_dim[2] / 2 + space_offset[2]
+ )
+ random_tensor[:, 4:7] *= torch.pi * 2
+ range_geometry_size = max_geometry_size - min_geometry_size
+ random_tensor[:, 7:] = (
+ random_tensor[:, 7:] * range_geometry_size + min_geometry_size
+ )
+
+ visuals: List[urdfpy.Visual] = []
+ collisions: List[urdfpy.Collision] = []
+ for i in range(num_geometries):
+ if int(random_tensor[i, 0]) == 0:
+ # box
+ geometry = urdfpy.Geometry(box=urdfpy.Box(random_tensor[i, 7:].tolist()))
+ elif int(random_tensor[i, 0]) == 1:
+ # cylinder
+ r = float(random_tensor[i, 7]) / 2
+ length = float(random_tensor[i, 8])
+ geometry = urdfpy.Geometry(
+ cylinder=urdfpy.Cylinder(radius=r, length=length)
+ )
+ else:
+ # sphere
+ r = float(random_tensor[i, 7]) / 2
+ geometry = urdfpy.Geometry(sphere=urdfpy.Sphere(r))
+ origin = urdfpy.xyz_rpy_to_matrix(random_tensor[i, 1:7].tolist())
+ visual = urdfpy.Visual(geometry=geometry, origin=origin)
+ collision = urdfpy.Collision(name=None, geometry=geometry, origin=origin)
+ visuals.append(visual)
+ collisions.append(collision)
+
+ link = urdfpy.Link(name=name, inertial=None, visuals=visuals, collisions=collisions)
+ set_link_color(link, color)
+
+ return link
+
+
+def random_cylinders_link(
+ name: str,
+ num_cylinders: int,
+ space_dim: List[float],
+ space_offset: List[float],
+ radius_min: float,
+ radius_max: float,
+ length_min: float,
+ length_max: float,
+ color: List[float] = None,
+) -> urdfpy.Link:
+ if color is None:
+ color = [1.0, 1.0, 1.0, 1.0]
+
+ random_tensor = torch.rand(num_cylinders, 3 + 2)
+ random_tensor[:, 0] = (
+ random_tensor[:, 0] * space_dim[0] - space_dim[0] / 2 + space_offset[0]
+ )
+ random_tensor[:, 1] = (
+ random_tensor[:, 1] * space_dim[1] - space_dim[1] / 2 + space_offset[1]
+ )
+ random_tensor[:, 2] = (
+ random_tensor[:, 2] * space_dim[2] - space_dim[2] / 2 + space_offset[2]
+ )
+
+ radius_range = radius_max - radius_min
+ random_tensor[:, 3] = random_tensor[:, 3] * radius_range + radius_min
+ length_range = length_max - length_min
+ random_tensor[:, 4] = random_tensor[:, 4] * length_range + length_min
+
+ visuals: List[urdfpy.Visual] = []
+ collisions: List[urdfpy.Collision] = []
+ for i in range(num_cylinders):
+ r = float(random_tensor[i, 3])
+ l = float(random_tensor[i, 4])
+ geom = urdfpy.Geometry(cylinder=urdfpy.Cylinder(radius=r, length=l))
+ origin = urdfpy.xyz_rpy_to_matrix(
+ random_tensor[i, 0:3].tolist() + [0.0, 0.0, 0.0]
+ )
+ visual = urdfpy.Visual(geometry=geom, origin=origin)
+ collision = urdfpy.Collision(name=None, geometry=geom, origin=origin)
+ visuals.append(visual)
+ collisions.append(collision)
+
+ link = urdfpy.Link(name=name, inertial=None, visuals=visuals, collisions=collisions)
+ set_link_color(link, color)
+
+ return link
+
+
+def fixed_joint(
+ parent_name: str, child_name: str, xyz_rpy: List[float]
+) -> urdfpy.Joint:
+ joint = urdfpy.Joint(
+ name=parent_name + "_" + child_name,
+ parent=parent_name,
+ child=child_name,
+ joint_type="fixed",
+ origin=urdfpy.xyz_rpy_to_matrix(xyz_rpy),
+ )
+ return joint
+
+
+def set_link_color(link: urdfpy.Link, color: List[float]):
+ visuals: List[urdfpy.Visual] = link.visuals
+ for visual in visuals:
+ visual.material = urdfpy.Material("color" + str(color), color=color)
+
+
+def export_urdf(urdf: urdfpy.URDF) -> Tuple[str, str]:
+ file_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "export")
+ if not os.path.exists(file_dir):
+ os.mkdir(file_dir)
+ file_name_with_ext = urdf.name + ".urdf"
+ file = os.path.join(file_dir, file_name_with_ext)
+ urdf.save(file)
+
+ return file_dir, file_name_with_ext
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/rand_dr.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/rand_dr.pth
new file mode 100644
index 000000000..c63c9c6e9
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/rand_dr.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/rand_no_obst.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/rand_no_obst.pth
new file mode 100644
index 000000000..53a8d09dd
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/rand_no_obst.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/config.yaml b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/config.yaml
new file mode 100644
index 000000000..6e8198270
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/config.yaml
@@ -0,0 +1,525 @@
+task:
+ name: DRRandom
+ physics_engine: ${..physics_engine}
+ sim:
+ dt: 0.004
+ substeps: 1
+ up_axis: z
+ gravity:
+ - 0.0
+ - 0.0
+ - -9.81
+ use_gpu_pipeline: ${eq:${...pipeline},"gpu"}
+ num_client_threads: 0
+ physx:
+ always_use_articulations: false
+ bounce_threshold_velocity: 0.2
+ contact_collection: 1
+ contact_offset: 0.02
+ default_buffer_size_multiplier: 2.0
+ friction_correlation_distance: 0.025
+ friction_offset_threshold: 0.04
+ max_depenetration_velocity: 1.0
+ max_gpu_contact_pairs: 1048576
+ num_position_iterations: 4
+ num_subscenes: ${....num_subscenes}
+ num_threads: ${....num_threads}
+ num_velocity_iterations: 1
+ rest_offset: 0.001
+ solver_type: ${....solver_type}
+ use_gpu: ${contains:"cuda",${....sim_device}}
+ env:
+ numEnvs: ${resolve_default:256,${...num_envs}}
+ numActions: 4
+ numAgents: 1
+ numObservations: 120
+ controlFrequencyInv: 10
+ obsImgMode: dce
+ maxEpisodeLength: 150
+ enableDebugVis: false
+ enableVirtualWalls: true
+ enableCameraSensors: true
+ cameraEnableTensors: true
+ cameraWidth: 480
+ cameraHeight: 270
+ cameraHfov: 90
+ cameraBodyPos:
+ - 0.08
+ - 0.0
+ - 0.015
+ cameraAngleDeg: 30
+ cameraDepthMax: 20
+ logging:
+ enable: false
+ experimentName: ${...name}
+ logMainCam: false
+ logExtraCams: false
+ maxNumEpisodes: 10
+ numStepsPerSave: 50
+ extraCameraWidth: 256
+ extraCameraHeight: 256
+ extraCameraHfov: 90
+ viewer:
+ camPos:
+ - -20
+ - -20
+ - 30
+ camTarget:
+ - 20
+ - 20
+ - 10
+ initRandOpt:
+ randDroneOptions:
+ next_wp_id_max: 1
+ dist_along_line_min: 0.0
+ dist_along_line_max: 0.25
+ drone_rotation_x_max: 1
+ dist_to_line_max: 2.0
+ lin_vel_x_max: 1
+ lin_vel_y_max: 1
+ lin_vel_z_max: 1
+ ang_vel_x_max: 1
+ ang_vel_y_max: 1
+ ang_vel_z_max: 1
+ aileron_max: 0.2
+ elevator_max: 0.2
+ rudder_max: 0.2
+ throttle_min: -1
+ throttle_max: -0.5
+ randCameraOptions:
+ d_x_max: 0.01
+ d_y_max: 0
+ d_z_max: 0.01
+ d_angle_max: 5
+ randWaypointOptions:
+ wp_size_min: 1.4
+ wp_size_max: 2.0
+ init_roll_max: 0.2
+ init_pitch_max: 0.2
+ init_yaw_max: 3.14
+ psi_max: 0.3
+ theta_max: 0.3
+ alpha_max: 3.14
+ gamma_max: 0.2
+ r_min: 6
+ r_max: 18
+ force_gate_flag: -1
+ same_track: 0
+ randObstacleOptions:
+ extra_clearance: 1.4
+ orbit_density: 0
+ tree_density: 1
+ wall_density: 1
+ wall_dist_scale: 0.67
+ std_dev_scale: 1
+ gnd_distance_min: 2
+ gnd_distance_max: 5
+ mdp:
+ observation:
+ dim_action: ${...env.numActions}
+ pos_max: 40.0
+ vel_max: 20.0
+ ang_vel_max: 12
+ dist_to_corner_max: 20.0
+ reward:
+ k_progress: 1.0
+ k_perception: 0.02
+ k_cam_dev: -10.0
+ k_cmd_ang_vel: -0.0004
+ k_cmd_diff: -0.0002
+ k_collision: -10.0
+ k_guidance: 1.0
+ k_rejection: 2.0
+ k_waypoint: 5.0
+ k_timeout: -10.0
+ guidance_x_thresh: 3.0
+ guidance_tol: 0.2
+ enable_normalization: false
+ extra_reward:
+ k_vel_lateral: -0.001
+ k_vel_backward: -0.005
+ droneSim:
+ num_rotors: 4
+ rotors_x:
+ - -0.078665
+ - 0.078665
+ - -0.078665
+ - 0.078665
+ rotors_y:
+ - 0.097143
+ - 0.097143
+ - -0.097143
+ - -0.097143
+ rotors_dir:
+ - 1
+ - -1
+ - -1
+ - 1
+ drone_asset_options:
+ arm_length_front: 0.125
+ arm_length_back: 0.125
+ arm_thickness: 0.01
+ arm_front_angle: 1.780236
+ motor_diameter: 0.023
+ motor_height: 0.006
+ central_body_pos:
+ - 0.0
+ - 0.0
+ - 0.015
+ central_body_dim:
+ - 0.15
+ - 0.05
+ - 0.05
+ propeller_diameter: 0.12954
+ propeller_height: 0.01
+ mass: 0.76
+ center_of_mass:
+ - 0.0
+ - 0.0
+ - 0.0
+ diagonal_inertia:
+ - 0.0025
+ - 0.0021
+ - 0.0043
+ principle_axes_q:
+ - 1.0
+ - 0.0
+ - 0.0
+ - 0.0
+ disable_visuals: false
+ simpleBetaflight:
+ dt: ${...sim.dt}
+ center_sensitivity:
+ - 100.0
+ - 100.0
+ - 100.0
+ max_rate:
+ - 670.0
+ - 670.0
+ - 670.0
+ rate_expo:
+ - 0.0
+ - 0.0
+ - 0.0
+ kp:
+ - 70.0
+ - 70.0
+ - 125.0
+ ki:
+ - 0.5
+ - 0.5
+ - 25.0
+ kd:
+ - 1.0
+ - 1.0
+ - 0.0
+ kff:
+ - 0.0
+ - 0.0
+ - 0.0
+ iterm_lim:
+ - 5.0
+ - 5.0
+ - 5.0
+ pid_sum_lim:
+ - 1000.0
+ - 1000.0
+ - 1000.0
+ dterm_lpf_cutoff: 1000
+ rotors_x: ${..rotors_x}
+ rotors_y: ${..rotors_y}
+ rotors_dir: ${..rotors_dir}
+ pid_sum_mixer_scale: 1000.0
+ output_idle: 0.05
+ throttle_boost_gain: 0.0
+ throttle_boost_freq: 125.0
+ thrust_linearization_gain: 0.4
+ rotorPolyLag:
+ dt: ${...sim.dt}
+ num_rotors: ${..num_rotors}
+ rotors_dir: ${..rotors_dir}
+ spinup_time_constant: 0.033
+ slowdown_time_constant: 0.033
+ k_rpm_quadratic: -13421.95
+ k_rpm_linear: 37877.42
+ rotor_diagonal_inertia:
+ - 0.0
+ - 0.0
+ - 9.3575e-06
+ rotor_principle_axes_q:
+ - 1.0
+ - 0.0
+ - 0.0
+ - 0.0
+ propellerPoly:
+ num_props: ${..num_rotors}
+ k_force_quadratic: 2.1549e-08
+ k_force_linear: -4.5101e-05
+ k_torque_quadratic: 4.74078e-10
+ k_torque_linear: -9.92222e-07
+ bodyDragPoly:
+ air_density: 1.204
+ a_trans:
+ - 0.015
+ - 0.015
+ - 0.03
+ k_trans_quadratic:
+ - 1.04
+ - 1.04
+ - 1.04
+ k_trans_linear:
+ - 0.0
+ - 0.0
+ - 0.0
+ a_rot:
+ - 0.01
+ - 0.01
+ - 0.01
+ k_rot_quadratic:
+ - 0.0
+ - 0.0
+ - 0.0
+ k_rot_linear:
+ - 0.0
+ - 0.0
+ - 0.0
+ wrenchSum:
+ num_positions: ${..num_rotors}
+ position_x: ${..rotors_x}
+ position_y: ${..rotors_y}
+ position_z:
+ - 0.0
+ - 0.0
+ - 0.0
+ - 0.0
+ envCreator:
+ env_size: 40.0
+ backstage_z_offset: 20.0
+ ground_color:
+ - 0.25
+ - 0.25
+ - 0.25
+ ground_len_z: 0.3
+ gate_bar_len_x:
+ - 0.15
+ gate_bar_len_y:
+ - 2.0
+ gate_bar_len_z:
+ - 0.225
+ gate_color:
+ - 1.0
+ - 0.5
+ - 0.3
+ disable_tqdm: false
+ drone_asset_options: ${..droneSim.drone_asset_options}
+ num_box_actors: 0
+ num_box_assets: 0
+ box_params_min:
+ - 0.3
+ - 0.3
+ - 0.3
+ box_params_max:
+ - 2.0
+ - 2.0
+ - 2.0
+ box_color:
+ - 0.12156862745098039
+ - 0.4666666666666667
+ - 0.7058823529411765
+ num_capsule_actors: 0
+ num_capsule_assets: 0
+ capsule_params_min:
+ - 0.3
+ - 0.3
+ capsule_params_max:
+ - 1.0
+ - 1.0
+ capsule_color:
+ - 0.7294117647058823
+ - 0.21176470588235294
+ - 0.3411764705882353
+ num_cuboid_wireframe_actors: 0
+ num_cuboid_wireframe_assets: 0
+ cuboid_wireframe_params_min:
+ - 0.3
+ - 0.3
+ - 0.3
+ - 0.2
+ cuboid_wireframe_params_max:
+ - 2.0
+ - 2.0
+ - 2.0
+ - 0.4
+ cuboid_wireframe_color:
+ - 0.5803921568627451
+ - 0.403921568627451
+ - 0.7411764705882353
+ num_cylinder_actors: 0
+ num_cylinder_assets: 0
+ cylinder_params_min:
+ - 0.1
+ - 0.2
+ cylinder_params_max:
+ - 1.0
+ - 2.0
+ cylinder_color:
+ - 0.5490196078431373
+ - 0.33725490196078434
+ - 0.29411764705882354
+ num_hollow_cuboid_actors: 0
+ num_hollow_cuboid_assets: 0
+ hollow_cuboid_params_min:
+ - 0.1
+ - 0.5
+ - 0.5
+ - 0.2
+ - 0.2
+ hollow_cuboid_params_max:
+ - 0.25
+ - 1.4
+ - 1.4
+ - 0.6
+ - 0.6
+ hollow_cuboid_color:
+ - 0.8901960784313725
+ - 0.4666666666666667
+ - 0.7607843137254902
+ num_sphere_actors: 0
+ num_sphere_assets: 0
+ sphere_params_min:
+ - 0.3
+ sphere_params_max:
+ - 1.0
+ sphere_color:
+ - 0.7372549019607844
+ - 0.7411764705882353
+ - 0.13333333333333333
+ num_tree_actors: 4
+ num_tree_assets: 4
+ tree_color:
+ - 0.4196078431372549
+ - 0.5411764705882353
+ - 0.47843137254901963
+ num_wall_actors: 12
+ num_wall_assets: 12
+ wall_params_min:
+ - 0.2
+ - 1.5
+ - 1.5
+ wall_params_max:
+ - 0.2
+ - 2.5
+ - 2.5
+ wall_color:
+ - 0.09019607843137255
+ - 0.7450980392156863
+ - 0.8117647058823529
+ disableObstacleManager: false
+ waypointGenerator:
+ num_waypoints: 4
+ num_gate_x_lens: 1
+ num_gate_weights: 1
+ gate_weight_max: 0.225
+ fixed_waypoint_id: 1
+ fixed_waypoint_position:
+ - 0.0
+ - 0.0
+ - 20.0
+train:
+ params:
+ seed: ${...seed}
+ algo:
+ name: dr_continuous
+ model:
+ name: continuous_a2c_logstd
+ network:
+ name: actor_critic
+ separate: false
+ space:
+ continuous:
+ mu_activation: None
+ sigma_activation: None
+ mu_init:
+ name: default
+ sigma_init:
+ name: const_initializer
+ val: 0
+ fixed_sigma: true
+ mlp:
+ units:
+ - 256
+ - 128
+ - 128
+ - 64
+ activation: elu
+ d2rl: false
+ initializer:
+ name: default
+ regularizer:
+ name: None
+ load_checkpoint: ${if:${...checkpoint},True,False}
+ load_path: ${...checkpoint}
+ config:
+ name: ${resolve_default:DRRandom,${....experiment}}
+ full_experiment_name: ${.name}
+ env_name: rlgpu
+ multi_gpu: ${....multi_gpu}
+ ppo: true
+ mixed_precision: false
+ normalize_input: false
+ normalize_value: true
+ num_actors: ${....task.env.numEnvs}
+ reward_shaper:
+ scale_value: 0.1
+ normalize_advantage: true
+ gamma: 0.99
+ tau: 0.95
+ learning_rate: 0.001
+ lr_schedule: adaptive
+ kl_threshold: 0.016
+ score_to_win: 20000
+ max_epochs: ${resolve_default:500,${....max_iterations}}
+ save_best_after: 50
+ save_frequency: 50
+ grad_norm: 1.0
+ entropy_coef: 0.0
+ truncate_grads: true
+ e_clip: 0.2
+ horizon_length: 1024
+ minibatch_size: 32768
+ mini_epochs: 8
+ critic_coef: 2
+ clip_value: true
+ bounds_loss_coef: 0.0001
+pbt:
+ enabled: false
+task_name: ${task.name}
+experiment: ''
+num_envs: 512
+seed: 42
+torch_deterministic: false
+max_iterations: 1000
+physics_engine: physx
+pipeline: gpu
+sim_device: cuda:0
+rl_device: cuda:0
+graphics_device_id: 0
+num_threads: 4
+solver_type: 1
+num_subscenes: 4
+test: false
+checkpoint: ''
+sigma: ''
+multi_gpu: false
+wandb_activate: true
+wandb_group: ''
+wandb_name: ${train.params.config.name}
+wandb_entity: ''
+wandb_project: isaacgymenvs
+wandb_tags: []
+wandb_logcode_dir: ''
+capture_video: false
+capture_video_freq: 1464
+capture_video_len: 100
+force_render: true
+headless: false
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_1000_rew_28.540253.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_1000_rew_28.540253.pth
new file mode 100644
index 000000000..d118fa98d
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_1000_rew_28.540253.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_1000_rew__28.54_.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_1000_rew__28.54_.pth
new file mode 100644
index 000000000..19bcb2115
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_1000_rew__28.54_.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_100_rew_11.455327.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_100_rew_11.455327.pth
new file mode 100644
index 000000000..546c8cdcb
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_100_rew_11.455327.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_150_rew_14.506991.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_150_rew_14.506991.pth
new file mode 100644
index 000000000..d00e0846d
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_150_rew_14.506991.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_200_rew_17.46312.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_200_rew_17.46312.pth
new file mode 100644
index 000000000..0773913e4
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_200_rew_17.46312.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_250_rew_19.978048.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_250_rew_19.978048.pth
new file mode 100644
index 000000000..04a2fc865
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_250_rew_19.978048.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_300_rew_21.590405.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_300_rew_21.590405.pth
new file mode 100644
index 000000000..ccc3e054a
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_300_rew_21.590405.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_350_rew_21.668037.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_350_rew_21.668037.pth
new file mode 100644
index 000000000..98a9d8724
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_350_rew_21.668037.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_400_rew_24.526379.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_400_rew_24.526379.pth
new file mode 100644
index 000000000..e0252e620
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_400_rew_24.526379.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_450_rew_23.421623.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_450_rew_23.421623.pth
new file mode 100644
index 000000000..6d81e5717
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_450_rew_23.421623.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_500_rew_24.687069.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_500_rew_24.687069.pth
new file mode 100644
index 000000000..833361eca
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_500_rew_24.687069.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_50_rew_2.74659.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_50_rew_2.74659.pth
new file mode 100644
index 000000000..a261c8aa2
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_50_rew_2.74659.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_550_rew_23.820522.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_550_rew_23.820522.pth
new file mode 100644
index 000000000..3afc591c2
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_550_rew_23.820522.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_600_rew_24.42814.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_600_rew_24.42814.pth
new file mode 100644
index 000000000..d44cf43ce
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_600_rew_24.42814.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_650_rew_25.773247.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_650_rew_25.773247.pth
new file mode 100644
index 000000000..7200400fb
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_650_rew_25.773247.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_700_rew_27.169775.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_700_rew_27.169775.pth
new file mode 100644
index 000000000..e50f0f157
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_700_rew_27.169775.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_750_rew_27.271652.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_750_rew_27.271652.pth
new file mode 100644
index 000000000..6d77092c1
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_750_rew_27.271652.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_800_rew_26.590324.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_800_rew_26.590324.pth
new file mode 100644
index 000000000..db0d7de51
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_800_rew_26.590324.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_850_rew_28.143215.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_850_rew_28.143215.pth
new file mode 100644
index 000000000..05c572755
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_850_rew_28.143215.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_900_rew_29.137526.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_900_rew_29.137526.pth
new file mode 100644
index 000000000..28b289953
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_900_rew_29.137526.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_950_rew_27.809605.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_950_rew_27.809605.pth
new file mode 100644
index 000000000..102eba465
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/run_rand_dr/last_DRRandom_ep_950_rew_27.809605.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/splits_ang_vel_plot.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/splits_ang_vel_plot.pth
new file mode 100644
index 000000000..8418a1081
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/splits_ang_vel_plot.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/checkpoints/splits_direct_training.pth b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/splits_direct_training.pth
new file mode 100644
index 000000000..6b3d435a0
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/checkpoints/splits_direct_training.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/dce.py b/isaacgymenvs/tasks/drone_racing/demos/dce.py
new file mode 100644
index 000000000..2f761b01c
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/dce.py
@@ -0,0 +1,19 @@
+import isaacgym # noqa
+from isaacgymenvs.tasks.drone_racing.encoders.dce import (
+ VAEImageEncoder,
+ VAEImageEncoderConfig,
+)
+
+torch = None
+import torch # noqa
+
+
+enc = VAEImageEncoder(VAEImageEncoderConfig())
+inp = torch.rand(2, 270, 480, device="cuda")
+out = enc.encode(inp)
+recon = enc.decode(out)
+
+print(enc.vae_model)
+print(out.shape)
+print(recon.shape)
+print(enc.vae_model.inference_mode, enc.config.return_sampled_latent)
diff --git a/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_rand_default.png b/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_rand_default.png
new file mode 100644
index 000000000..86833369a
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_rand_default.png differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_rand_no_obst.png b/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_rand_no_obst.png
new file mode 100644
index 000000000..299db205c
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_rand_no_obst.png differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_splits.png b/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_splits.png
new file mode 100644
index 000000000..35823566e
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/imgs/perf_test_splits.png differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_splits_direct.png b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_splits_direct.png
new file mode 100644
index 000000000..358e0239a
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_splits_direct.png differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_splits_rand.png b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_splits_rand.png
new file mode 100644
index 000000000..836cfa6e5
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_splits_rand.png differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_turns_direct.png b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_turns_direct.png
new file mode 100644
index 000000000..d9b2fe747
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_turns_direct.png differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_turns_rand.png b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_turns_rand.png
new file mode 100644
index 000000000..c04598bd6
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/demos/imgs/traj_turns_rand.png differ
diff --git a/isaacgymenvs/tasks/drone_racing/demos/mdp.py b/isaacgymenvs/tasks/drone_racing/demos/mdp.py
new file mode 100644
index 000000000..f030fc5c9
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/mdp.py
@@ -0,0 +1,511 @@
+import inspect
+from dataclasses import dataclass
+from typing import List, Tuple
+
+import cv2
+import numpy as np
+
+from isaacgym import gymapi, gymtorch
+from isaacgymenvs.tasks.drone_racing.assets import (
+ create_drone_quadcopter,
+ DroneQuadcopterOptions,
+)
+from isaacgymenvs.tasks.drone_racing.mdp import (
+ RewardParams,
+ Reward,
+ ObservationParams,
+ Observation,
+)
+from isaacgymenvs.tasks.drone_racing.waypoint import (
+ WaypointGeneratorParams,
+ RandWaypointOptions,
+ WaypointGenerator,
+ WaypointTrackerParams,
+ WaypointTracker,
+)
+from isaacgymenvs.utils.torch_jit_utils import (
+ quaternion_to_matrix,
+ quat_from_euler_xyz,
+ quat_mul,
+)
+
+print("Importing torch...")
+import torch # noqa
+
+
+@dataclass
+class MdpParams:
+ env_size: int = 40
+ num_envs: int = 4
+ init_move_inc: float = 0.5
+ init_rot_inc: float = torch.pi / 8
+ add_ground: bool = True
+ print_obs: bool = True
+
+ quad_init_pose: gymapi.Transform = gymapi.Transform()
+ quad_init_pose.p = gymapi.Vec3(0.0, 0.0, 1.0)
+
+ quad_asset_opts: DroneQuadcopterOptions = DroneQuadcopterOptions()
+ quad_asset_opts.asset_options.fix_base_link = True
+
+ camera_props: gymapi.CameraProperties = gymapi.CameraProperties()
+ camera_props.enable_tensors = True
+ camera_props.width = 640
+ camera_props.height = 480
+ camera_props.horizontal_fov = 90
+
+ cam_tf: gymapi.Transform = gymapi.Transform()
+ cam_tf.p = gymapi.Vec3(0.08, 0.0, 0.02)
+ cam_tf.r = gymapi.Quat.from_axis_angle(gymapi.Vec3(0, 1, 0), np.radians(-15.0))
+
+ wp_gen_params: WaypointGeneratorParams = WaypointGeneratorParams()
+ wp_gen_params.num_envs = num_envs
+ wp_gen_params.fixed_waypoint_id = 0
+ wp_gen_params.fixed_waypoint_position = [0.0, 0.0, 1.0]
+
+ wp_tracker_params: WaypointTrackerParams = WaypointTrackerParams()
+ wp_tracker_params.num_envs = num_envs
+
+ reward_params: RewardParams = RewardParams()
+ reward_params.num_envs = num_envs
+
+ rand_wp_opts: RandWaypointOptions = RandWaypointOptions()
+ rand_wp_opts.init_yaw_max = 0.0
+ rand_wp_opts.init_roll_max = 0.0
+ rand_wp_opts.init_pitch_max = 0.0
+ rand_wp_opts.theta_max = torch.pi / 12
+ rand_wp_opts.psi_max = torch.pi / 2
+ rand_wp_opts.alpha_max = 0
+ rand_wp_opts.gamma_max = torch.pi / 6
+ rand_wp_opts.r_min = 2
+ rand_wp_opts.r_max = 10
+ rand_wp_opts.wp_size_min = 1
+ rand_wp_opts.wp_size_max = 3
+
+ observation_params: ObservationParams = ObservationParams()
+ observation_params.num_envs = num_envs
+
+
+class Mdp:
+
+ def __init__(self, params: MdpParams):
+ torch.set_printoptions(linewidth=130, sci_mode=False, precision=2)
+
+ self.params = params
+ self.selected_env_id = 0
+ self.move_inc = params.init_move_inc
+ self.rot_inc = params.init_rot_inc
+ self.quad_init_pose_p = torch.tensor(
+ [
+ params.quad_init_pose.p.x,
+ params.quad_init_pose.p.y,
+ params.quad_init_pose.p.z,
+ ],
+ device="cuda",
+ )
+ self.quad_init_pose_q = torch.tensor(
+ [
+ params.quad_init_pose.r.x,
+ params.quad_init_pose.r.y,
+ params.quad_init_pose.r.z,
+ params.quad_init_pose.r.w,
+ ],
+ device="cuda",
+ )
+
+ self.gym, self.sim = self._create_sim_gym()
+ self.viewer = self._create_viewer()
+
+ self.envs, self.cam_tensors, self.depth_tensors = self._init_envs()
+ self.gym.prepare_sim(self.sim)
+ self.actor_root_state = gymtorch.wrap_tensor(
+ self.gym.acquire_actor_root_state_tensor(self.sim)
+ )
+
+ self.wp_gen = WaypointGenerator(self.params.wp_gen_params)
+ self.wp_tracker = WaypointTracker(self.params.wp_tracker_params)
+ self.mdp_reward = Reward(self.params.reward_params)
+ self.mdp_observation = Observation(self.params.observation_params)
+
+ self.collision = torch.zeros(
+ self.params.num_envs, dtype=torch.bool, device="cuda"
+ )
+ self.timeout = torch.zeros(
+ self.params.num_envs, dtype=torch.bool, device="cuda"
+ )
+
+ def run(self):
+ mdp_initialized = False
+ init_next_wp_id = torch.ones(
+ self.params.num_envs, dtype=torch.int, device="cuda"
+ )
+ while not self.gym.query_viewer_has_closed(self.viewer):
+
+ self.gym.simulate(self.sim)
+ self.gym.fetch_results(self.sim, True)
+ self.gym.refresh_actor_root_state_tensor(self.sim)
+
+ self.gym.step_graphics(self.sim)
+ self.gym.render_all_camera_sensors(self.sim)
+ self.gym.start_access_image_tensors(self.sim)
+ img = self.cam_tensors[self.selected_env_id].cpu().numpy()
+ self.gym.end_access_image_tensors(self.sim)
+ self.gym.draw_viewer(self.viewer, self.sim, True)
+
+ move, reset, reset_all = self._check_key_update_actor_state()
+
+ if reset_all:
+ wp_data = self.wp_gen.compute(self.params.rand_wp_opts)
+
+ self.gym.clear_lines(self.viewer)
+ wp_data.visualize(self.gym, self.envs, self.viewer, 1.0)
+
+ self.wp_tracker.set_waypoint_data(wp_data)
+ self.wp_tracker.set_init_drone_state_next_wp(
+ self.actor_root_state, init_next_wp_id
+ )
+
+ self.mdp_reward.set_waypoint_and_cam(
+ wp_data, [self.params.cam_tf] * self.params.num_envs
+ )
+ self.mdp_reward.set_init_drone_state_action(
+ self.actor_root_state,
+ torch.zeros(self.params.num_envs, 4, device="cuda"),
+ )
+
+ self.mdp_observation.set_waypoint_and_cam(
+ wp_data, [self.params.cam_tf] * self.params.num_envs
+ )
+ self.mdp_observation.set_init_drone_state_action(
+ self.actor_root_state,
+ torch.zeros(self.params.num_envs, 4, device="cuda"),
+ )
+
+ mdp_initialized = True
+
+ if reset and mdp_initialized:
+ self.wp_tracker.set_init_drone_state_next_wp(
+ self.actor_root_state,
+ init_next_wp_id,
+ torch.tensor([self.selected_env_id], device="cuda"),
+ )
+ self.mdp_reward.set_init_drone_state_action(
+ self.actor_root_state,
+ torch.zeros(self.params.num_envs, 4, device="cuda"),
+ torch.tensor([self.selected_env_id], device="cuda"),
+ )
+ self.mdp_observation.set_init_drone_state_action(
+ self.actor_root_state,
+ torch.zeros(self.params.num_envs, 4, device="cuda"),
+ torch.tensor([self.selected_env_id], device="cuda"),
+ )
+
+ if move:
+ # if reset_all or reset is True, move is True
+ # if reset_all and reset are all False, move can still happen
+ self.gym.set_actor_root_state_tensor(
+ self.sim, gymtorch.unwrap_tensor(self.actor_root_state)
+ )
+ if (not reset_all) and (not reset) and mdp_initialized:
+ wp_passing, next_wp_id = self.wp_tracker.compute(
+ self.actor_root_state
+ )
+ r = self.mdp_reward.compute(
+ self.actor_root_state,
+ torch.zeros(self.params.num_envs, 4, device="cuda"),
+ self.collision,
+ self.timeout,
+ wp_passing,
+ next_wp_id,
+ )
+ o_state, o_cam, o_wp, o_act = self.mdp_observation.compute(
+ drone_state=self.actor_root_state,
+ next_wp_id=next_wp_id,
+ action=torch.zeros(self.params.num_envs, 4, device="cuda"),
+ )
+
+ print("------------")
+ print("- next wp id:")
+ print(next_wp_id)
+ print("- reward:")
+ print(r)
+ print("- progress:")
+ print(self.mdp_reward.reward_progress)
+ print("- perception:")
+ print(self.mdp_reward.reward_perception)
+ print("- guidance:")
+ print(self.mdp_reward.reward_guidance)
+ print("- waypoint:")
+ print(self.mdp_reward.reward_waypoint)
+ if self.params.print_obs:
+ print("- obs_state:")
+ print(o_state)
+ print("- obs_wp:")
+ print(o_wp)
+
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
+ cv2.putText(img, str(self.selected_env_id), (8, 32), 0, 1, (0, 255, 0), 2)
+ cx = int(self.params.camera_props.width / 2)
+ cy = int(self.params.camera_props.height / 2)
+ cv2.circle(img, (cx, cy), 4, (0, 255, 0), -1)
+ cv2.imshow("fpv", img)
+ cv2.waitKey(1)
+
+ self.gym.sync_frame_time(self.sim)
+
+ def _create_sim_gym(self) -> Tuple[gymapi.Gym, gymapi.Sim]:
+ sim_params = gymapi.SimParams()
+ sim_params.use_gpu_pipeline = True
+ sim_params.physx.use_gpu = True
+ sim_params.up_axis = gymapi.UP_AXIS_Z
+ sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
+ gym = gymapi.acquire_gym()
+ sim = gym.create_sim(0, 0, gymapi.SIM_PHYSX, sim_params)
+ if self.params.add_ground:
+ plane_params = gymapi.PlaneParams()
+ plane_params.normal = gymapi.Vec3(0, 0, 1)
+ gym.add_ground(sim, plane_params)
+ return gym, sim
+
+ def _create_viewer(self) -> gymapi.Viewer:
+ line_number = inspect.currentframe().f_back.f_lineno
+ print("Control keys: read `_create_viewer` at code line", line_number)
+ viewer = self.gym.create_viewer(self.sim, gymapi.CameraProperties())
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_0, "env_0")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_1, "env_1")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_2, "env_2")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_3, "env_3")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_4, "env_4")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_5, "env_5")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_6, "env_6")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_7, "env_7")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_8, "env_8")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_9, "env_9")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_UP, "move_front")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_DOWN, "move_back")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_LEFT, "move_left")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_RIGHT, "move_right")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_S, "move_down")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_W, "move_up")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_Q, "roll_left")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_E, "roll_right")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_A, "yaw_left")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_D, "yaw_right")
+ self.gym.subscribe_viewer_keyboard_event(
+ viewer, gymapi.KEY_LEFT_SHIFT, "pitch_down"
+ )
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_SPACE, "pitch_up")
+ self.gym.subscribe_viewer_keyboard_event(
+ viewer, gymapi.KEY_MINUS, "move_inc_down"
+ )
+ self.gym.subscribe_viewer_keyboard_event(
+ viewer, gymapi.KEY_EQUAL, "move_inc_up"
+ )
+ self.gym.subscribe_viewer_keyboard_event(
+ viewer, gymapi.KEY_COMMA, "rot_inc_down"
+ )
+ self.gym.subscribe_viewer_keyboard_event(
+ viewer, gymapi.KEY_PERIOD, "rot_inc_up"
+ )
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_R, "reset")
+ self.gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_ENTER, "reset_all")
+
+ return viewer
+
+ def _init_envs(
+ self,
+ ) -> Tuple[List[gymapi.Env], List[torch.Tensor], List[torch.Tensor]]:
+ # asset
+ quad_asset = create_drone_quadcopter(
+ self.gym, self.sim, self.params.quad_asset_opts
+ )
+
+ # envs
+ envs = []
+ cam_tensors = []
+ depth_tensors = []
+ # create envs
+ for i in range(self.params.num_envs):
+ env = self.gym.create_env(
+ self.sim,
+ gymapi.Vec3(-self.params.env_size / 2, -self.params.env_size / 2, 0),
+ gymapi.Vec3(
+ self.params.env_size / 2,
+ self.params.env_size / 2,
+ self.params.env_size,
+ ),
+ int(self.params.num_envs**0.5),
+ )
+ envs.append(env)
+
+ quad_actor = self.gym.create_actor(
+ env, quad_asset, self.params.quad_init_pose, "Quadcopter", i, 1
+ )
+
+ cam = self.gym.create_camera_sensor(env, self.params.camera_props)
+ self.gym.attach_camera_to_body(
+ cam, env, quad_actor, self.params.cam_tf, gymapi.FOLLOW_TRANSFORM
+ )
+ depth_gym_tensor = self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, cam, gymapi.IMAGE_DEPTH
+ )
+ depth_tensors.append(gymtorch.wrap_tensor(depth_gym_tensor))
+
+ if i < 10:
+ color_gym_tensor = self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, cam, gymapi.IMAGE_COLOR
+ )
+ cam_tensors.append(gymtorch.wrap_tensor(color_gym_tensor))
+
+ return envs, cam_tensors, depth_tensors
+
+ def _check_key_update_actor_state(self) -> Tuple[bool, bool, bool]:
+ move = False
+ reset = False
+ reset_all = False
+
+ for evt in self.gym.query_viewer_action_events(self.viewer):
+ # guard against key release
+ if evt.value <= 0.0:
+ break
+
+ # select env
+ for env_id in range(10):
+ if evt.action == "env_" + str(env_id) and env_id < self.params.num_envs:
+ self.selected_env_id = env_id
+ print("selected env", env_id)
+ break
+
+ actor_rot_mat = quaternion_to_matrix(
+ self.actor_root_state[:, 3:7].roll(1, dims=1)
+ )
+
+ # change increment
+ if evt.action == "move_inc_down":
+ self.move_inc /= 2
+ print("move increment", self.move_inc)
+
+ elif evt.action == "move_inc_up":
+ self.move_inc *= 2
+ print("move increment", self.move_inc)
+
+ elif evt.action == "rot_inc_down":
+ self.rot_inc /= 2
+ print("rotation increment", self.rot_inc)
+
+ elif evt.action == "rot_inc_up":
+ self.rot_inc *= 2
+ print("rotation increment", self.rot_inc)
+
+ # move
+ elif evt.action == "move_front":
+ displacement = actor_rot_mat[self.selected_env_id, :, 0] * self.move_inc
+ self.actor_root_state[self.selected_env_id, 0:3] += displacement
+ move = True
+
+ elif evt.action == "move_back":
+ displacement = actor_rot_mat[self.selected_env_id, :, 0] * self.move_inc
+ self.actor_root_state[self.selected_env_id, 0:3] -= displacement
+ move = True
+
+ elif evt.action == "move_left":
+ displacement = actor_rot_mat[self.selected_env_id, :, 1] * self.move_inc
+ self.actor_root_state[self.selected_env_id, 0:3] += displacement
+ move = True
+
+ elif evt.action == "move_right":
+ displacement = actor_rot_mat[self.selected_env_id, :, 1] * self.move_inc
+ self.actor_root_state[self.selected_env_id, 0:3] -= displacement
+ move = True
+
+ elif evt.action == "move_up":
+ displacement = actor_rot_mat[self.selected_env_id, :, 2] * self.move_inc
+ self.actor_root_state[self.selected_env_id, 0:3] += displacement
+ move = True
+
+ elif evt.action == "move_down":
+ displacement = actor_rot_mat[self.selected_env_id, :, 2] * self.move_inc
+ self.actor_root_state[self.selected_env_id, 0:3] -= displacement
+ move = True
+
+ # rotation
+ elif evt.action == "roll_left":
+ rotation_q = quat_from_euler_xyz(
+ torch.tensor(-self.rot_inc),
+ torch.tensor(0.0),
+ torch.tensor(0.0),
+ ).to(device="cuda")
+ self.actor_root_state[self.selected_env_id, 3:7] = quat_mul(
+ self.actor_root_state[self.selected_env_id, 3:7], rotation_q
+ )
+ move = True
+
+ elif evt.action == "roll_right":
+ rotation_q = quat_from_euler_xyz(
+ torch.tensor(self.rot_inc), torch.tensor(0.0), torch.tensor(0.0)
+ ).to(device="cuda")
+ self.actor_root_state[self.selected_env_id, 3:7] = quat_mul(
+ self.actor_root_state[self.selected_env_id, 3:7], rotation_q
+ )
+ move = True
+
+ elif evt.action == "pitch_up":
+ rotation_q = quat_from_euler_xyz(
+ torch.tensor(0.0),
+ torch.tensor(-self.rot_inc),
+ torch.tensor(0.0),
+ ).to(device="cuda")
+ self.actor_root_state[self.selected_env_id, 3:7] = quat_mul(
+ self.actor_root_state[self.selected_env_id, 3:7], rotation_q
+ )
+ move = True
+
+ elif evt.action == "pitch_down":
+ rotation_q = quat_from_euler_xyz(
+ torch.tensor(0.0), torch.tensor(self.rot_inc), torch.tensor(0.0)
+ ).to(device="cuda")
+ self.actor_root_state[self.selected_env_id, 3:7] = quat_mul(
+ self.actor_root_state[self.selected_env_id, 3:7], rotation_q
+ )
+ move = True
+
+ elif evt.action == "yaw_left":
+ rotation_q = quat_from_euler_xyz(
+ torch.tensor(0.0), torch.tensor(0.0), torch.tensor(self.rot_inc)
+ ).to(device="cuda")
+ self.actor_root_state[self.selected_env_id, 3:7] = quat_mul(
+ self.actor_root_state[self.selected_env_id, 3:7], rotation_q
+ )
+ move = True
+
+ elif evt.action == "yaw_right":
+ rotation_q = quat_from_euler_xyz(
+ torch.tensor(0.0),
+ torch.tensor(0.0),
+ torch.tensor(-self.rot_inc),
+ ).to(device="cuda")
+ self.actor_root_state[self.selected_env_id, 3:7] = quat_mul(
+ self.actor_root_state[self.selected_env_id, 3:7], rotation_q
+ )
+ move = True
+
+ # reset, no new waypoint
+ elif evt.action == "reset":
+ self.actor_root_state[self.selected_env_id, :3] = self.quad_init_pose_p
+ self.actor_root_state[self.selected_env_id, 3:7] = self.quad_init_pose_q
+ move = True
+ reset = True
+
+ # new waypoints and reset all
+ elif evt.action == "reset_all":
+ self.actor_root_state[:, :3] = self.quad_init_pose_p
+ self.actor_root_state[:, 3:7] = self.quad_init_pose_q
+ move = True
+ reset_all = True
+
+ return move, reset, reset_all
+
+
+if __name__ == "__main__":
+ mdp = Mdp((MdpParams()))
+ mdp.run()
diff --git a/isaacgymenvs/tasks/drone_racing/demos/obstacles.py b/isaacgymenvs/tasks/drone_racing/demos/obstacles.py
new file mode 100644
index 000000000..c6fa416ec
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/obstacles.py
@@ -0,0 +1,157 @@
+import time
+
+from isaacgym import gymapi, gymtorch
+from isaacgymenvs.tasks.drone_racing.env import (
+ EnvCreatorParams,
+ EnvCreator,
+)
+from isaacgymenvs.tasks.drone_racing.managers import (
+ DroneManager,
+ DroneManagerParams,
+ RandDroneOptions,
+)
+from isaacgymenvs.tasks.drone_racing.managers import (
+ ObstacleManager,
+ RandObstacleOptions,
+)
+from isaacgymenvs.tasks.drone_racing.waypoint import (
+ WaypointGenerator,
+ WaypointGeneratorParams,
+ RandWaypointOptions,
+)
+
+print("import torch")
+import torch
+
+if __name__ == "__main__":
+ # settings
+ draw_orbit_min = False
+ draw_orbit_mean = False
+ draw_orbit_max = False
+ draw_wall_region = False
+ run_physics_sim = True
+ torch.manual_seed(42)
+
+ # create sim and gym
+ sim_params = gymapi.SimParams()
+ sim_params.use_gpu_pipeline = True
+ sim_params.physx.use_gpu = True
+ sim_params.up_axis = gymapi.UP_AXIS_Z
+ sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
+
+ gym = gymapi.acquire_gym()
+ sim = gym.create_sim(0, 0, gymapi.SIM_PHYSX, sim_params)
+
+ # create envs
+ env_creator_params = EnvCreatorParams()
+ env_creator_params.disable_tqdm = False
+ env_creator_params.num_envs = 1
+ print("Initializing environment creator...")
+ env_creator = EnvCreator(gym, sim, env_creator_params)
+ print("Creating envs and actors...")
+ env_creator.create([0.0, 0.0, env_creator_params.env_size / 2])
+
+ # all environments are set up, prepare sim
+ gym.prepare_sim(sim)
+ actor_root_state = gymtorch.wrap_tensor(gym.acquire_actor_root_state_tensor(sim))
+ gym.refresh_actor_root_state_tensor(sim)
+
+ # init waypoint generator
+ wp_generator_params = WaypointGeneratorParams()
+ wp_generator_params.num_envs = env_creator_params.num_envs
+ wp_generator_params.num_waypoints = 4
+ wp_generator_params.num_gate_x_lens = len(env_creator_params.gate_bar_len_x)
+ wp_generator_params.num_gate_weights = len(env_creator_params.gate_bar_len_z)
+ wp_generator_params.gate_weight_max = max(env_creator_params.gate_bar_len_z)
+ wp_generator_params.fixed_waypoint_id = 1
+ wp_generator_params.fixed_waypoint_position = [
+ 0.0,
+ 0.0,
+ env_creator_params.env_size / 2,
+ ]
+ wp_generator = WaypointGenerator(wp_generator_params)
+
+ # init actor manager
+ obstacle_manager = ObstacleManager(env_creator)
+ rand_obs_opts = RandObstacleOptions()
+ rand_obs_opts.wall_density = 0
+ rand_obs_opts.tree_density = 0
+ drone_manager_params = DroneManagerParams()
+ drone_manager_params.num_envs = env_creator_params.num_envs
+ drone_manager = DroneManager(drone_manager_params)
+
+ # viewer
+ viewer = gym.create_viewer(sim, gymapi.CameraProperties())
+ gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_R, "randomize")
+ print("Use R key to randomize envs.")
+
+ # update simulation
+ while not gym.query_viewer_has_closed(viewer):
+
+ # check reset key
+ for evt in gym.query_viewer_action_events(viewer):
+ if evt.action == "randomize" and evt.value > 0:
+
+ # generate random waypoints
+ t0 = time.time()
+ rand_wp_options = RandWaypointOptions()
+ rand_wp_options.init_roll_max = 0
+ rand_wp_options.init_pitch_max = 0
+ rand_wp_options.init_yaw_max = 0
+ rand_wp_options.psi_max = 0
+ rand_wp_options.theta_max = 0
+ # rand_wp_options.alpha_max = 0
+ rand_wp_options.gamma_max = 0
+ rand_wp_options.r_min = 10
+ rand_wp_options.r_max = 10
+ rand_wp_options.force_gate_flag = 1
+ wp_data = wp_generator.compute(rand_wp_options)
+
+ # update obstacles
+ actor_pose, actor_id = obstacle_manager.compute(
+ waypoint_data=wp_data, rand_obs_opts=rand_obs_opts
+ )
+ actor_root_state[actor_id, :7] = actor_pose[actor_id].to("cuda")
+
+ # update drone
+ drone_manager.set_waypoint(wp_data)
+ drone_state, act, next_id = drone_manager.compute(RandDroneOptions())
+ actor_root_state[env_creator.drone_actor_id.flatten()] = drone_state
+
+ # submit
+ gym.set_actor_root_state_tensor(
+ sim, gymtorch.unwrap_tensor(actor_root_state)
+ )
+
+ # draw debug geometries
+ t1 = time.time()
+ gym.clear_lines(viewer)
+ wp_data.visualize(gym, env_creator.envs, viewer, 1)
+ orbit_vis_data, wall_vis_data = obstacle_manager.get_vis_data()
+ orbit_vis_data.visualize(
+ gym,
+ env_creator.envs,
+ viewer,
+ draw_min=draw_orbit_min,
+ draw_mean=draw_orbit_mean,
+ draw_max=draw_orbit_max,
+ )
+ if draw_wall_region:
+ wall_vis_data.visualize(gym, env_creator.envs, viewer)
+ t2 = time.time()
+
+ # print time info
+ print("---")
+ print("envs rand:", int((t1 - t0) * 1000), "ms")
+ print("debug vis:", int((t2 - t1) * 1000), "ms")
+
+ # gym.simulate(sim)
+ if run_physics_sim:
+ gym.simulate(sim)
+ gym.fetch_results(sim, True)
+ gym.step_graphics(sim)
+ gym.refresh_actor_root_state_tensor(sim)
+ gym.draw_viewer(viewer, sim, True)
+ gym.sync_frame_time(sim)
+
+ gym.destroy_sim(sim)
diff --git a/isaacgymenvs/tasks/drone_racing/demos/plot_ang_vel.py b/isaacgymenvs/tasks/drone_racing/demos/plot_ang_vel.py
new file mode 100644
index 000000000..8a72951ae
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/plot_ang_vel.py
@@ -0,0 +1,116 @@
+import argparse
+import warnings
+from typing import Dict, Any, List
+
+import torch
+from matplotlib import pyplot as plt
+from matplotlib.ticker import MultipleLocator
+
+
+def pt_to_inch(w, h):
+ return w / 72.27, h / 72.27
+
+
+if __name__ == "__main__":
+ # info
+ print("+++ Plotting desired and controlled angular velocity")
+
+ # Suppress torch.load warning
+ warnings.filterwarnings("ignore", category=FutureWarning)
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument("--log_file", type=str, required=True)
+ arg_parser.add_argument("--episode_id", type=int, required=True)
+ arg_parser.add_argument("--ctrl_dt", type=float, required=True)
+ arg_parser.add_argument("--fig_w", type=float, required=True)
+ arg_parser.add_argument("--fig_h", type=float, required=True)
+ arg_parser.add_argument("--fig_file", type=str, required=True)
+ arg_parser.add_argument("--ang_vel_max", type=float, default=14)
+ arg_parser.add_argument("--font_size", type=int, default=10)
+ arg_parser.add_argument("--font_family", type=str, default="sans-serif")
+ arg_parser.add_argument("--legend_vspace", type=float, default=0.05)
+
+ args = arg_parser.parse_args()
+ log_file: str = args.log_file
+ episode_id: int = args.episode_id
+ ctrl_dt: float = args.ctrl_dt
+ fig_w: float = args.fig_w
+ fig_h: float = args.fig_h
+ fig_file: str = args.fig_file
+ ang_vel_max: float = args.ang_vel_max
+ font_size: int = args.font_size
+ font_family: str = args.font_family
+ legend_vspace: float = args.legend_vspace
+
+ # load log and get data
+ ep_dict: Dict[str, Any] = torch.load(log_file)
+ des_ang_vel_list: List[torch.Tensor] = ep_dict[f"ep_{episode_id}"][
+ "ang_vel_des_b_frd"
+ ]
+ ang_vel_list: List[torch.Tensor] = ep_dict[f"ep_{episode_id}"]["ang_vel_b_frd"]
+
+ # pre-process data
+ des_ang_vel = torch.stack(des_ang_vel_list).flatten(0, 1)
+ ang_vel = torch.stack(ang_vel_list).flatten(0, 1)
+ assert des_ang_vel.shape == ang_vel.shape
+
+ # data to plot
+ t = (torch.arange(des_ang_vel.shape[0]) * ctrl_dt).numpy()
+ des_ang_vel_x = des_ang_vel[:, 0].numpy()
+ des_ang_vel_y = des_ang_vel[:, 1].numpy()
+ des_ang_vel_z = des_ang_vel[:, 2].numpy()
+ ang_vel_x = ang_vel[:, 0].numpy()
+ ang_vel_y = ang_vel[:, 1].numpy()
+ ang_vel_z = ang_vel[:, 2].numpy()
+
+ # plot
+ plt.rcParams.update(
+ {
+ "font.size": font_size,
+ "font.family": font_family,
+ "font.sans-serif": "Arial",
+ "font.serif": "Times New Roman",
+ },
+ )
+ fig, axs = plt.subplots(
+ 3, 1, figsize=pt_to_inch(fig_w, fig_h), sharex="col", constrained_layout=True
+ )
+ axs[-1].set_xlabel("Time (s)")
+ for i in range(3):
+ desired = None
+ measured = None
+ label = None
+ if i == 0:
+ desired = des_ang_vel_x
+ measured = ang_vel_x
+ label = "X (rad/s)"
+ elif i == 1:
+ desired = des_ang_vel_y
+ measured = ang_vel_y
+ label = "Y (rad/s)"
+
+ elif i == 2:
+ desired = des_ang_vel_z
+ measured = ang_vel_z
+ label = "Z (rad/s)"
+
+ axs[i].plot(t, desired, label="Desired Angular Velocity")
+ axs[i].plot(t, measured, label="Measured Angular Velocity")
+ axs[i].grid(True)
+ axs[i].set_xlim([t[0], t[-1]])
+ axs[i].set_ylim([-ang_vel_max, ang_vel_max])
+ axs[i].set_ylabel(label)
+ axs[i].minorticks_on()
+ axs[i].xaxis.set_minor_locator(MultipleLocator(0.1))
+
+ if i == 0:
+ axs[i].legend(
+ bbox_to_anchor=(0.0, 1 + legend_vspace, 1.0, 1.0),
+ loc="lower right",
+ ncols=2,
+ borderaxespad=0.0,
+ )
+
+ plt.savefig(fig_file)
+ print(f"Plot saved to {fig_file}")
diff --git a/isaacgymenvs/tasks/drone_racing/demos/plot_guidance_reward.py b/isaacgymenvs/tasks/drone_racing/demos/plot_guidance_reward.py
new file mode 100644
index 000000000..88bf46bac
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/plot_guidance_reward.py
@@ -0,0 +1,221 @@
+import argparse
+import time
+from math import sin, cos, radians
+
+import numpy as np
+import plotly.graph_objects as go
+
+from isaacgym import gymapi
+from isaacgymenvs.tasks.drone_racing.mdp import RewardParams, Reward
+from isaacgymenvs.tasks.drone_racing.waypoint import WaypointData
+
+print("Importing torch...")
+import torch # noqa
+
+
+def pt_to_px(pt):
+ return pt * (96 / 72)
+
+
+if __name__ == "__main__":
+ # info
+ print("+++ Plotting guidance reward")
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument("--device", type=str, default="cuda")
+ arg_parser.add_argument("--wp_w", type=float, default=3)
+ arg_parser.add_argument("--wp_h", type=float, default=1.6)
+ arg_parser.add_argument("--space_x", type=float, default=4)
+ arg_parser.add_argument("--space_y", type=float, default=4)
+ arg_parser.add_argument("--space_z", type=float, default=4)
+ arg_parser.add_argument("--points_x", type=int, default=21)
+ arg_parser.add_argument("--points_y", type=int, default=100)
+ arg_parser.add_argument("--points_z", type=int, default=100)
+ arg_parser.add_argument("--fig_x_scale", type=float, default=7.5)
+ arg_parser.add_argument("--fig_w", type=float, required=True)
+ arg_parser.add_argument("--fig_h", type=float, required=True)
+ arg_parser.add_argument("--fig_file", type=str, required=True)
+ arg_parser.add_argument("--font_size", type=float, default=7)
+ arg_parser.add_argument("--cam_dist", type=float, default=2)
+ arg_parser.add_argument("--cam_azm", type=float, default=65)
+ arg_parser.add_argument("--cam_ele", type=float, default=15)
+ args = arg_parser.parse_args()
+
+ # settings
+ compute_device = args.device
+ wp_w = args.wp_w
+ wp_h = args.wp_h
+ space_len_x = args.space_x
+ space_len_y = args.space_y
+ space_len_z = args.space_z
+ num_points_x = args.points_x
+ num_points_y = args.points_y
+ num_points_z = args.points_z
+ fig_x_axis_scale = args.fig_x_scale
+ font_size = args.font_size
+ cam_r_to_center = args.cam_dist
+ cam_angles = [args.cam_azm, args.cam_ele]
+ w_pt = args.fig_w
+ h_pt = args.fig_h
+ fig_f = args.fig_file
+
+ # generate the grid points
+ x_range = torch.linspace(-space_len_x, space_len_x, num_points_x)
+ y_range = torch.linspace(-space_len_y, space_len_y, num_points_y)
+ z_range = torch.linspace(-space_len_z, space_len_z, num_points_z)
+
+ # create a meshgrid using torch
+ x_grid, y_grid, z_grid = torch.meshgrid(x_range, y_range, z_range, indexing="ij")
+
+ # flatten the grid points
+ x = x_grid.flatten()
+ y = y_grid.flatten()
+ z = z_grid.flatten()
+ points = torch.stack((x, y, z), dim=-1)
+ num_points = points.shape[0]
+
+ # use parallel envs to compute the reward
+ num_envs = num_points
+
+ # create waypoint data
+ wp_quaternion = torch.zeros(num_envs, 2, 4)
+ wp_quaternion[:, :, -1] = 1
+ wp_data = WaypointData(
+ position=torch.zeros(num_envs, 2, 3),
+ quaternion=wp_quaternion,
+ width=torch.ones(num_envs, 2) * wp_w,
+ height=torch.ones(num_envs, 2) * wp_h,
+ gate_flag=torch.zeros(num_envs, 2, dtype=torch.bool),
+ gate_x_len_choice=torch.zeros(num_envs, 2),
+ gate_weight_choice=torch.zeros(num_envs, 2),
+ psi=torch.zeros(num_envs, 1),
+ theta=torch.zeros(num_envs, 1),
+ gamma=torch.zeros(num_envs, 1),
+ r=torch.zeros(num_envs, 1),
+ )
+
+ # create reward calculator
+ reward_params = RewardParams()
+ reward_params.num_envs = num_envs
+ reward_params.device = compute_device
+ reward_params.guidance_x_thresh = 3
+ # reward_params.k_guidance = 0.1
+ # reward_params.k_rejection = 10
+ mdp_reward = Reward(reward_params)
+
+ # compute reward and get guidance term
+ drone_state = torch.zeros(wp_data.num_envs, 13, device=compute_device)
+ drone_state[:, 6] = 1.0
+ action = torch.zeros(wp_data.num_envs, 4, device=compute_device)
+ mdp_reward.set_waypoint_and_cam(
+ wp_data=wp_data,
+ cam_tf=[gymapi.Transform()] * wp_data.num_envs,
+ )
+ mdp_reward.set_init_drone_state_action(drone_state, action)
+
+ drone_state[:, :3] = points.to(device=compute_device)
+ drone_collision = timeout = wp_passing = torch.zeros(
+ wp_data.num_envs, dtype=torch.bool, device=compute_device
+ )
+ next_wp_id = torch.ones(wp_data.num_envs, dtype=torch.int, device=compute_device)
+ t0 = time.time()
+ r = mdp_reward.compute(
+ drone_state, action, drone_collision, timeout, wp_passing, next_wp_id
+ )
+ r_guidance = mdp_reward.reward_guidance
+ t1 = time.time()
+ print("number of points:", num_points)
+ print("calculation:", int((t1 - t0) * 1000), "ms")
+
+ # reward field
+ reward_field = go.Scatter3d(
+ x=x.numpy(),
+ y=y.numpy(),
+ z=z.numpy(),
+ mode="markers",
+ marker=dict(
+ size=0.5,
+ color=r_guidance.cpu().numpy(), # Set color to the rewards
+ colorscale="Viridis", # Choose a colorscale
+ colorbar=dict(
+ title="",
+ orientation="h",
+ thickness=6,
+ tickfont=dict(size=pt_to_px(font_size / 1.25)),
+ ), # Show colorbar
+ opacity=0.3,
+ ),
+ )
+
+ # gate
+ x_gate = [0, 0, 0, 0, 0] # Closed loop
+ y_gate = [-wp_w / 2, -wp_w / 2, wp_w / 2, wp_w / 2, -wp_w / 2]
+ z_gate = [-wp_h / 2, wp_h / 2, wp_h / 2, -wp_h / 2, -wp_h / 2]
+ gate = go.Scatter3d(
+ x=x_gate,
+ y=y_gate,
+ z=z_gate,
+ mode="lines", # Use lines to create the outline
+ line=dict(color="black", width=2), # Outline color and width
+ )
+
+ # frame
+ x_axis = go.Scatter3d(
+ x=[0, 1 / fig_x_axis_scale],
+ y=[0, 0],
+ z=[0, 0],
+ mode="lines",
+ line=dict(color="red", width=2),
+ )
+ y_axis = go.Scatter3d(
+ x=[0, 0],
+ y=[0, 1],
+ z=[0, 0],
+ mode="lines",
+ line=dict(color="green", width=2),
+ )
+ z_axis = go.Scatter3d(
+ x=[0, 0],
+ y=[0, 0],
+ z=[0, 1],
+ mode="lines",
+ line=dict(color="blue", width=2),
+ )
+
+ layout = go.Layout(
+ # title="Guidance Reward Field",
+ width=pt_to_px(w_pt),
+ height=pt_to_px(h_pt),
+ scene=dict(
+ xaxis=dict(
+ title="",
+ tickvals=np.arange(-space_len_x, space_len_x + 0.4, 0.4),
+ ticktext=[
+ f"{val:.1f}"
+ for val in np.arange(-space_len_x, space_len_x + 0.4, 0.4)
+ ],
+ tickfont=dict(size=pt_to_px(font_size)), # Set smaller tick font size
+ ),
+ yaxis=dict(title="", tickvals=[], ticktext=[]),
+ zaxis=dict(title="", tickvals=[], ticktext=[]),
+ camera=dict(
+ eye=dict(
+ x=cam_r_to_center
+ * cos(radians(cam_angles[1]))
+ * cos(radians(cam_angles[0])),
+ y=cam_r_to_center
+ * cos(radians(cam_angles[1]))
+ * sin(radians(cam_angles[0])),
+ z=cam_r_to_center * sin(radians(cam_angles[1])),
+ )
+ ),
+ aspectmode="manual",
+ aspectratio=dict(x=fig_x_axis_scale, y=1, z=1),
+ ),
+ showlegend=False,
+ font=dict(family="Times New Roman"),
+ margin=dict(l=2, r=2, t=2, b=2, pad=0),
+ )
+ fig = go.Figure(data=[reward_field, gate, x_axis, y_axis, z_axis], layout=layout)
+ fig.write_image(fig_f, format="pdf", engine="kaleido", scale=10)
diff --git a/isaacgymenvs/tasks/drone_racing/demos/plot_perf_test.py b/isaacgymenvs/tasks/drone_racing/demos/plot_perf_test.py
new file mode 100644
index 000000000..35ff93120
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/plot_perf_test.py
@@ -0,0 +1,179 @@
+import argparse
+from typing import List
+
+import numpy as np
+from PIL import Image
+from matplotlib import pyplot as plt
+from matplotlib.ticker import EngFormatter
+
+
+def pt_to_inch(w, h):
+ return w / 72.27, h / 72.27
+
+
+if __name__ == "__main__":
+ # info
+ print("+++ Plotting simulator performance")
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument("--env_img", type=str, required=True)
+ arg_parser.add_argument("--num_envs_no_cam", type=int, nargs="+", required=True)
+ arg_parser.add_argument("--total_fps_no_cam", type=int, nargs="+", required=True)
+ arg_parser.add_argument("--vram_no_cam", type=int, nargs="+", required=True)
+ arg_parser.add_argument("--num_envs_cam", type=int, nargs="+", required=True)
+ arg_parser.add_argument("--total_fps_cam", type=int, nargs="+", required=True)
+ arg_parser.add_argument("--vram_cam", type=int, nargs="+", required=True)
+ arg_parser.add_argument("--fig_w", type=float, required=True)
+ arg_parser.add_argument("--fig_h", type=float, required=True)
+ arg_parser.add_argument("--fig_file", type=str, required=True)
+ arg_parser.add_argument("--font_size", type=float, default=8)
+ arg_parser.add_argument("--font_family", type=str, default="sans-serif")
+ arg_parser.add_argument("--yaxis_offset", type=float, default=1.15)
+ arg_parser.add_argument("--marker_size", type=int, default=4)
+ arg_parser.add_argument("--dpi", type=int, default=1000)
+ arg_parser.add_argument("--legend_vspace", type=float, default=0.25)
+
+ args = arg_parser.parse_args()
+ img_path: str = args.env_img
+ num_envs_no_cam: List[int] = args.num_envs_no_cam
+ total_fps_no_cam: List[int] = args.total_fps_no_cam
+ vram_no_cam: List[int] = args.vram_no_cam
+ num_envs_cam: List[int] = args.num_envs_cam
+ total_fps_cam: List[int] = args.total_fps_cam
+ vram_cam: List[int] = args.vram_cam
+ fig_w: float = args.fig_w
+ fig_h: float = args.fig_h
+ fig_file: str = args.fig_file
+ font_size: float = args.font_size
+ font_family: str = args.font_family
+ yaxis_offset: float = args.yaxis_offset
+ marker_size: int = args.marker_size
+ dpi: int = args.dpi
+ legend_vspace: float = args.legend_vspace
+
+ # check args
+ assert len(num_envs_no_cam) == len(total_fps_no_cam) == len(vram_no_cam)
+ assert len(num_envs_cam) == len(total_fps_cam) == len(vram_cam)
+ print("---")
+ print("image:", img_path)
+ print("---")
+ print("num_envs_no_cam:", num_envs_no_cam)
+ print("total_fps_no_cam:", total_fps_no_cam)
+ print("vram_no_cam:", vram_no_cam)
+ print("---")
+ print("num_envs_cam:", num_envs_cam)
+ print("total_fps_cam:", total_fps_cam)
+ print("vram_cam:", vram_cam)
+ print("---")
+
+ # load screenshot
+ img: np.ndarray = np.asarray(Image.open(img_path))
+
+ # plot
+ plt.rcParams.update(
+ {
+ "font.size": font_size,
+ "font.family": font_family,
+ "font.sans-serif": "Arial",
+ "font.serif": "Times New Roman",
+ },
+ )
+ fig, axs = plt.subplots(
+ 1, 3, figsize=pt_to_inch(fig_w, fig_h), constrained_layout=True
+ )
+
+ # image
+ axs[0].imshow(img, interpolation="lanczos")
+ axs[0].tick_params(
+ axis="x", which="both", bottom=False, top=False, labelbottom=False
+ )
+ axs[0].tick_params(axis="y", which="both", left=False, right=False, labelleft=False)
+
+ legend_lines = None
+ legend_labels = None
+ for i in range(2):
+ num_envs = None
+ total_fps = None
+ vram = None
+ fps = None
+ ylim_total_fps = None
+ xlim = None
+ xlabel = None
+ if i == 0:
+ num_envs = num_envs_no_cam
+ total_fps = total_fps_no_cam
+ vram = np.array(vram_no_cam) / (24 * 1024)
+ fps = np.array(total_fps_no_cam) / np.array(num_envs_no_cam)
+ ylim_total_fps = [0, 500_000]
+ xlim = [0, 24576]
+ xlabel = "Number of Environments without Camera"
+ else:
+ num_envs = num_envs_cam
+ total_fps = total_fps_cam
+ vram = np.array(vram_cam) / (24 * 1024)
+ fps = np.array(total_fps_cam) / np.array(num_envs_cam)
+ ylim_total_fps = [0, 5_000]
+ xlim = [0, 1400]
+ xlabel = "Number of Environments with Camera"
+
+ twin_fps = axs[i + 1].twinx()
+ twin_vram = axs[i + 1].twinx()
+ twin_fps.spines.right.set_position(("axes", yaxis_offset))
+
+ (l_total_fps,) = axs[i + 1].plot(
+ num_envs,
+ total_fps,
+ color="tab:blue",
+ marker=".",
+ ms=marker_size,
+ label="Total SPS",
+ )
+ (l_fps,) = twin_fps.plot(
+ num_envs, fps, color="tab:orange", marker=".", ms=marker_size, label="SPS"
+ )
+ (l_vram,) = twin_vram.plot(
+ num_envs,
+ vram,
+ color="tab:green",
+ marker=".",
+ ms=marker_size,
+ label="VRAM",
+ )
+
+ axs[i + 1].yaxis.set_major_formatter(EngFormatter())
+ axs[i + 1].xaxis.set_major_formatter(EngFormatter())
+ axs[i + 1].grid(True)
+ axs[i + 1].set_ylim(ylim_total_fps)
+ axs[i + 1].set_xlim(xlim)
+ axs[i + 1].set_xlabel(xlabel)
+ axs[i + 1].tick_params(axis="y", colors=l_total_fps.get_color())
+
+ twin_fps.tick_params(axis="y", colors=l_fps.get_color())
+ twin_fps.set_ylim(0, 120)
+
+ twin_vram.tick_params(axis="y", colors=l_vram.get_color())
+ twin_vram.set_ylim(0, 1)
+
+ if i == 0:
+ twin_fps.axis("off")
+ twin_vram.axis("off")
+ legend_lines = [l_total_fps, l_fps, l_vram]
+ legend_labels = [
+ l_total_fps.get_label(),
+ l_fps.get_label(),
+ l_vram.get_label(),
+ ]
+
+ axs[0].legend(
+ legend_lines,
+ legend_labels,
+ bbox_to_anchor=(0.0, -legend_vspace, 1.0, 1.0),
+ loc="lower right",
+ ncols=3,
+ mode="expand",
+ borderaxespad=0.0,
+ )
+
+ plt.savefig(fig_file, dpi=dpi)
+ print(f"Plot saved to {fig_file}")
diff --git a/isaacgymenvs/tasks/drone_racing/demos/plot_policy_metrics.py b/isaacgymenvs/tasks/drone_racing/demos/plot_policy_metrics.py
new file mode 100644
index 000000000..614d319d5
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/plot_policy_metrics.py
@@ -0,0 +1,179 @@
+import argparse
+import os.path
+import warnings
+from typing import List, Dict, Any
+
+import numpy as np
+import torch
+from matplotlib import pyplot as plt
+from matplotlib.patches import Patch
+
+
+def pt_to_inch(w, h):
+ return w / 72.27, h / 72.27
+
+
+def main():
+ # info
+ print("+++ Plotting policy metrics vs. task complexity")
+
+ # Suppress torch.load warning
+ warnings.filterwarnings("ignore", category=FutureWarning)
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument(
+ "--exp_dirs",
+ type=str,
+ nargs="+",
+ required=True,
+ help="experiment directories given in order of simple to hard",
+ )
+ arg_parser.add_argument("--font_size", type=float, default=6)
+ arg_parser.add_argument("--font_family", type=str, default="serif")
+ arg_parser.add_argument("--fig_w", type=float, required=True)
+ arg_parser.add_argument("--fig_h", type=float, required=True)
+ arg_parser.add_argument("--fig_file", type=str, required=True)
+ arg_parser.add_argument("--dpi", type=int, default=1000)
+
+ args = arg_parser.parse_args()
+ exp_dirs: List[str] = args.exp_dirs
+ font_size: float = args.font_size
+ font_family: str = args.font_family
+ fig_w: float = args.fig_w
+ fig_h: float = args.fig_h
+ fig_file: str = args.fig_file
+ dpi: int = args.dpi
+
+ # aggregate metrics
+ success_rates: List[float] = [] # length will be num_exps
+ safety_margins: List[List[float]] = []
+ avg_lin_speeds: List[List[float]] = []
+ max_lin_speeds: List[List[float]] = []
+ avg_ang_speeds: List[List[float]] = []
+ max_ang_speeds: List[List[float]] = []
+ avg_avg_rotor_cmds: List[List[float]] = []
+ max_avg_rotor_cmds: List[List[float]] = []
+ for exp_dir in exp_dirs:
+ # load metrics file
+ exp_metrics: Dict[str, Any] = torch.load(os.path.join(exp_dir, "metrics.pt"))
+
+ # print data
+ sr = exp_metrics["num_finishes"] / (
+ exp_metrics["num_finishes"]
+ + exp_metrics["num_crashes"]
+ + exp_metrics["num_timeouts"]
+ )
+ print(exp_dir)
+ print(f"- sr = {sr}")
+ print(f"- avg_lin_speed = {np.mean(exp_metrics['avg_lin_speeds'])}")
+ print(f"- max_lin_speed = {np.max(exp_metrics['max_lin_speeds'])}")
+ print(f"- avg_ang_speed = {np.mean(exp_metrics['avg_ang_speeds'])}")
+ print(f"- max_ang_speed = {np.max(exp_metrics['max_ang_speeds'])}")
+ print(f"- avg_avg_rotor_cmd = {np.mean(exp_metrics['avg_avg_rotor_cmds'])}")
+ print(f"- max_avg_rotor_cmd = {np.max(exp_metrics['max_avg_rotor_cmds'])}")
+
+ # append info
+ success_rates.append(sr)
+ safety_margins.append(exp_metrics["min_safety_margins"])
+ avg_lin_speeds.append(exp_metrics["avg_lin_speeds"])
+ max_lin_speeds.append(exp_metrics["max_lin_speeds"])
+ avg_ang_speeds.append(exp_metrics["avg_ang_speeds"])
+ max_ang_speeds.append(exp_metrics["max_ang_speeds"])
+ avg_avg_rotor_cmds.append(exp_metrics["avg_avg_rotor_cmds"])
+ max_avg_rotor_cmds.append(exp_metrics["max_avg_rotor_cmds"])
+
+ # plot data
+ plt.rcParams.update(
+ {
+ "font.size": font_size,
+ "font.family": font_family,
+ "font.sans-serif": "Arial",
+ "font.serif": "Times New Roman",
+ },
+ )
+ fig, axs = plt.subplots(
+ 2, 2, figsize=pt_to_inch(fig_w, fig_h), constrained_layout=True, sharex="col"
+ )
+
+ # safety margin and success rate
+ axs[0][0].violinplot(safety_margins, showmeans=True)
+ axs[0][0].plot(np.arange(len(success_rates)) + 1, success_rates, marker=".")
+ axs[0][0].grid(True)
+ legend_elements = [
+ Patch(facecolor="tab:blue", label="Safety Margin"),
+ Patch(facecolor="tab:orange", label="Success Rate"),
+ ]
+ axs[0][0].legend(handles=legend_elements)
+ axs[0][0].set_ylim([0, 1.2])
+ axs[0][0].set_ylabel("Safety Margin (m) and Success Rate")
+ axs[0][0].yaxis.set_label_coords(-0.175, 0.5)
+
+ # rotor commands
+ axs[0][1].violinplot(
+ avg_avg_rotor_cmds,
+ showmeans=True,
+ positions=np.arange(1, len(avg_avg_rotor_cmds) + 1) - 0.125,
+ )
+ axs[0][1].violinplot(
+ max_avg_rotor_cmds,
+ showmeans=True,
+ positions=np.arange(1, len(max_avg_rotor_cmds) + 1) + 0.125,
+ )
+ axs[0][1].grid(True)
+ legend_elements = [
+ Patch(facecolor="tab:blue", label="Mean"),
+ Patch(facecolor="tab:orange", label="Max"),
+ ]
+ axs[0][1].legend(handles=legend_elements)
+ axs[0][1].set_ylabel("Average Motor Commands")
+ axs[0][1].yaxis.set_label_coords(-0.175, 0.5)
+
+ # linear speed
+ axs[1][0].violinplot(
+ avg_lin_speeds,
+ showmeans=True,
+ positions=np.arange(1, len(avg_lin_speeds) + 1) - 0.125,
+ )
+ axs[1][0].violinplot(
+ max_lin_speeds,
+ showmeans=True,
+ positions=np.arange(1, len(max_lin_speeds) + 1) + 0.125,
+ )
+ axs[1][0].grid(True)
+ axs[1][0].set_xlabel("Difficulty Level")
+ legend_elements = [
+ Patch(facecolor="tab:blue", label="Mean"),
+ Patch(facecolor="tab:orange", label="Max"),
+ ]
+ axs[1][0].legend(handles=legend_elements)
+ axs[1][0].set_ylabel("Linear Speed (m/s)")
+ axs[1][0].yaxis.set_label_coords(-0.175, 0.5)
+
+ # angular speed
+ axs[1][1].violinplot(
+ avg_ang_speeds,
+ showmeans=True,
+ positions=np.arange(1, len(avg_ang_speeds) + 1) - 0.125,
+ )
+ axs[1][1].violinplot(
+ max_ang_speeds,
+ showmeans=True,
+ positions=np.arange(1, len(max_ang_speeds) + 1) + 0.125,
+ )
+ axs[1][1].grid(True)
+ axs[1][1].set_xlabel("Difficulty Level")
+ legend_elements = [
+ Patch(facecolor="tab:blue", label="Mean"),
+ Patch(facecolor="tab:orange", label="Max"),
+ ]
+ axs[1][1].legend(handles=legend_elements)
+ axs[1][1].set_ylabel("Angular Speed (rad/s)")
+ axs[1][1].yaxis.set_label_coords(-0.175, 0.5)
+
+ plt.savefig(fig_file, dpi=dpi)
+ print(f"Plot saved to {fig_file}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/isaacgymenvs/tasks/drone_racing/demos/plot_train_log.py b/isaacgymenvs/tasks/drone_racing/demos/plot_train_log.py
new file mode 100644
index 000000000..9df0c408f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/plot_train_log.py
@@ -0,0 +1,139 @@
+import argparse
+
+import numpy as np
+import pandas as pd
+from matplotlib import pyplot as plt
+from matplotlib.ticker import EngFormatter
+
+
+def pt_to_inch(w, h):
+ return w / 72.27, h / 72.27
+
+
+if __name__ == "__main__":
+ # info
+ print("+++ Plotting train log")
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument("--ep_len_csv", type=str, required=True)
+ arg_parser.add_argument("--rew_csv", type=str, required=True)
+ arg_parser.add_argument("--rew_col_csv", type=str, default="")
+ arg_parser.add_argument("--rew_wp_csv", type=str, default="")
+ arg_parser.add_argument("--fig_w", type=float, required=True)
+ arg_parser.add_argument("--fig_h", type=float, required=True)
+ arg_parser.add_argument("--fig_file", type=str, required=True)
+ arg_parser.add_argument("--font_size", type=float, default=6)
+ arg_parser.add_argument("--font_family", type=str, default="sans-serif")
+ arg_parser.add_argument("--xlim_low", type=float, default=0)
+ arg_parser.add_argument("--xlim_high", type=float, required=True)
+ arg_parser.add_argument("--lwidth", type=float, default=0.5)
+
+ args = arg_parser.parse_args()
+ ep_len_csv: str = args.ep_len_csv
+ rew_csv: str = args.rew_csv
+ rew_col_csv: str = args.rew_col_csv
+ rew_wp_csv: str = args.rew_wp_csv
+ fig_w: float = args.fig_w
+ fig_h: float = args.fig_h
+ fig_file: str = args.fig_file
+ font_size: float = args.font_size
+ font_family: str = args.font_family
+ xlim_low: float = args.xlim_low
+ xlim_high: float = args.xlim_high
+ lwidth: float = args.lwidth
+
+ # load csv
+ ep_len_df = pd.read_csv(ep_len_csv)
+ rew_df = pd.read_csv(rew_csv)
+ rew_col_df = None
+ rew_wp_df = None
+ if rew_col_csv != "":
+ rew_col_df = pd.read_csv(rew_col_csv)
+ if rew_wp_csv != "":
+ rew_wp_df = pd.read_csv(rew_wp_csv)
+
+ # extract data
+ global_step = np.asarray(ep_len_df["global_step"])
+ ep_len = np.asarray(ep_len_df.iloc[:, 4])
+ rew = np.asarray(rew_df.iloc[:, 4])
+ rew_col = None
+ rew_wp = None
+ if rew_col_csv != "":
+ rew_col = rew_col_df.iloc[:, 4]
+ if rew_wp_csv != "":
+ rew_wp = rew_wp_df.iloc[:, 4]
+
+ assert len(ep_len) == len(rew) == len(ep_len)
+
+ # plot
+ plt.rcParams.update(
+ {
+ "font.size": font_size,
+ "font.family": font_family,
+ "font.sans-serif": "Arial",
+ "font.serif": "Times New Roman",
+ },
+ )
+
+ if rew_col_csv == "" and rew_col_csv == "":
+ print("plotting only ep length and total reward")
+ fig, axs = plt.subplots(
+ 1, 2, figsize=pt_to_inch(fig_w, fig_h), constrained_layout=True
+ )
+
+ for i in [0, 1]:
+ item = None
+ label = None
+ if i == 0:
+ item = rew
+ label = "Mean Episode Reward"
+ else:
+ item = ep_len
+ label = "Mean Episode Length"
+ axs[i].plot(global_step, item)
+ axs[i].xaxis.set_major_formatter(EngFormatter())
+ axs[i].grid(True)
+ axs[i].set_ylabel(label)
+ axs[i].set_xlabel("Number of Total Steps")
+ axs[i].set_xlim([xlim_low, xlim_high])
+
+ elif rew_col_csv != "" or rew_col_csv != "":
+ print("plotting ep len, total rew, collision rew, wp rew")
+ fig, axs = plt.subplots(
+ 4,
+ 1,
+ figsize=pt_to_inch(fig_w, fig_h),
+ constrained_layout=True,
+ sharex="col",
+ )
+
+ for i in [0, 1, 2, 3]:
+ item = None
+ if i == 0:
+ item = ep_len
+ if i == 1:
+ item = rew
+ if i == 2:
+ item = rew_col
+ axs[i].set_ylim([-10, 0])
+ if i == 3:
+ item = rew_wp
+ axs[i].set_ylim([0, 10])
+ axs[i].plot(global_step, item, linewidth=lwidth)
+ axs[i].xaxis.set_major_formatter(EngFormatter())
+ axs[i].grid(True)
+ axs[i].set_xlim([xlim_low, xlim_high])
+ axs[i].yaxis.set_label_coords(-0.1, 0.5)
+
+ axs[0].set_ylabel("Mean Episode Length")
+ axs[1].set_ylabel("Mean Total Reward")
+ axs[2].set_ylabel("Mean Collision Reward")
+ axs[3].set_ylabel("Mean Waypoint Reward")
+ axs[3].set_xlabel("Number of Total Steps")
+
+ else:
+ raise ValueError
+
+ plt.savefig(fig_file)
+ print(f"Plot saved to {fig_file}")
diff --git a/isaacgymenvs/tasks/drone_racing/demos/plot_traj_splits_turns.py b/isaacgymenvs/tasks/drone_racing/demos/plot_traj_splits_turns.py
new file mode 100644
index 000000000..7683c77ab
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/plot_traj_splits_turns.py
@@ -0,0 +1,94 @@
+import argparse
+
+import numpy as np
+from PIL import Image
+from matplotlib import pyplot as plt
+from matplotlib.cm import ScalarMappable
+from matplotlib.colors import Normalize
+
+
+def pt_to_inch(w, h):
+ return w / 72.27, h / 72.27
+
+
+if __name__ == "__main__":
+ # info
+ print("+++ Plotting trajectories on Split-S and Turns")
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument("--img_splits", type=str, required=True)
+ arg_parser.add_argument("--img_turns", type=str, required=True)
+ arg_parser.add_argument("--max_v", type=float, required=True)
+ arg_parser.add_argument("--colormap", type=str, required=True)
+ arg_parser.add_argument("--fig_w", type=float, required=True)
+ arg_parser.add_argument("--fig_h", type=float, required=True)
+ arg_parser.add_argument("--fig_file", type=str, required=True)
+ arg_parser.add_argument("--font_size", type=float, default=8)
+ arg_parser.add_argument("--font_family", type=str, default="sans-serif")
+ arg_parser.add_argument("--dpi", type=int, default=1000)
+ arg_parser.add_argument("--cbar_aspect", type=float, default=45)
+
+ args = arg_parser.parse_args()
+ img_splits_path: str = args.img_splits
+ img_turns_path: str = args.img_turns
+ max_v: float = args.max_v
+ colormap: str = args.colormap
+ fig_w: float = args.fig_w
+ fig_h: float = args.fig_h
+ fig_file: str = args.fig_file
+ font_size: float = args.font_size
+ font_family: str = args.font_family
+ dpi: float = args.dpi
+ cbar_aspect: float = args.cbar_aspect
+
+ # load images
+ img_splits: np.ndarray = np.asarray(Image.open(img_splits_path))
+ img_turns: np.ndarray = np.asarray(Image.open(img_turns_path))
+
+ # plot
+ plt.rcParams.update(
+ {
+ "font.size": font_size,
+ "font.family": font_family,
+ "font.sans-serif": "Arial",
+ "font.serif": "Times New Roman",
+ },
+ )
+ fig, axs = plt.subplots(
+ 1, 2, figsize=pt_to_inch(fig_w, fig_h), constrained_layout=True
+ )
+
+ for i in [0, 1]:
+ img = None
+ label = None
+ if i == 0:
+ img = img_splits
+ label = "Split-S"
+ else:
+ img = img_turns
+ label = "Turns"
+
+ im = axs[i].imshow(img, interpolation="lanczos")
+ axs[i].tick_params(
+ axis="y", which="both", left=False, right=False, labelleft=False
+ )
+ axs[i].tick_params(
+ axis="x", which="both", bottom=False, top=False, labelbottom=False
+ )
+ axs[i].set_xlabel(label)
+
+ norm = Normalize(vmin=0, vmax=25) # Define the color range
+ sm = ScalarMappable(norm=norm, cmap="plasma")
+ sm.set_array([])
+ cbar = fig.colorbar(
+ sm,
+ ax=axs[i],
+ orientation="horizontal",
+ location="top",
+ aspect=cbar_aspect,
+ shrink=1.0,
+ )
+
+ plt.savefig(fig_file, dpi=dpi)
+ print(f"Plot saved to {fig_file}")
diff --git a/isaacgymenvs/tasks/drone_racing/demos/process_logs.py b/isaacgymenvs/tasks/drone_racing/demos/process_logs.py
new file mode 100644
index 000000000..68281e8b3
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/process_logs.py
@@ -0,0 +1,404 @@
+import argparse
+import gc
+import multiprocessing as mp
+import os
+import time
+import warnings
+from typing import Dict, Any, List, Tuple
+
+import numpy as np
+import open3d as o3d
+import torch
+
+
+def empty_log_items_dict() -> Dict[str, List[Any]]:
+ return {
+ "t": [],
+ "main_depth": [],
+ "main_color": [],
+ "min_dist_to_obstacle": [],
+ "main_cam_pose": [],
+ "action": [],
+ "next_waypoint_p": [],
+ "ang_vel_des_b_frd": [],
+ "rotor_cmd": [],
+ "position_w": [],
+ "quaternion_w": [],
+ "lin_vel_w": [],
+ "lin_vel_b_frd": [],
+ "ang_vel_b_frd": [],
+ "is_finished": [],
+ "is_crashed": [],
+ "is_timeout": [],
+ }
+
+
+def pcd_from_np_array(points: np.ndarray) -> o3d.geometry.PointCloud:
+ return o3d.geometry.PointCloud(o3d.utility.Vector3dVector(points))
+
+
+def convert_o3d(mat: np.ndarray) -> np.ndarray:
+ ret = mat.copy()
+ ret[:3, 0] = -mat[:3, 1]
+ ret[:3, 1] = -mat[:3, 2]
+ ret[:3, 2] = mat[:3, 0]
+ return ret
+
+
+def pinhole_depth_to_pcd(
+ depth: np.ndarray, intrinsic: o3d.camera.PinholeCameraIntrinsic, tf: np.ndarray
+) -> o3d.geometry.PointCloud:
+ pcd: o3d.geometry.PointCloud = o3d.geometry.PointCloud.create_from_depth_image(
+ depth=o3d.geometry.Image(depth),
+ intrinsic=intrinsic,
+ ) # noqa
+ return pcd.transform(tf)
+
+
+def process_log(
+ global_env_id: int,
+ num_substeps: int,
+ sim_dt: float,
+ pcd_proc_params: Dict[str, Any],
+ ep_dict: Dict[str, Any], # dict containing keys "ep_0", "ep_1", ...
+ pcd_points: np.ndarray,
+ env_step: List[int],
+ episode_id: torch.Tensor, # (num_envs, )
+ episode_progress: torch.Tensor, # (num_steps, )
+ main_depth: torch.Tensor, # (num_steps, h, w)
+ main_color: torch.Tensor, # (num_steps, h, w, 4)
+ extra_depth: torch.Tensor, # (num_steps, 6, cam_h, cam_w)
+ min_dist_to_obstacle: torch.Tensor, # (num_steps, )
+ main_cam_pose: torch.Tensor, # (num_steps, 12)
+ action: torch.Tensor, # (num_steps, 4)
+ next_waypoint_p: torch.Tensor, # (num_steps, 3)
+ ang_vel_des_b_frd: torch.Tensor, # (num_steps, ctrl_freq_inv, 3)
+ rotor_cmd: torch.Tensor, # (num_steps, ctrl_freq_inv, 4)
+ position_w: torch.Tensor, # (num_steps, ctrl_freq_inv, 3)
+ quaternion_w: torch.Tensor, # (num_steps, ctrl_freq_inv, 4)
+ lin_vel_w: torch.Tensor, # (num_steps, ctrl_freq_inv, 3)
+ lin_vel_b_frd: torch.Tensor, # (num_steps, ctrl_freq_inv, 3)
+ ang_vel_b_frd: torch.Tensor, # (num_steps, ctrl_freq_inv, 3)
+ is_finished: torch.Tensor, # (num_steps, )
+ is_crashed: torch.Tensor, # (num_steps, )
+ is_timeout: torch.Tensor, # (num_steps, )
+) -> Tuple[Dict, np.ndarray]:
+ # get starting time
+ t_start = time.time()
+
+ # prepare for pcd integration
+ pcd = pcd_from_np_array(pcd_points)
+ cam_intrinsic = o3d.camera.PinholeCameraIntrinsic(
+ width=pcd_proc_params["w"],
+ height=pcd_proc_params["h"],
+ fx=pcd_proc_params["fx"],
+ fy=pcd_proc_params["fy"],
+ cx=pcd_proc_params["cx"],
+ cy=pcd_proc_params["cy"],
+ )
+ q_w_first = quaternion_w[:, 0].roll(1, 1)
+ pcd_update_itv = pcd_proc_params["pcd_update_itv"]
+
+ # calculate dt between two steps
+ step_dt = sim_dt * num_substeps
+
+ # iterate through steps and put each step into the right episode
+ num_steps = len(env_step)
+ for i in range(num_steps):
+ # identify episode
+ step_ep_id = int(episode_id[i])
+ ep_name = f"ep_{step_ep_id}"
+ if not ep_name in ep_dict:
+ ep_dict[ep_name] = empty_log_items_dict()
+
+ # get timestamp from episode progress
+ step_ep_prog = float(episode_progress[i])
+ step_t = step_ep_prog * step_dt
+
+ # feed data into the lists
+ ep_dict[ep_name]["t"].append(step_t)
+ ep_dict[ep_name]["main_depth"].append(main_depth[i])
+ ep_dict[ep_name]["main_color"].append(main_color[i])
+ ep_dict[ep_name]["min_dist_to_obstacle"].append(min_dist_to_obstacle[i])
+ ep_dict[ep_name]["main_cam_pose"].append(main_cam_pose[i])
+ ep_dict[ep_name]["action"].append(action[i])
+ ep_dict[ep_name]["next_waypoint_p"].append(next_waypoint_p[i])
+ ep_dict[ep_name]["ang_vel_des_b_frd"].append(ang_vel_des_b_frd[i])
+ ep_dict[ep_name]["rotor_cmd"].append(rotor_cmd[i])
+ ep_dict[ep_name]["position_w"].append(position_w[i])
+ ep_dict[ep_name]["quaternion_w"].append(quaternion_w[i])
+ ep_dict[ep_name]["lin_vel_w"].append(lin_vel_w[i])
+ ep_dict[ep_name]["lin_vel_b_frd"].append(lin_vel_b_frd[i])
+ ep_dict[ep_name]["ang_vel_b_frd"].append(ang_vel_b_frd[i])
+ ep_dict[ep_name]["is_finished"].append(is_finished[i])
+ ep_dict[ep_name]["is_crashed"].append(is_crashed[i])
+ ep_dict[ep_name]["is_timeout"].append(is_timeout[i])
+
+ # process extra depth into pcd
+ if i % pcd_update_itv == 0:
+ # extra depth images front the batch
+ depth_front = extra_depth[i, 0].numpy()
+ depth_back = extra_depth[i, 1].numpy()
+ depth_left = extra_depth[i, 2].numpy()
+ depth_right = extra_depth[i, 3].numpy()
+ depth_up = extra_depth[i, 4].numpy()
+ depth_down = extra_depth[i, 5].numpy()
+
+ # transform matrices of cameras
+ q_front = q_w_first[i].numpy()
+
+ mat_front: np.ndarray = np.eye(4)
+ mat_front[:3, :3] = o3d.geometry.get_rotation_matrix_from_quaternion(
+ q_front
+ )
+ mat_front[:3, 3] = position_w[i, 0].numpy()
+
+ mat_back = mat_front.copy()
+ mat_back[:3, :2] *= -1
+
+ mat_left = mat_front.copy()
+ mat_left[:3, 0] = mat_front[:3, 1]
+ mat_left[:3, 1] = -mat_front[:3, 0]
+
+ mat_right = mat_left.copy()
+ mat_right[:3, :2] *= -1
+
+ mat_up = mat_front.copy()
+ mat_up[:3, 0] = mat_front[:3, 2]
+ mat_up[:3, 2] = -mat_front[:3, 0]
+
+ mat_down = mat_up.copy()
+ mat_down[:3, [0, 2]] *= -1
+
+ # create pcds
+ pcd_front = pinhole_depth_to_pcd(
+ depth_front, cam_intrinsic, convert_o3d(mat_front)
+ )
+ pcd_back = pinhole_depth_to_pcd(
+ depth_back, cam_intrinsic, convert_o3d(mat_back)
+ )
+ pcd_left = pinhole_depth_to_pcd(
+ depth_left, cam_intrinsic, convert_o3d(mat_left)
+ )
+ pcd_right = pinhole_depth_to_pcd(
+ depth_right, cam_intrinsic, convert_o3d(mat_right)
+ )
+ pcd_up = pinhole_depth_to_pcd(depth_up, cam_intrinsic, convert_o3d(mat_up))
+ pcd_down = pinhole_depth_to_pcd(
+ depth_down, cam_intrinsic, convert_o3d(mat_down)
+ )
+ pcd += pcd_front + pcd_back + pcd_left + pcd_right + pcd_up + pcd_down
+
+ # down-sample the pcd before returning
+ pcd = pcd.voxel_down_sample(pcd_proc_params["voxel_size"])
+
+ # get ending time and print info
+ t_end = time.time()
+ print(f"[process log] env {global_env_id}, process time {t_end - t_start} s, {pcd}")
+
+ return ep_dict, np.asarray(pcd.points)
+
+
+def save_data(
+ global_env_id: int,
+ exp_dir: str,
+ ep_dict: Dict,
+ pcd_points: np.ndarray,
+):
+ t_start = time.time()
+
+ torch.save(ep_dict, os.path.join(exp_dir, f"log_{global_env_id}.pt"))
+ o3d.io.write_point_cloud(
+ os.path.join(exp_dir, f"pcd_{global_env_id}.ply"), pcd_from_np_array(pcd_points)
+ )
+
+ t_end = time.time()
+ print(f"[save data] env {global_env_id}, process time {t_end - t_start} s")
+
+
+def main():
+ # info
+ print("+++ Processing log files")
+ warnings.filterwarnings("ignore", category=FutureWarning)
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument("--exp_dir", type=str, required=True)
+ arg_parser.add_argument("--num_processes", type=int, default=16)
+ arg_parser.add_argument("--voxel_size", type=float, default=0.05)
+ arg_parser.add_argument("--pcd_update_itv", type=int, default=25)
+
+ args = arg_parser.parse_args()
+ exp_dir: str = args.exp_dir
+ num_processes: int = args.num_processes
+ voxel_size: float = args.voxel_size
+ pcd_update_itv: int = args.pcd_update_itv
+
+ # get all log dirs
+ log_dirs: List[str] = [
+ os.path.join(exp_dir, d)
+ for d in os.listdir(exp_dir)
+ if os.path.isdir(os.path.join(exp_dir, d))
+ ]
+ log_dirs.sort()
+ print("log dirs include:")
+ print(log_dirs)
+ print(
+ "make sure there are no other dirs in the experiment dir, "
+ "otherwise this script will not run"
+ )
+
+ # get total number of envs (separated in different log dirs)
+ num_total_envs = 0
+ for log_dir in log_dirs:
+ cfg: Dict[str, Any] = torch.load(os.path.join(log_dir, "cfg.pt"))
+ num_total_envs += cfg["env"]["numEnvs"]
+
+ # dictionary of data for all envs
+ # env_episode_data["env_0"] is for env[0], and is a dict containing keys "ep_0", "ep_1", ...
+ # env_episode_data["env_0"]["ep_0"] is a dictionary of specific data items like position
+ # each data item is eventually a list representing data on the timeline
+ # env_pcd_points[i] is a numpy array storing points for env[i]
+ env_episode_data: Dict[str, Dict[str, Dict[str, List[Any]]]] = {
+ f"env_{i}": {} for i in range(num_total_envs)
+ }
+ env_pcd_points: Dict[str, np.ndarray] = {
+ f"env_{i}": np.empty((0, 3)) for i in range(num_total_envs)
+ }
+
+ # iterate through log dirs to update env data dict and env pcd points
+ env_id_offset: int = 0
+ for log_dir in log_dirs:
+ cfg: Dict[str, Any] = torch.load(os.path.join(log_dir, "cfg.pt"))
+ num_envs_log: int = cfg["env"]["numEnvs"]
+ num_log_files: int = cfg["env"]["logging"]["numLogFiles"]
+ ctrl_freq_inv: int = cfg["env"]["controlFrequencyInv"]
+ sim_dt: float = cfg["sim"]["dt"]
+ cam_w: int = cfg["env"]["logging"]["extraCameraWidth"]
+ cam_h: int = cfg["env"]["logging"]["extraCameraHeight"]
+ cam_hfov: float = cfg["env"]["logging"]["extraCameraHfov"]
+
+ # pcd process params
+ cam_fx = cam_w / (2 * np.tan(np.deg2rad(cam_hfov) / 2))
+ cam_fy = cam_fx * cam_h / cam_w
+ cam_cx = cam_w / 2
+ cam_cy = cam_h / 2
+ pcd_proc_params: Dict[str, Any] = {
+ "w": cam_w,
+ "h": cam_h,
+ "fx": cam_fx,
+ "fy": cam_fy,
+ "cx": cam_cx,
+ "cy": cam_cy,
+ "voxel_size": voxel_size,
+ "pcd_update_itv": pcd_update_itv,
+ }
+
+ # process all log files
+ for i in range(num_log_files):
+ log_file = os.path.join(log_dir, str(i) + ".pt")
+ print(f"loading {log_file}")
+ file_dict: Dict[str, Any] = torch.load(log_file)
+ print("done loading")
+
+ # extract info, stack tensors so we can select slices for each env
+ print("extracting info from dict")
+ env_step: List[int] = file_dict["env_step"]
+ episode_id = torch.stack(file_dict["episode_id"])
+ episode_progress = torch.stack(file_dict["episode_progress"])
+ main_depth = torch.stack(file_dict["main_depth"])
+ main_color = torch.stack(file_dict["main_color"])
+ extra_depth = torch.stack(file_dict["extra_depth"])
+ min_dist_to_obstacle = torch.stack(file_dict["min_dist_to_obstacle"])
+ main_cam_pose = torch.stack(file_dict["main_cam_pose"])
+ action = torch.stack(file_dict["action"])
+ next_waypoint_p = torch.stack(file_dict["next_waypoint_p"])
+ ang_vel_des_b_frd = torch.stack(file_dict["ang_vel_des_b_frd"])
+ rotor_cmd = torch.stack(file_dict["rotor_cmd"])
+ position_w = torch.stack(file_dict["position_w"])
+ quaternion_w = torch.stack(file_dict["quaternion_w"])
+ lin_vel_w = torch.stack(file_dict["lin_vel_w"])
+ lin_vel_b_frd = torch.stack(file_dict["lin_vel_b_frd"])
+ ang_vel_b_frd = torch.stack(file_dict["ang_vel_b_frd"])
+ is_finished = torch.stack(file_dict["is_finished"])
+ is_crashed = torch.stack(file_dict["is_crashed"])
+ is_timeout = torch.stack(file_dict["is_timeout"])
+ file_dict.clear() # free up some mem
+ gc.collect()
+ print("done extracting info")
+
+ # process log file
+ print(f"processing log file {log_file}")
+ with mp.Pool(min(num_processes, num_envs_log)) as pool:
+ ret: List[Tuple[Dict, np.ndarray]] = pool.starmap(
+ process_log,
+ [
+ (
+ env_id + env_id_offset, # global env id
+ ctrl_freq_inv,
+ sim_dt,
+ pcd_proc_params,
+ env_episode_data[f"env_{env_id + env_id_offset}"],
+ env_pcd_points[f"env_{env_id + env_id_offset}"],
+ env_step,
+ episode_id[:, env_id].clone(),
+ episode_progress[:, env_id].clone(),
+ main_depth[:, env_id].clone(),
+ main_color[:, env_id].clone(),
+ extra_depth[:, env_id].clone(),
+ min_dist_to_obstacle[:, env_id].clone(),
+ main_cam_pose[:, env_id].clone(),
+ action[:, env_id].clone(),
+ next_waypoint_p[:, env_id].clone(),
+ ang_vel_des_b_frd[:, :, env_id].clone(),
+ rotor_cmd[:, :, env_id].clone(),
+ position_w[:, :, env_id].clone(),
+ quaternion_w[:, :, env_id].clone(),
+ lin_vel_w[:, :, env_id].clone(),
+ lin_vel_b_frd[:, :, env_id].clone(),
+ ang_vel_b_frd[:, :, env_id].clone(),
+ is_finished[:, env_id].clone(),
+ is_crashed[:, env_id].clone(),
+ is_timeout[:, env_id].clone(),
+ )
+ for env_id in range(num_envs_log)
+ ],
+ )
+
+ # update env data dict and env pcd using ret
+ for env_id in range(num_envs_log):
+ global_env_id = env_id + env_id_offset
+ (
+ env_episode_data[f"env_{global_env_id}"],
+ env_pcd_points[f"env_{global_env_id}"],
+ ) = ret[env_id]
+
+ # save env data
+ print(f"saving data extracted from {log_dir}")
+ with mp.Pool(min(num_processes, num_envs_log)) as pool:
+ pool.starmap(
+ save_data,
+ [
+ (
+ env_id + env_id_offset,
+ exp_dir,
+ env_episode_data[f"env_{env_id + env_id_offset}"],
+ env_pcd_points[f"env_{env_id + env_id_offset}"],
+ )
+ for env_id in range(num_envs_log)
+ ],
+ )
+
+ # clear already saved data
+ for env_id in range(num_envs_log):
+ global_env_id = env_id + env_id_offset
+ env_episode_data[f"env_{global_env_id}"].clear()
+ env_pcd_points[f"env_{global_env_id}"] = np.empty((0, 3))
+ gc.collect()
+
+ # update global env id offset
+ env_id_offset += num_envs_log
+
+
+if __name__ == "__main__":
+ main()
diff --git a/isaacgymenvs/tasks/drone_racing/demos/quad_fpv.py b/isaacgymenvs/tasks/drone_racing/demos/quad_fpv.py
new file mode 100644
index 000000000..11e2ef365
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/quad_fpv.py
@@ -0,0 +1,442 @@
+import json
+import time
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+import cv2
+import numpy as np
+import pygame
+import zmq
+
+from isaacgym import gymapi, gymtorch
+from isaacgymenvs.tasks.drone_racing.assets import (
+ create_drone_quadcopter,
+ TrackMultiStoryOptions,
+ TrackRmuaOptions,
+ TrackSplitsOptions,
+ TrackWallsOptions,
+ create_track_multistory,
+ create_track_rmua,
+ create_track_splits,
+ create_track_walls,
+)
+from isaacgymenvs.tasks.drone_racing.drone_sim import (
+ SimpleBetaflight,
+ BodyDragPoly,
+ PropellerPoly,
+ RotorPolyLag,
+ WrenchSum,
+ Kingfisher250,
+)
+from isaacgymenvs.tasks.drone_racing.waypoint import WaypointData
+from isaacgymenvs.utils.torch_jit_utils import quat_rotate_inverse
+
+print("Importing torch...")
+import torch # noqa
+
+
+@dataclass
+class QuadFpvParams:
+ """
+ No arg parser for simplicity, just modify me directly.
+ """
+
+ # toggles
+ show_viewer: bool = True
+ enable_joysticks: bool = False
+ enable_zmq: bool = True
+ show_fpv: bool = True
+ fpv_depth: bool = False
+ # when fpv_depth is false, this decides if image is displayed in color or gray
+ fpv_gray: bool = False
+
+ # depth clipping
+ depth_max: float = 50.0
+
+ # sim settings
+ compute_device_id: int = 0
+ graphics_device_id: int = 0
+ physics_engine: gymapi.SimType = gymapi.SIM_PHYSX
+ sim_params: gymapi.SimParams = gymapi.SimParams()
+ sim_params.dt = 1 / 250
+ sim_params.substeps = 2
+ sim_params.up_axis = gymapi.UP_AXIS_Z
+ sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
+ sim_params.physx.use_gpu = True
+ sim_params.use_gpu_pipeline = True
+ fps: int = 50
+
+ # env settings
+ num_envs: int = 100
+ env_spacing: float = 0.5
+ preset: Kingfisher250 = Kingfisher250(num_envs, "cuda")
+
+ # pygame joysticks
+ joystick_channels: List[int] = field(default_factory=lambda: [1, 2, 0, 3])
+ joystick_directions: List[int] = field(default_factory=lambda: [1, 1, 1, 1])
+ joystick_deadzones: List[float] = field(
+ default_factory=lambda: [0.01, 0.01, 0.0, 0.01]
+ )
+
+ # zmq for plot juggler
+ zmq_port: int = 9872
+
+
+class QuadFpv:
+
+ def __init__(self, params: QuadFpvParams):
+ """
+ Init Isaac Gym FPV. This script can also be used for flight tuning with PlotJuggler.
+
+ Args:
+ params: all necessary params.
+ """
+
+ # store params
+ self.params = params
+
+ # create sim and ground plane
+ self.gym = gymapi.acquire_gym()
+
+ self.sim = self.gym.create_sim(
+ params.compute_device_id,
+ params.graphics_device_id,
+ params.physics_engine,
+ params.sim_params,
+ )
+
+ if params.show_viewer:
+ self.viewer = self.gym.create_viewer(self.sim, gymapi.CameraProperties())
+ self.gym.subscribe_viewer_keyboard_event(self.viewer, gymapi.KEY_R, "reset")
+ print("Key R: reset")
+ else:
+ self.viewer = None
+
+ plane_params = gymapi.PlaneParams()
+ plane_params.normal = gymapi.Vec3(0, 0, 1)
+ self.gym.add_ground(self.sim, plane_params)
+
+ # sim scheduling
+ self.num_physics_per_render = int(
+ 1 / self.params.fps / self.params.sim_params.dt
+ )
+ pygame.init()
+ self.pygame_clk = pygame.time.Clock()
+ self.frame_time = 1000 / self.params.fps
+
+ # initialize envs, actors, sensors, buffers
+ self.quad_asset = create_drone_quadcopter(
+ self.gym, self.sim, self.params.preset.quad_asset_options
+ )
+ self._init_envs()
+ self.gym.prepare_sim(self.sim)
+
+ # init uav simulation
+ self.simple_betaflight = SimpleBetaflight(params.preset.simple_bf_params)
+ self.rotor_poly_lag = RotorPolyLag(params.preset.rotor_params)
+ self.propeller_poly = PropellerPoly(params.preset.propeller_params)
+ self.body_drag_poly = BodyDragPoly(params.preset.body_drag_params)
+ self.wrench_sum = WrenchSum(params.preset.wrench_sum_params)
+ self.actor_states = gymtorch.wrap_tensor(
+ self.gym.acquire_actor_root_state_tensor(self.sim)
+ )
+ self.gym.refresh_actor_root_state_tensor(self.sim)
+ self.init_actor_states = self.actor_states.clone()
+ self.flu_frd = torch.tensor([[1.0, -1.0, -1.0]], device="cuda")
+ self.command = torch.zeros(self.params.num_envs, 4, device="cuda")
+ self.command[:, 2] = -1
+
+ # init pygame for joystick and fps control
+ if self.params.enable_joysticks:
+ pygame.joystick.init()
+ self.joystick = pygame.joystick.Joystick(0)
+ self.joystick.init()
+
+ # zmq for plot juggler
+ if self.params.enable_zmq:
+ self.zmq_context = zmq.Context()
+ self.zmq_socket = self.zmq_context.socket(zmq.PUB)
+ self.zmq_socket.bind("tcp://*:" + str(self.params.zmq_port))
+ self.zmq_data = torch.zeros(
+ self.num_physics_per_render, 2, 3, device="cuda"
+ )
+
+ def run(self):
+ """
+ This function runs the sim loop.
+ """
+
+ total_force = torch.zeros(
+ self.num_scene_actors + self.params.num_envs, 3, device="cuda"
+ )
+ total_torque = torch.zeros(
+ self.num_scene_actors + self.params.num_envs, 3, device="cuda"
+ )
+
+ while self.viewer is None or not self.gym.query_viewer_has_closed(self.viewer):
+ # check reset
+ if self.viewer is not None:
+ for evt in self.gym.query_viewer_action_events(self.viewer):
+ if evt.action == "reset" and evt.value > 0:
+ self.simple_betaflight.reset()
+ self.rotor_poly_lag.reset()
+ self.gym.set_actor_root_state_tensor(
+ self.sim, gymtorch.unwrap_tensor(self.init_actor_states)
+ )
+
+ # commands are updated at rendering rate
+ if self.params.enable_joysticks:
+ self._update_command_joysticks()
+
+ self.simple_betaflight.set_command(self.command)
+
+ # physics steps
+ t_physics_start = time.time()
+
+ for i in range(self.num_physics_per_render):
+ # get body frame linear and angular velocities in FRD
+ lin_vel, ang_vel = self._get_body_vel_frd()
+
+ # get ctrl wrench
+ des_ang_vel, normalized_cmd = self.simple_betaflight.compute(ang_vel)
+ if self.params.enable_zmq:
+ self.zmq_data[i, 0, :] = des_ang_vel[0]
+ self.zmq_data[i, 1, :] = ang_vel[0]
+
+ rpm, rotor_force, rotor_torque = self.rotor_poly_lag.compute(
+ normalized_cmd
+ )
+ prop_force, prop_torque = self.propeller_poly.compute(rpm)
+ ctrl_force, ctrl_torque = self.wrench_sum.compute(
+ rotor_force + prop_force, rotor_torque + prop_torque
+ )
+
+ # get drag wrench
+ drag_force, drag_torque = self.body_drag_poly.compute(lin_vel, ang_vel)
+
+ # apply total wrench
+ total_force[self.quad_actor_id] = (
+ ctrl_force + drag_force
+ ) * self.flu_frd
+ total_torque[self.quad_actor_id] = (
+ ctrl_torque + drag_torque
+ ) * self.flu_frd
+ self.gym.apply_rigid_body_force_tensors(
+ self.sim,
+ gymtorch.unwrap_tensor(total_force),
+ gymtorch.unwrap_tensor(total_torque),
+ gymapi.LOCAL_SPACE,
+ )
+
+ # step physics
+ self.gym.simulate(self.sim)
+ self.gym.fetch_results(self.sim, True)
+ self.gym.refresh_actor_root_state_tensor(self.sim)
+
+ t_physics_end = time.time()
+ t_physics_dur = t_physics_end - t_physics_start
+
+ # step graphics and render cam sensors
+ self.gym.step_graphics(self.sim)
+ self.gym.render_all_camera_sensors(self.sim)
+
+ # access image tensors
+ self.gym.start_access_image_tensors(self.sim)
+ img = self.fpv_cam_tensor.cpu().numpy()
+ self.gym.end_access_image_tensors(self.sim)
+
+ # send out debug data
+ if self.params.enable_zmq:
+ self._zmq_publish()
+
+ # update viewer frame
+ if self.viewer is not None:
+ self.gym.draw_viewer(self.viewer, self.sim, True)
+
+ # update fpv
+ if self.params.show_fpv:
+ self._update_fpv(img, t_physics_dur)
+
+ # limit fps
+ self.frame_time = self.pygame_clk.tick(self.params.fps)
+
+ if self.params.enable_zmq:
+ self.zmq_socket.close()
+ self.zmq_context.term()
+
+ def _init_envs(self):
+ lb = gymapi.Vec3(-self.params.env_spacing, -self.params.env_spacing, 0)
+ ub = gymapi.Vec3(
+ self.params.env_spacing, self.params.env_spacing, self.params.env_spacing
+ )
+
+ self.envs = []
+ self.quad_actors = []
+ self.num_scene_actors = 0
+ wp_lists = []
+ asset_tfs = []
+
+ for i in range(self.params.num_envs):
+ # create env
+ env = self.gym.create_env(self.sim, lb, ub, int(self.params.num_envs**0.5))
+ self.envs.append(env)
+
+ # create scene actors for fpv env
+ if i == 0:
+ ms_tf = gymapi.Transform()
+ ms_tf.p = gymapi.Vec3(40, 0, 0)
+ asset_tfs.append(ms_tf)
+ multistory_asset, multistory_wp = create_track_multistory(
+ self.gym, self.sim, TrackMultiStoryOptions()
+ )
+ self.gym.create_actor(env, multistory_asset, ms_tf, "multistory", i, 1)
+ self.num_scene_actors += 1
+ wp_lists.append(multistory_wp)
+
+ rmua_tf = gymapi.Transform()
+ rmua_tf.p = gymapi.Vec3(-40, 0, 0)
+ asset_tfs.append(rmua_tf)
+ rmua_asset, rmua_wp = create_track_rmua(
+ self.gym, self.sim, TrackRmuaOptions()
+ )
+ self.gym.create_actor(env, rmua_asset, rmua_tf, "rmua", i, 1)
+ self.num_scene_actors += 1
+ wp_lists.append(rmua_wp)
+
+ splits_tf = gymapi.Transform()
+ splits_tf.p = gymapi.Vec3(0, 40, 0)
+ asset_tfs.append(splits_tf)
+ splits_asset, splits_wp = create_track_splits(
+ self.gym, self.sim, TrackSplitsOptions()
+ )
+ self.gym.create_actor(env, splits_asset, splits_tf, "splits", i, 1)
+ self.num_scene_actors += 1
+ wp_lists.append(splits_wp)
+
+ walls_tf = gymapi.Transform()
+ walls_tf.p = gymapi.Vec3(0, -40, 0)
+ asset_tfs.append(walls_tf)
+ walls_asset, walls_wp = create_track_walls(
+ self.gym, self.sim, TrackWallsOptions()
+ )
+ self.gym.create_actor(env, walls_asset, walls_tf, "walls", i, 1)
+ self.num_scene_actors += 1
+ wp_lists.append(walls_wp)
+
+ if self.viewer is not None:
+ for j in range(len(wp_lists)):
+ wp_data = WaypointData.from_waypoint_list(1, wp_lists[j])
+ wp_data.position += torch.tensor(
+ [asset_tfs[j].p.x, asset_tfs[j].p.y, asset_tfs[j].p.z]
+ )
+ wp_data.visualize(self.gym, [self.envs[i]], self.viewer, 1)
+
+ # create actor
+ quad_init_pose = gymapi.Transform()
+ quad_init_pose.p = gymapi.Vec3(0.0, 0.0, 0.2)
+ quad_actor = self.gym.create_actor(
+ env, self.quad_asset, quad_init_pose, "Quadcopter", i, 0
+ )
+ self.quad_actors.append(quad_actor)
+
+ # create camera sensor for fpv env
+ if i == 0:
+ # different settings if viewing depth
+ image_type = gymapi.IMAGE_COLOR
+ if self.params.fpv_depth:
+ self.params.preset.camera_props.use_collision_geometry = True
+ image_type = gymapi.IMAGE_DEPTH
+
+ # create camera sensor and attach to body
+ self.quad_fpv_cam = self.gym.create_camera_sensor(
+ env, self.params.preset.camera_props
+ )
+ self.gym.attach_camera_to_body(
+ self.quad_fpv_cam,
+ env,
+ quad_actor,
+ self.params.preset.camera_pose,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+
+ # init buffer
+ cam_gym_tensor = self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, self.quad_fpv_cam, image_type
+ )
+ self.fpv_cam_tensor = gymtorch.wrap_tensor(cam_gym_tensor)
+
+ self.quad_actor_id = torch.arange(
+ self.num_scene_actors,
+ self.num_scene_actors + self.params.num_envs,
+ device="cuda",
+ )
+
+ def _update_command_joysticks(self):
+ pygame.event.get()
+ for i in range(4):
+ joystick_input = self.joystick.get_axis(self.params.joystick_channels[i])
+ self.command[:, i] = (
+ joystick_input
+ * self.params.joystick_directions[i]
+ * (abs(joystick_input) > self.params.joystick_deadzones[i])
+ )
+
+ def _get_body_vel_frd(self) -> Tuple[torch.Tensor, torch.Tensor]:
+ attitude = self.actor_states[self.quad_actor_id, 3:7]
+ lin_vel_w = self.actor_states[self.quad_actor_id, 7:10]
+ ang_vel_w = self.actor_states[self.quad_actor_id, 10:13]
+ lin_vel_b = quat_rotate_inverse(attitude, lin_vel_w) * self.flu_frd
+ ang_vel_b = quat_rotate_inverse(attitude, ang_vel_w) * self.flu_frd
+ return lin_vel_b, ang_vel_b
+
+ def _update_fpv(self, img: np.ndarray, t_physics: float):
+ if self.params.fpv_depth:
+ # note that debug lines will also appear
+ # with depth clipped, it is harder to maintain attitude awareness
+ # img[img < -self.params.depth_max] = -self.params.depth_max
+ # img = -img / self.params.depth_max
+ img = img / self.params.depth_max + 1
+ np.clip(img, 0, 1)
+ else:
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
+ calculated_fps = int(1000 / self.frame_time)
+ cv2.putText(
+ img,
+ str(calculated_fps) + ", " + str(int(t_physics * 1000)),
+ (8, 32),
+ 0,
+ 1,
+ (0, 255, 0),
+ 2,
+ )
+ cx = int(self.params.preset.camera_props.width / 2)
+ cy = int(self.params.preset.camera_props.height / 2)
+ cv2.circle(img, (cx, cy), 4, (0, 255, 0), -1)
+ if self.params.fpv_gray:
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
+ cv2.imshow("fpv", img)
+ cv2.waitKey(1)
+
+ def _zmq_publish(self):
+ data_np = self.zmq_data.cpu().numpy()
+ for i in range(data_np.shape[0]):
+ msg = {
+ "t": time.time() - self.params.sim_params.dt * (data_np.shape[0] - i),
+ "des_ang_vel": {
+ "x": float(data_np[i, 0, 0]),
+ "y": float(data_np[i, 0, 1]),
+ "z": float(data_np[i, 0, 2]),
+ },
+ "ang_vel": {
+ "x": float(data_np[i, 1, 0]),
+ "y": float(data_np[i, 1, 1]),
+ "z": float(data_np[i, 1, 2]),
+ },
+ }
+ self.zmq_socket.send_string(json.dumps(msg))
+
+
+if __name__ == "__main__":
+ fpv_params = QuadFpvParams()
+ fpv = QuadFpv(fpv_params)
+ fpv.run()
diff --git a/isaacgymenvs/tasks/drone_racing/demos/racing_tracks.py b/isaacgymenvs/tasks/drone_racing/demos/racing_tracks.py
new file mode 100644
index 000000000..bb368082f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/racing_tracks.py
@@ -0,0 +1,248 @@
+from typing import List, Tuple
+
+from isaacgym import gymapi
+from isaacgym.gymapi import Asset
+from isaacgymenvs.tasks.drone_racing.assets import (
+ TrackMultiStoryOptions,
+ TrackRmuaOptions,
+ TrackSplitsOptions,
+ TrackWallsOptions,
+ TrackGeomKebabOptions,
+ TrackPlanarCircleOptions,
+ TrackWavyEightOptions,
+ TrackTurnsOptions,
+ TrackSimpleStickOptions,
+ TrackSjtu3dcOptions,
+ TrackSjtuEllOptions,
+ TrackSjtuStrOptions,
+ create_track_multistory,
+ create_track_rmua,
+ create_track_splits,
+ create_track_walls,
+ create_track_geom_kebab,
+ create_track_planar_circle,
+ create_track_wavy_eight,
+ create_track_turns,
+ create_track_simple_stick,
+ create_track_sjtu_3dc,
+ create_track_sjtu_ell,
+ create_track_sjtu_str,
+)
+from isaacgymenvs.tasks.drone_racing.waypoint import (
+ Waypoint,
+ WaypointData,
+)
+
+print("Importing torch...")
+import torch # noqa
+
+
+def define_track_assets() -> Tuple[List[Asset], List[str], List[List[Waypoint]]]:
+ track_assets = []
+ track_names = []
+ track_wp_lists = []
+
+ # multistory without debug view
+ multistory_options = TrackMultiStoryOptions()
+ multistory_asset, multistory_wp = create_track_multistory(
+ gym, sim, multistory_options
+ )
+ track_assets.append(multistory_asset)
+ track_names.append("multistory")
+ track_wp_lists.append(multistory_wp)
+
+ # multistory with debug view
+ multistory_options.track_options.enable_debug_visualization = True
+ multistory_asset, multistory_wp = create_track_multistory(
+ gym, sim, multistory_options
+ )
+ track_assets.append(multistory_asset)
+ track_names.append("multistory_debug")
+ track_wp_lists.append(multistory_wp)
+
+ # rmua simple with debug view
+ rmua_options = TrackRmuaOptions()
+ rmua_options.enable_waypoint_randomization = False
+ rmua_options.enable_additional_obstacles = False
+ rmua_options.track_options.enable_debug_visualization = True
+ rmua_asset, rmua_wp = create_track_rmua(gym, sim, rmua_options)
+ track_assets.append(rmua_asset)
+ track_names.append("rmua_simple")
+ track_wp_lists.append(rmua_wp)
+
+ # rmua random waypoint with debug view
+ rmua_options.enable_waypoint_randomization = True
+ rmua_options.enable_additional_obstacles = False
+ rmua_options.track_options.enable_debug_visualization = True
+ rmua_asset, rmua_wp = create_track_rmua(gym, sim, rmua_options)
+ track_assets.append(rmua_asset)
+ track_names.append("rmua_waypoint")
+ track_wp_lists.append(rmua_wp)
+
+ # rmua add more obstacles
+ rmua_options.enable_waypoint_randomization = True
+ rmua_options.enable_additional_obstacles = True
+ rmua_options.track_options.enable_debug_visualization = True
+ rmua_asset, rmua_wp = create_track_rmua(gym, sim, rmua_options)
+ track_assets.append(rmua_asset)
+ track_names.append("rmua_obstacles_1")
+ track_wp_lists.append(rmua_wp)
+
+ # rmua add more obstacles
+ rmua_options.enable_waypoint_randomization = True
+ rmua_options.enable_additional_obstacles = True
+ rmua_options.track_options.enable_debug_visualization = False
+ rmua_asset, rmua_wp = create_track_rmua(gym, sim, rmua_options)
+ track_assets.append(rmua_asset)
+ track_names.append("rmua_obstacles_2")
+ track_wp_lists.append(rmua_wp)
+
+ # split-s
+ splits_options = TrackSplitsOptions()
+ splits_asset, splits_wp = create_track_splits(gym, sim, splits_options)
+ track_assets.append(splits_asset)
+ track_names.append("splits_debug")
+ track_wp_lists.append(splits_wp)
+
+ # walls
+ walls_options = TrackWallsOptions()
+ walls_asset, walls_wp = create_track_walls(gym, sim, walls_options)
+ track_assets.append(walls_asset)
+ track_names.append("walls_debug")
+ track_wp_lists.append(walls_wp)
+
+ # obstacle kebab
+ geom_kebab_options = TrackGeomKebabOptions()
+ geom_kebab_asset, geom_kebab_wp = create_track_geom_kebab(
+ gym, sim, geom_kebab_options
+ )
+ track_assets.append(geom_kebab_asset)
+ track_names.append("geom_kebab")
+ track_wp_lists.append(geom_kebab_wp)
+
+ # planar circle
+ planar_circle_options = TrackPlanarCircleOptions()
+ planar_circle_asset, planar_circle_wp = create_track_planar_circle(
+ gym, sim, planar_circle_options
+ )
+ track_assets.append(planar_circle_asset)
+ track_names.append("planar_circle")
+ track_wp_lists.append(planar_circle_wp)
+
+ # wavy eight
+ wavy_eight_options = TrackWavyEightOptions()
+ wavy_eight_asset, wavy_eight_wp = create_track_wavy_eight(
+ gym, sim, wavy_eight_options
+ )
+ track_assets.append(wavy_eight_asset)
+ track_names.append("wavy_eight")
+ track_wp_lists.append(wavy_eight_wp)
+
+ # turns
+ turns_options = TrackTurnsOptions()
+ turns_asset, turns_wp = create_track_turns(gym, sim, turns_options)
+ track_assets.append(turns_asset)
+ track_names.append("turns")
+ track_wp_lists.append(turns_wp)
+
+ # simple stick
+ simple_stick_options = TrackSimpleStickOptions()
+ simple_stick_asset, simple_stick_wp = create_track_simple_stick(
+ gym, sim, simple_stick_options
+ )
+ track_assets.append(simple_stick_asset)
+ track_names.append("simple_stick")
+ track_wp_lists.append(simple_stick_wp)
+
+ # sjtu straight
+ sjtu_str_options = TrackSjtuStrOptions()
+ sjtu_str_asset, sjtu_str_wp = create_track_sjtu_str(gym, sim, sjtu_str_options)
+ track_assets.append(sjtu_str_asset)
+ track_names.append("sjtu_straight")
+ track_wp_lists.append(sjtu_str_wp)
+
+ # sjtu 3d circle (4 types)
+ for i in range(4):
+ sjtu_3dc_asset, sjtu_3dc_wp = create_track_sjtu_3dc(
+ gym, sim, TrackSjtu3dcOptions(type_id=i)
+ )
+ track_assets.append(sjtu_3dc_asset)
+ track_names.append("sjtu_3dcircle_" + str(i))
+ track_wp_lists.append(sjtu_3dc_wp)
+
+ # sjtu ellipse (4 types)
+ for i in range(4):
+ sjtu_ell_asset, sjtu_ell_wp = create_track_sjtu_ell(
+ gym, sim, TrackSjtuEllOptions(type_id=i)
+ )
+ track_assets.append(sjtu_ell_asset)
+ track_names.append("sjtu_ellipse_" + str(i))
+ track_wp_lists.append(sjtu_ell_wp)
+
+ # TODO: more tracks can be added here
+
+ return track_assets, track_names, track_wp_lists
+
+
+if __name__ == "__main__":
+ # create sim and gym
+ gym = gymapi.acquire_gym()
+
+ sim_params = gymapi.SimParams()
+ sim_params.use_gpu_pipeline = True
+ sim_params.physx.use_gpu = True
+ sim_params.up_axis = gymapi.UP_AXIS_Z
+ sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
+ sim = gym.create_sim(0, 0, gymapi.SIM_PHYSX, sim_params)
+
+ plane_params = gymapi.PlaneParams()
+ plane_params.normal = gymapi.Vec3(0, 0, 1)
+ gym.add_ground(sim, plane_params)
+
+ # spawn track assets into envs
+ envs = []
+ assets, names, wp_lists = define_track_assets()
+ assert len(assets) == len(names)
+ for i in range(len(assets)):
+ env = gym.create_env(
+ sim,
+ gymapi.Vec3(-20, -20, 0),
+ gymapi.Vec3(20, 20, 40),
+ 4,
+ )
+ gym.create_actor(env, assets[i], gymapi.Transform(), names[i], i, 1)
+ envs.append(env)
+
+ # viewer and gpu pipeline
+ viewer = gym.create_viewer(sim, gymapi.CameraProperties())
+ gym.viewer_camera_look_at(
+ viewer,
+ None,
+ gymapi.Vec3(-20, -20, 30),
+ gymapi.Vec3(20, 20, 10),
+ )
+ gym.prepare_sim(sim)
+
+ # draw waypoint data on those w/o debug views
+ torch.set_printoptions(linewidth=130, sci_mode=False, precision=2)
+ for env_id in (
+ [0, 5, 6, 7, 8, 9, 10, 11, 12, 13] + [14, 15, 16, 17] + [18, 19, 20, 21]
+ ):
+ wp_data = WaypointData.from_waypoint_list(1, wp_lists[env_id])
+ wp_data.visualize(gym, [envs[env_id]], viewer, 1)
+ print("---")
+ print("env :", env_id)
+ print("r :", wp_data.r)
+ print("psi :", torch.rad2deg(wp_data.psi))
+ print("theta:", torch.rad2deg(wp_data.theta))
+ print("gamma:", torch.rad2deg(wp_data.gamma))
+
+ # update simulation
+ while not gym.query_viewer_has_closed(viewer):
+ gym.simulate(sim)
+ gym.fetch_results(sim, True)
+ gym.step_graphics(sim)
+ gym.draw_viewer(viewer, sim, True)
+ gym.sync_frame_time(sim)
+
+ gym.destroy_sim(sim)
diff --git a/isaacgymenvs/tasks/drone_racing/demos/rerun_exp.py b/isaacgymenvs/tasks/drone_racing/demos/rerun_exp.py
new file mode 100644
index 000000000..28112aed7
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/rerun_exp.py
@@ -0,0 +1,668 @@
+import argparse
+import multiprocessing as mp
+import os
+import time
+import warnings
+from datetime import datetime
+from typing import Dict, Any, List
+
+import matplotlib
+import numpy as np
+import open3d as o3d
+import rerun as rr
+import rerun.blueprint as rrb
+import torch
+from rerun_loader_urdf import URDFLogger
+
+
+# TODO: blueprint
+def rrb_single_env() -> rrb.Blueprint:
+ blueprint = rrb.Blueprint(rrb.Spatial3DView())
+ return blueprint
+
+
+# TODO: blueprint
+def rrb_combined_env() -> rrb.Blueprint:
+ blueprint = rrb.Blueprint(rrb.Spatial3DView())
+ return blueprint
+
+
+def log_world_frame_and_pcd(pcd: o3d.geometry.PointCloud, pcd_colormap: str):
+ # log world frame
+ rr.log(
+ f"world_frame",
+ rr.Transform3D(axis_length=1.0),
+ static=True,
+ )
+
+ # load and log pcd
+ pcd_points = np.asarray(pcd.points)
+ pcd_points_z = pcd_points[:, -1]
+ pcd_points_min_z = pcd_points_z.min()
+ pcd_points_max_z = pcd_points_z.max()
+ pcd_z_norm = matplotlib.colors.Normalize(
+ vmin=pcd_points_min_z, vmax=pcd_points_max_z
+ )
+
+ pcd_cmap = matplotlib.colormaps[pcd_colormap]
+ rr.log(
+ f"pcd",
+ rr.Points3D(pcd_points, colors=pcd_cmap(pcd_z_norm(pcd_points_z))),
+ static=True,
+ )
+
+
+def log_waypoint_data(
+ wp_p: torch.Tensor,
+ wp_q: torch.Tensor,
+ wp_w: torch.Tensor,
+ wp_h: torch.Tensor,
+):
+ num_waypoints = wp_p.shape[0]
+ for i in range(num_waypoints):
+ rr.log(
+ f"waypoint/{i}",
+ rr.Boxes3D(
+ half_sizes=[0.05, wp_w[i] / 2, wp_h[i] / 2],
+ labels=f"{i}",
+ colors=[0, 255, 0],
+ ),
+ static=True,
+ )
+ rr.log(
+ f"waypoint/{i}",
+ rr.Transform3D(
+ translation=wp_p[i],
+ rotation=rr.Quaternion(xyzw=wp_q[i]),
+ axis_length=1.0,
+ ),
+ static=True,
+ )
+ if i < num_waypoints - 1:
+ rr.log(
+ f"waypoint/line_segment/{i}_{i + 1}",
+ rr.LineStrips3D(wp_p[i : i + 2].numpy(), colors=[0, 255, 0]),
+ static=True,
+ )
+
+
+def log_episode_data(
+ ep_dict: Dict[str, Any],
+ cam_params: Dict[str, Any],
+ vel_colormap: str,
+ vel_max_cmap: float,
+ traj_line_weight: float,
+ drone_urdf: str,
+ num_episodes: int,
+ log_cam: bool,
+ ep_prefix: str,
+ only_traj: bool = False,
+):
+ num_substeps = ep_dict["ep_0"]["position_w"][0].shape[0]
+ step_dt = ep_dict["ep_0"]["t"][1]
+ sim_dt = step_dt / num_substeps
+ vel_cmap = matplotlib.colormaps[vel_colormap]
+
+ # load urdf
+ urdf_logger = None
+ if drone_urdf is not None:
+ urdf_logger = URDFLogger(drone_urdf, None)
+
+ for i in range(num_episodes):
+ num_steps = len(ep_dict[f"ep_{i}"]["t"])
+
+ # log trajectory
+ pos_tensor = torch.stack(ep_dict[f"ep_{i}"]["position_w"]).flatten(0, 1)
+ line_start = pos_tensor[:-1] # (N-1, 3)
+ line_end = pos_tensor[1:] # (N-1, 3)
+ line_data = torch.stack((line_start, line_end), dim=1).numpy() # (N-1, 2, 3)
+ ep_vel_norm = (
+ torch.stack(ep_dict[f"ep_{i}"]["lin_vel_w"]).flatten(0, 1).norm(dim=1)
+ )
+ vel_line_avg = ((ep_vel_norm[:-1] + ep_vel_norm[1:]) / 2).numpy()
+ rr.log(
+ f"episode_{ep_prefix}{i}/trajectory",
+ rr.LineStrips3D(
+ line_data,
+ colors=vel_cmap(vel_line_avg / vel_max_cmap),
+ radii=rr.Radius.ui_points(traj_line_weight),
+ ),
+ static=True,
+ )
+
+ if not only_traj:
+ # log urdf
+ if urdf_logger is not None:
+ urdf_logger.entity_path_prefix = f"episode_{ep_prefix}{i}/urdf"
+ urdf_logger.log()
+
+ # log time series line indicator
+ for field in ["ang_vel_des_b_frd", "ang_vel_b_frd", "lin_vel_b_frd"]:
+ for dim in ["x", "y", "z"]:
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/{field}/{dim}",
+ rr.SeriesLine(name=f"{field}_{dim}"),
+ static=True,
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/speed",
+ rr.SeriesLine(name="speed"),
+ static=True,
+ )
+ for rotor_id in range(4):
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/rotor_cmd/{rotor_id}",
+ rr.SeriesLine(name=f"rotor_cmd_{rotor_id}"),
+ static=True,
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/min_d_to_obst",
+ rr.SeriesLine(name="min_d_to_obst"),
+ static=True,
+ )
+
+ for j in range(num_steps):
+ step_t = ep_dict[f"ep_{i}"]["t"][j]
+ step_min_d_obst = ep_dict[f"ep_{i}"]["min_dist_to_obstacle"][j]
+ step_wp_pos = ep_dict[f"ep_{i}"]["next_waypoint_p"][j]
+ # TODO: log action?
+
+ step_depth = None
+ step_color = None
+ step_cam_pose = None
+ if log_cam:
+ step_depth = ep_dict[f"ep_{i}"]["main_depth"][j]
+ step_color = ep_dict[f"ep_{i}"]["main_color"][j]
+ step_cam_pose = ep_dict[f"ep_{i}"]["main_cam_pose"][j]
+
+ for k in range(num_substeps):
+ substep_t = step_t + sim_dt * k
+ substep_ang_vel_d_b_frd = ep_dict[f"ep_{i}"]["ang_vel_des_b_frd"][
+ j
+ ][k]
+ substep_rotor_cmd = ep_dict[f"ep_{i}"]["rotor_cmd"][j][k]
+ substep_pos = ep_dict[f"ep_{i}"]["position_w"][j][k]
+ substep_quat = ep_dict[f"ep_{i}"]["quaternion_w"][j][k]
+ substep_lin_vel_w = ep_dict[f"ep_{i}"]["lin_vel_w"][j][k]
+ substep_lin_vel_b_frd = ep_dict[f"ep_{i}"]["lin_vel_b_frd"][j][k]
+ substep_ang_vel_b_frd = ep_dict[f"ep_{i}"]["ang_vel_b_frd"][j][k]
+
+ substep_lin_vel_norm = substep_lin_vel_w.norm()
+ vel_mapped_color = vel_cmap(substep_lin_vel_norm / vel_max_cmap)
+
+ # log time
+ rr.set_time_seconds("sim_time", substep_t)
+
+ # log position
+ rr.log(
+ f"episode_{ep_prefix}{i}/position",
+ rr.Points3D(
+ substep_pos,
+ colors=vel_mapped_color,
+ ),
+ )
+
+ # log timeseries
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/ang_vel_des_b_frd/x",
+ rr.Scalar(substep_ang_vel_d_b_frd[0]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/ang_vel_des_b_frd/y",
+ rr.Scalar(substep_ang_vel_d_b_frd[1]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/ang_vel_des_b_frd/z",
+ rr.Scalar(substep_ang_vel_d_b_frd[2]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/ang_vel_b_frd/x",
+ rr.Scalar(substep_ang_vel_b_frd[0]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/ang_vel_b_frd/y",
+ rr.Scalar(substep_ang_vel_b_frd[1]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/ang_vel_b_frd/z",
+ rr.Scalar(substep_ang_vel_b_frd[2]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/lin_vel_b_frd/x",
+ rr.Scalar(substep_lin_vel_b_frd[0]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/lin_vel_b_frd/y",
+ rr.Scalar(substep_lin_vel_b_frd[1]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/lin_vel_b_frd/z",
+ rr.Scalar(substep_lin_vel_b_frd[2]),
+ rr.SeriesLine(),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/speed",
+ rr.Scalar(substep_lin_vel_norm),
+ rr.SeriesLine(),
+ )
+ for rotor_id in range(4):
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/rotor_cmd/{rotor_id}",
+ rr.Scalar(substep_rotor_cmd[rotor_id]),
+ rr.SeriesLine(),
+ )
+
+ # log low frequency data
+ if k == 0:
+ # log min dist to obstacle
+ rr.log(
+ f"episode_{ep_prefix}{i}/scalar/min_d_to_obst",
+ rr.Scalar(step_min_d_obst),
+ rr.SeriesLine(),
+ )
+
+ # log lin vel vector
+ rr.log(
+ f"episode_{ep_prefix}{i}/velocity",
+ rr.Arrows3D(
+ origins=substep_pos,
+ vectors=substep_lin_vel_w / substep_lin_vel_norm,
+ colors=vel_mapped_color,
+ ),
+ )
+
+ # log vector to target waypoint
+ rr.log(
+ f"episode_{ep_prefix}{i}/vec_to_wp",
+ rr.Arrows3D(
+ origins=substep_pos,
+ vectors=step_wp_pos - substep_pos,
+ colors=[0, 255, 0],
+ ),
+ )
+
+ # log camera
+ if log_cam:
+ tf_body_to_cam = torch.eye(4)
+ tf_body_to_cam[:3, :3] = step_cam_pose[3:].reshape(3, 3)
+ tf_body_to_cam[:3, 3] = step_cam_pose[:3]
+ tf_world_to_body = torch.eye(4)
+ tf_world_to_body[:3, :3] = torch.tensor(
+ o3d.geometry.get_rotation_matrix_from_quaternion(
+ substep_quat.roll(1).numpy()
+ )
+ )
+ tf_world_to_body[:3, 3] = substep_pos
+ tf_world_to_cam = tf_world_to_body @ tf_body_to_cam
+ rr.log(
+ f"episode_{ep_prefix}{i}/camera",
+ rr.Pinhole(
+ focal_length=float(cam_params["f"]),
+ width=int(cam_params["w"]),
+ height=int(cam_params["h"]),
+ camera_xyz=rr.ViewCoordinates.FLU,
+ image_plane_distance=1.0,
+ ),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/camera/color",
+ rr.Image(step_color),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/camera/depth",
+ rr.DepthImage(
+ step_depth,
+ meter=(1 / cam_params["depth_scale"]),
+ colormap=rr.components.Colormap(1), # gray scale
+ ),
+ )
+ rr.log(
+ f"episode_{ep_prefix}{i}/camera",
+ rr.Transform3D(
+ translation=tf_world_to_cam[:3, 3],
+ mat3x3=tf_world_to_cam[:3, :3],
+ axis_length=0.0,
+ ),
+ )
+
+ # log urdf transform
+ rr.log(
+ f"episode_{ep_prefix}{i}/urdf",
+ rr.Transform3D(
+ translation=substep_pos,
+ rotation=rr.Quaternion(xyzw=substep_quat),
+ axis_length=1.0,
+ ),
+ )
+
+
+@rr.shutdown_at_exit
+def proc_env(
+ only_calc_metrics: bool,
+ combine: bool,
+ only_traj_combine: bool,
+ combine_rec_id: str,
+ cam_params: Dict[str, Any],
+ pcd_colormap: str,
+ vel_colormap: str,
+ vel_max_cmap: float,
+ traj_line_weight: float,
+ drone_urdf: str,
+ exp_dir: str,
+ env_id: int,
+ num_episodes: int,
+ wp_data_p: torch.Tensor, # (num_wps, 3)
+ wp_data_q: torch.Tensor, # (num_wps, 4)
+ wp_data_w: torch.Tensor, # (num_wps, )
+ wp_data_h: torch.Tensor, # (num_wps, )
+) -> Dict[str, Any]:
+ # start stopwatch
+ t_start = time.time()
+
+ # load episode data from file
+ ep_dict: Dict = torch.load(os.path.join(exp_dir, f"log_{env_id}.pt"))
+
+ rrd_file = "no rrd file as only calculating the metrics"
+ if not only_calc_metrics:
+ # init rerun
+ exp_name = os.path.basename(os.path.normpath(exp_dir))
+ rrd_file = os.path.join(exp_dir, f"env_{env_id}.rrd")
+ rr.init(application_id=exp_name, recording_id=f"env_{env_id}")
+ rr.save(path=rrd_file, default_blueprint=rrb_single_env())
+
+ # load pcd
+ pcd = o3d.io.read_point_cloud(os.path.join(exp_dir, f"pcd_{env_id}.ply"))
+
+ # log world frame and pcd
+ log_world_frame_and_pcd(pcd, pcd_colormap)
+
+ # log waypoint data
+ log_waypoint_data(wp_data_p, wp_data_q, wp_data_w, wp_data_h)
+
+ # log episode data
+ log_episode_data(
+ ep_dict,
+ cam_params,
+ vel_colormap,
+ vel_max_cmap,
+ traj_line_weight,
+ drone_urdf,
+ num_episodes,
+ True,
+ "",
+ )
+
+ # log extra data if combine envs
+ if combine:
+ rr.init(application_id=exp_name, recording_id=combine_rec_id)
+ rr.connect()
+ log_world_frame_and_pcd(pcd, pcd_colormap)
+ log_waypoint_data(wp_data_p, wp_data_q, wp_data_w, wp_data_h)
+ log_episode_data(
+ ep_dict,
+ cam_params,
+ vel_colormap,
+ vel_max_cmap,
+ traj_line_weight,
+ drone_urdf,
+ num_episodes,
+ False,
+ str(env_id),
+ only_traj_combine,
+ )
+
+ # calculate metrics for this env
+ metrics: Dict[str, Any] = {
+ "num_finishes": 0,
+ "num_crashes": 0,
+ "num_timeouts": 0,
+ "min_safety_margins": [], # each item correspond to one episode
+ "avg_lin_speeds": [],
+ "max_lin_speeds": [],
+ "avg_ang_speeds": [],
+ "max_ang_speeds": [],
+ "avg_avg_rotor_cmds": [],
+ "max_avg_rotor_cmds": [],
+ }
+ for i in range(num_episodes):
+ # termination flag
+ is_finished = ep_dict[f"ep_{i}"]["is_finished"]
+ is_crashed = ep_dict[f"ep_{i}"]["is_crashed"]
+ is_timeout = ep_dict[f"ep_{i}"]["is_timeout"]
+ assert len(is_finished) == len(is_crashed) == len(is_timeout)
+
+ ep_finished = torch.any(torch.stack(is_finished))
+ ep_crashed = torch.any(torch.stack(is_crashed))
+ ep_timeout = torch.any(torch.stack(is_timeout))
+ assert ep_finished.int() + ep_crashed.int() + ep_timeout.int() == 1
+
+ if ep_finished:
+ metrics["num_finishes"] += 1
+ elif ep_crashed:
+ metrics["num_crashes"] += 1
+ elif ep_timeout:
+ metrics["num_timeouts"] += 1
+
+ # safety margin
+ min_dist_to_obstacle = ep_dict[f"ep_{i}"]["min_dist_to_obstacle"]
+ metrics["min_safety_margins"].append(
+ float(torch.min(torch.stack(min_dist_to_obstacle)))
+ )
+
+ # lin speed
+ lin_vel = ep_dict[f"ep_{i}"]["lin_vel_w"]
+ if ep_crashed:
+ lin_vel.pop()
+ lin_speed = torch.linalg.norm(torch.cat(lin_vel), dim=1)
+ metrics["avg_lin_speeds"].append(float(torch.mean(lin_speed)))
+ metrics["max_lin_speeds"].append(float(torch.max(lin_speed)))
+
+ # ang speed
+ ang_vel = ep_dict[f"ep_{i}"]["ang_vel_b_frd"]
+ if ep_crashed:
+ ang_vel.pop()
+ ang_speed = torch.linalg.norm(torch.cat(ang_vel), dim=1)
+ metrics["avg_ang_speeds"].append(float(torch.mean(ang_speed)))
+ metrics["max_ang_speeds"].append(float(torch.max(ang_speed)))
+
+ # rotor cmd
+ rotor_cmd = ep_dict[f"ep_{i}"]["rotor_cmd"]
+ if ep_crashed:
+ rotor_cmd.pop()
+ avg_rotor_cmd = torch.cat(rotor_cmd).mean(dim=1)
+ metrics["avg_avg_rotor_cmds"].append(float(torch.mean(avg_rotor_cmd)))
+ metrics["max_avg_rotor_cmds"].append(float(torch.max(avg_rotor_cmd)))
+
+ assert (
+ metrics["num_finishes"] + metrics["num_crashes"] + metrics["num_timeouts"]
+ == num_episodes
+ )
+
+ # end stopwatch
+ t_end = time.time()
+ print(
+ f"[process env] env {env_id}, process time {t_end - t_start}, created {rrd_file}"
+ )
+
+ # return the metrics for this env
+ return metrics
+
+
+def main():
+ # info
+ print("+++ Rerunning experiment")
+
+ # Suppress torch.load warning
+ warnings.filterwarnings("ignore", category=FutureWarning)
+
+ # args
+ arg_parser = argparse.ArgumentParser()
+ arg_parser.add_argument("--exp_dir", type=str, required=True)
+ arg_parser.add_argument("--num_processes", type=int, default=16)
+ arg_parser.add_argument("--pcd_colormap", type=str, default="turbo")
+ arg_parser.add_argument("--vel_colormap", type=str, default="plasma")
+ arg_parser.add_argument("--vel_max_cmap", type=float, default=25.0)
+ arg_parser.add_argument("--traj_line_weight", type=float, default=0.5)
+ arg_parser.add_argument("--drone_urdf", type=str)
+ arg_parser.add_argument("--combine_envs", action="store_true")
+ arg_parser.add_argument("--only_calc_metrics", action="store_true")
+ arg_parser.add_argument("--only_traj_combine", action="store_true")
+
+ args = arg_parser.parse_args()
+ exp_dir: str = args.exp_dir
+ num_processes: int = args.num_processes
+ pcd_colormap: str = args.pcd_colormap
+ vel_colormap: str = args.vel_colormap
+ vel_max_cmap: float = args.vel_max_cmap
+ traj_line_weight: float = args.traj_line_weight
+ drone_urdf: str = args.drone_urdf
+ combine_envs: bool = args.combine_envs
+ only_calc_metrics: bool = args.only_calc_metrics
+ only_traj_combine: bool = args.only_traj_combine
+
+ # get info from cfg
+ num_envs = 0
+ cam_params: Dict[str, Any] = {}
+ num_episodes = 0
+ wp_data_p_list: List[torch.Tensor] = []
+ wp_data_q_list: List[torch.Tensor] = []
+ wp_data_w_list: List[torch.Tensor] = []
+ wp_data_h_list: List[torch.Tensor] = []
+
+ log_dirs: List[str] = [
+ os.path.join(exp_dir, d)
+ for d in os.listdir(exp_dir)
+ if os.path.isdir(os.path.join(exp_dir, d))
+ ]
+ log_dirs.sort()
+ for log_dir in log_dirs:
+ cfg: Dict[str, Any] = torch.load(os.path.join(log_dir, "cfg.pt"))
+ num_envs += cfg["env"]["numEnvs"]
+ wp_data_p_list.append(cfg["waypoint_data_p"])
+ wp_data_q_list.append(cfg["waypoint_data_q"])
+ wp_data_w_list.append(cfg["waypoint_data_w"])
+ wp_data_h_list.append(cfg["waypoint_data_h"])
+ if len(cam_params) == 0:
+ w = cfg["env"]["cameraWidth"]
+ h = cfg["env"]["cameraHeight"]
+ hfov = cfg["env"]["cameraHfov"]
+ max_depth = cfg["env"]["cameraDepthMax"]
+ f = w / (2 * np.tan(np.deg2rad(hfov) / 2))
+ cam_params["w"] = w
+ cam_params["h"] = h
+ cam_params["f"] = f
+ cam_params["depth_scale"] = max_depth
+ num_episodes = cfg["env"]["logging"]["maxNumEpisodes"]
+ print(cam_params)
+ print(f"number of episodes: {num_episodes}")
+
+ # we assume the number of waypoints is constant throughout one experiment
+ wp_data_p = torch.cat(wp_data_p_list) # (num_envs, num_wps, 3)
+ wp_data_q = torch.cat(wp_data_q_list) # (num_envs, num_wps, 4)
+ wp_data_w = torch.cat(wp_data_w_list) # (num_envs, num_wps)
+ wp_data_h = torch.cat(wp_data_h_list) # (num_envs, num_wps)
+ assert wp_data_p.shape[0] == num_envs
+ assert wp_data_q.shape[0] == num_envs
+ assert wp_data_w.shape[0] == num_envs
+ assert wp_data_h.shape[0] == num_envs
+
+ # extra initialization if we need to combine envs
+ combine_rec_id: str = "env_combined_" + "{date:%y-%m-%d-%H-%M-%S}".format(
+ date=datetime.now()
+ )
+ if combine_envs:
+ rr.init(
+ application_id=os.path.basename(os.path.normpath(exp_dir)),
+ recording_id=combine_rec_id,
+ spawn=True,
+ )
+
+ # process data for envs in parallel
+ print("processing data in parallel")
+ with mp.Pool(min(num_processes, num_envs)) as pool:
+ env_metrics: List[Dict[str, Any]] = pool.starmap(
+ proc_env,
+ [
+ (
+ only_calc_metrics,
+ combine_envs,
+ only_traj_combine,
+ combine_rec_id,
+ cam_params,
+ pcd_colormap,
+ vel_colormap,
+ vel_max_cmap,
+ traj_line_weight,
+ drone_urdf,
+ exp_dir,
+ env_id,
+ num_episodes,
+ wp_data_p[env_id].clone(),
+ wp_data_q[env_id].clone(),
+ wp_data_w[env_id].clone(),
+ wp_data_h[env_id].clone(),
+ )
+ for env_id in range(num_envs)
+ ],
+ )
+
+ if combine_envs:
+ # TODO: automatic saving
+ rr.send_blueprint(rrb_combined_env())
+ print("[main] please manually save rr data for combined env")
+
+ # now we have a list of dictionaries containing episode data
+ # aggregate them and save them
+ aggregated_metrics: Dict[str, Any] = {
+ "num_finishes": 0,
+ "num_crashes": 0,
+ "num_timeouts": 0,
+ "min_safety_margins": [], # each item correspond to one episode
+ "avg_lin_speeds": [],
+ "max_lin_speeds": [],
+ "avg_ang_speeds": [],
+ "max_ang_speeds": [],
+ "avg_avg_rotor_cmds": [],
+ "max_avg_rotor_cmds": [],
+ }
+
+ for i in range(num_envs):
+ metrics = env_metrics[i]
+ aggregated_metrics["num_finishes"] += metrics["num_finishes"]
+ aggregated_metrics["num_crashes"] += metrics["num_crashes"]
+ aggregated_metrics["num_timeouts"] += metrics["num_timeouts"]
+ aggregated_metrics["min_safety_margins"].extend(metrics["min_safety_margins"])
+ aggregated_metrics["avg_lin_speeds"].extend(metrics["avg_lin_speeds"])
+ aggregated_metrics["max_lin_speeds"].extend(metrics["max_lin_speeds"])
+ aggregated_metrics["avg_ang_speeds"].extend(metrics["avg_ang_speeds"])
+ aggregated_metrics["max_ang_speeds"].extend(metrics["max_ang_speeds"])
+ aggregated_metrics["avg_avg_rotor_cmds"].extend(metrics["avg_avg_rotor_cmds"])
+ aggregated_metrics["max_avg_rotor_cmds"].extend(metrics["max_avg_rotor_cmds"])
+
+ total_episodes = num_envs * num_episodes
+ assert (
+ aggregated_metrics["num_finishes"]
+ + aggregated_metrics["num_crashes"]
+ + aggregated_metrics["num_timeouts"]
+ == total_episodes
+ )
+ assert len(aggregated_metrics["min_safety_margins"]) == total_episodes
+ assert len(aggregated_metrics["avg_lin_speeds"]) == total_episodes
+ assert len(aggregated_metrics["max_lin_speeds"]) == total_episodes
+ assert len(aggregated_metrics["avg_ang_speeds"]) == total_episodes
+ assert len(aggregated_metrics["max_ang_speeds"]) == total_episodes
+ assert len(aggregated_metrics["avg_avg_rotor_cmds"]) == total_episodes
+ assert len(aggregated_metrics["max_avg_rotor_cmds"]) == total_episodes
+ torch.save(aggregated_metrics, os.path.join(exp_dir, "metrics.pt"))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/hyperparam/tune_hyperparam_splits_no_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/hyperparam/tune_hyperparam_splits_no_cam.sh
new file mode 100755
index 000000000..25e67d209
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/hyperparam/tune_hyperparam_splits_no_cam.sh
@@ -0,0 +1,40 @@
+run() {
+ python train.py task=DRAsset \
+ headless=True \
+ wandb_activate=True \
+ max_iterations=$1 \
+ num_envs=$2 \
+ train.params.network.mlp.units=$3 \
+ train.params.config.normalize_input=$4 \
+ train.params.config.horizon_length=$5 \
+ train.params.config.minibatch_size=$6 \
+ train.params.config.name=$7
+}
+
+cd ../../../../../
+
+n_envs=16384
+b_iters=400
+for units in \
+ "[256,256,256,256]" \
+ "[256,128,128,64]" \
+ "[128,128,128,128]" \
+ "[256,256,256]" \
+ "[256,128,64]" \
+ "[128,128,128]" \
+ "[256,256]" \
+ "[256,128]" \
+ "[128,128]"; do
+ for normalize in False True; do
+ for horizon in 50 100 200; do
+ for denom in 8 16 32; do
+ minibatch_size=$((n_envs * horizon / denom))
+ clean_units=$(echo $units | tr -d "[]" | tr "," "-" | tr -d " ")
+ name="${clean_units}_${normalize}_${horizon}_${denom}"
+ iters=$((b_iters * 50 / horizon))
+ echo $iters $name
+ run $iters $n_envs $units $normalize $horizon $minibatch_size $name
+ done
+ done
+ done
+done
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_ang_vel.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_ang_vel.sh
new file mode 100755
index 000000000..e140f5380
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_ang_vel.sh
@@ -0,0 +1,47 @@
+# usage: ./plot_ang_vel.sh 460 350 ~/Desktop/ang_vel.pdf 8 sans-serif 0.05
+
+cd ../../../../../
+
+ts=$(date +"%Y%m%d%H%M%S")
+exp_name="plot_ang_vel_$ts"
+
+# run rollout on SPLIT-S with all cameras enabled
+run_out=$(
+ python train.py task=DRAsset \
+ checkpoint=tasks/drone_racing/demos/checkpoints/splits_ang_vel_plot.pth \
+ test=True \
+ num_envs=1 \
+ train.params.config.horizon_length=500 \
+ task.env.enableCameraSensors=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$exp_name \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=500 \
+ task.assetName=splits \
+ task.env.disableGround=True
+)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir
+
+# plot
+python plot_ang_vel.py \
+ --log_file "$exp_dir/log_0.pt" \
+ --episode_id 0 \
+ --ctrl_dt 0.004 \
+ --fig_w $1 \
+ --fig_h $2 \
+ --fig_file $3 \
+ --font_size $4 \
+ --font_family $5 \
+ --legend_vspace $6
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_rand_default.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_rand_default.sh
new file mode 100755
index 000000000..bf36bddb3
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_rand_default.sh
@@ -0,0 +1,35 @@
+# data in this script is collected using
+# test_perf_rand_default_no_cam.sh and test_perf_rand_default_with_cam.sh
+# OS: Ubuntu 22.04.4 LTS x86_64
+# CPU: 13th Gen Intel i9-13900K (32) @ 5.500GHz
+# GPU: NVIDIA RTX 4090
+# arg 1: path to environment screenshot
+# arg 2: figure width in pt
+# arg 3: figure height in pt
+# arg 4: file of saved figure
+# arg 5: font size
+# arg 6: font family
+# arg 7: additional y axis offset
+# arg 8: marker size
+# arg 9: result img dpi
+# arg 10: legend vertical space
+# usage:
+# ./plot_perf_rand_default.sh ../../imgs/perf_test_rand_default.png 460 110 ~/Desktop/perf_rand_default.pdf 6.3 sans-serif 1.15 4 1000 0.25
+
+python ../../plot_perf_test.py \
+ --env_img $1 \
+ --num_envs_no_cam 1 512 1024 2048 4096 8192 16384 24576 \
+ --total_fps_no_cam 108 36764 62548 96774 132771 156204 153786 147575 \
+ --vram_no_cam 880 1272 1732 2368 3822 6710 12356 17554 \
+ --num_envs_cam 1 200 400 600 800 1000 1200 1400 \
+ --total_fps_cam 89 3363 3740 3804 3832 3806 3745 3676 \
+ --vram_cam 1438 4246 7058 9888 12628 15513 18298 21043 \
+ --fig_w $2 \
+ --fig_h $3 \
+ --fig_file $4 \
+ --font_size $5 \
+ --font_family $6 \
+ --yaxis_offset $7 \
+ --marker_size $8 \
+ --dpi $9 \
+ --legend_vspace ${10}
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_rand_no_obstacle.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_rand_no_obstacle.sh
new file mode 100755
index 000000000..5d827398e
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_rand_no_obstacle.sh
@@ -0,0 +1,35 @@
+# data in this script is collected using
+# test_perf_rand_no_obstacle_no_cam.sh and test_perf_rand_no_obstacle_with_cam.sh
+# OS: Ubuntu 22.04.4 LTS x86_64
+# CPU: 13th Gen Intel i9-13900K (32) @ 5.500GHz
+# GPU: NVIDIA RTX 4090
+# arg 1: path to environment screenshot
+# arg 2: figure width in pt
+# arg 3: figure height in pt
+# arg 4: file of saved figure
+# arg 5: font size
+# arg 6: font family
+# arg 7: additional y axis offset
+# arg 8: marker size
+# arg 9: result img dpi
+# arg 10: legend vertical space
+# usage:
+# ./plot_perf_rand_no_obstacle.sh ../../imgs/perf_test_rand_no_obst.png 460 110 ~/Desktop/perf_rand_no_obst.pdf 6.3 sans-serif 1.15 4 1000 0.25
+
+python ../../plot_perf_test.py \
+ --env_img $1 \
+ --num_envs_no_cam 1 512 1024 2048 4096 8192 16384 24576 \
+ --total_fps_no_cam 111 42826 78176 138784 237917 351394 430363 442050 \
+ --vram_no_cam 880 1204 1466 2106 3272 5498 9990 14382 \
+ --num_envs_cam 1 200 400 600 800 1000 1200 1400 \
+ --total_fps_cam 87 4129 4643 4755 4752 4706 4635 4548 \
+ --vram_cam 1435 4171 6975 9726 12467 15220 17973 20782 \
+ --fig_w $2 \
+ --fig_h $3 \
+ --fig_file $4 \
+ --font_size $5 \
+ --font_family $6 \
+ --yaxis_offset $7 \
+ --marker_size $8 \
+ --dpi $9 \
+ --legend_vspace ${10}
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_splits.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_splits.sh
new file mode 100755
index 000000000..9ddfe2f5d
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_perf_splits.sh
@@ -0,0 +1,35 @@
+# data in this script is collected using
+# test_perf_splits_no_cam.sh and test_perf_splits_with_cam.sh
+# OS: Ubuntu 22.04.4 LTS x86_64
+# CPU: 13th Gen Intel i9-13900K (32) @ 5.500GHz
+# GPU: NVIDIA RTX 4090
+# arg 1: path to environment screenshot
+# arg 2: figure width in pt
+# arg 3: figure height in pt
+# arg 4: file of saved figure
+# arg 5: font size
+# arg 6: font family
+# arg 7: additional y axis offset
+# arg 8: marker size
+# arg 9: result img dpi
+# arg 10: legend vertical space
+# usage:
+# ./plot_perf_splits.sh ../../imgs/perf_test_splits.png 460 110 ~/Desktop/perf_splits.pdf 6.3 sans-serif 1.15 4 1000 0.25
+
+python ../../plot_perf_test.py \
+ --env_img $1 \
+ --num_envs_no_cam 1 512 1024 2048 4096 8192 16384 24576 \
+ --total_fps_no_cam 111 42020 79461 138075 207683 273133 291748 259968 \
+ --vram_no_cam 880 1204 1528 2168 3432 5940 10960 16104 \
+ --num_envs_cam 1 200 400 600 800 1000 1200 1400 \
+ --total_fps_cam 87 3919 4347 4456 4474 4407 4345 4247 \
+ --vram_cam 1435 4238 6982 9799 12543 15302 18182 20926 \
+ --fig_w $2 \
+ --fig_h $3 \
+ --fig_file $4 \
+ --font_size $5 \
+ --font_family $6 \
+ --yaxis_offset $7 \
+ --marker_size $8 \
+ --dpi $9 \
+ --legend_vspace ${10}
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_rand_dr.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_rand_dr.sh
new file mode 100755
index 000000000..8bd8c4a02
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_rand_dr.sh
@@ -0,0 +1,13 @@
+# usage: ./plot_train_rand_dr.sh 252 280 6.5
+
+python ../../plot_train_log.py \
+ --ep_len_csv ../../train_log/rand_dr_ep_len.csv \
+ --rew_csv ../../train_log/rand_dr_rew.csv \
+ --rew_col_csv ../../train_log/rand_dr_rew_col.csv \
+ --rew_wp_csv ../../train_log/rand_dr_rew_wp.csv \
+ --fig_w $1 \
+ --fig_h $2 \
+ --fig_file ~/Desktop/train_log_rand_dr.pdf \
+ --font_size $3 \
+ --font_family serif \
+ --xlim_high 530000000
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_rand_no_obst.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_rand_no_obst.sh
new file mode 100755
index 000000000..1888330e7
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_rand_no_obst.sh
@@ -0,0 +1,11 @@
+# usage: ./plot_train_rand_no_obst.sh 460 100 8
+
+python ../../plot_train_log.py \
+ --ep_len_csv ../../train_log/rand_no_obst_ep_len.csv \
+ --rew_csv ../../train_log/rand_no_obst_rew.csv \
+ --fig_w $1 \
+ --fig_h $2 \
+ --fig_file ~/Desktop/train_log_rand_no_obst.pdf \
+ --font_size $3 \
+ --font_family sans-serif \
+ --xlim_high 250000000
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_splits_direct.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_splits_direct.sh
new file mode 100755
index 000000000..d233c43eb
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/plots/plot_train_splits_direct.sh
@@ -0,0 +1,11 @@
+# usage: ./plot_train_splits_direct.sh 460 100 8
+
+python ../../plot_train_log.py \
+ --ep_len_csv ../../train_log/splits_direct_ep_len.csv \
+ --rew_csv ../../train_log/splits_direct_rew.csv \
+ --fig_w $1 \
+ --fig_h $2 \
+ --fig_file ~/Desktop/train_log_splits_direct.pdf \
+ --font_size $3 \
+ --font_family sans-serif \
+ --xlim_high 250000000
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_hard.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_hard.sh
new file mode 100755
index 000000000..bcf1c15b6
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_hard.sh
@@ -0,0 +1,6 @@
+ts=$(date +"%Y%m%d%H%M%S")
+
+./test_cam_multistory.sh $1 "${ts}_multistory"
+./test_cam_rmua.sh $1 "${ts}_rmua"
+./test_cam_walls.sh $1 "${ts}_walls"
+./test_cam_wavy_eight.sh $1 "${ts}_wavy_eight"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_no_obst.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_no_obst.sh
new file mode 100755
index 000000000..61c8630cb
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_no_obst.sh
@@ -0,0 +1,7 @@
+ts=$(date +"%Y%m%d%H%M%S")
+
+./test_cam_simple_stick_no_obst.sh $1 "${ts}_simple_stick_no_obst"
+./test_cam_geom_kebab_no_obst.sh $1 "${ts}_geom_kebab_no_obst"
+./test_cam_planar_circle_no_obst.sh $1 "${ts}_planar_circle_no_obst"
+./test_cam_wavy_eight_no_obst.sh $1 "${ts}_wavy_eight_no_obst"
+./test_cam_turns.sh $1 "${ts}_turns"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_obst.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_obst.sh
new file mode 100755
index 000000000..d12f7d19a
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_asset_obst.sh
@@ -0,0 +1,6 @@
+ts=$(date +"%Y%m%d%H%M%S")
+
+./test_cam_simple_stick.sh $1 "${ts}_simple_stick"
+./test_cam_geom_kebab.sh $1 "${ts}_geom_kebab"
+./test_cam_planar_circle.sh $1 "${ts}_planar_circle"
+./test_cam_wavy_eight.sh $1 "${ts}_wavy_eight"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_rand.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_rand.sh
new file mode 100755
index 000000000..0e624ded9
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/collection_cam_rand.sh
@@ -0,0 +1,8 @@
+ts=$(date +"%Y%m%d%H%M%S")
+
+#./test_cam_rand_l0.sh $1 "${ts}_rand_l0" # too similar to l1
+./test_cam_rand_l1.sh $1 "${ts}_rand_l1"
+#./test_cam_rand_l2.sh $1 "${ts}_rand_l2" # too similar to l1
+./test_cam_rand_l3.sh $1 "${ts}_rand_l3"
+./test_cam_rand_l4.sh $1 "${ts}_rand_l4"
+./test_cam_rand_l5.sh $1 "${ts}_rand_l5"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_geom_kebab.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_geom_kebab.sh
new file mode 100755
index 000000000..87ca86d52
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_geom_kebab.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=50 \
+ task.assetName=geom_kebab \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=2 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_geom_kebab_no_obst.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_geom_kebab_no_obst.sh
new file mode 100755
index 000000000..c77f74089
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_geom_kebab_no_obst.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=50 \
+ task.assetName=geom_kebab_no_obst \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=2 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_multistory.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_multistory.sh
new file mode 100755
index 000000000..126ff9bb2
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_multistory.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=multistory \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=0 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=4 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_planar_circle.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_planar_circle.sh
new file mode 100755
index 000000000..c2acf3e64
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_planar_circle.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=50 \
+ task.assetName=planar_circle \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=2 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_planar_circle_no_obst.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_planar_circle_no_obst.sh
new file mode 100755
index 000000000..036471ff4
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_planar_circle_no_obst.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=50 \
+ task.assetName=planar_circle_no_obst \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=2 \
+ task.env.logging.numStepsPerSave=100 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l0.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l0.sh
new file mode 100755
index 000000000..e462191de
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l0.sh
@@ -0,0 +1,109 @@
+# similar to training env in train_rand_dr.sh
+# disable all physical gates
+
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRRandom \
+ seed=$1 \
+ checkpoint=$2 \
+ num_envs=$3 \
+ test=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$4 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=$5 \
+ task.env.logging.numStepsPerSave=$6 \
+ task.env.maxEpisodeLength=$7 \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=4 \
+ task.envCreator.num_tree_assets=4 \
+ task.envCreator.num_wall_actors=12 \
+ task.envCreator.num_wall_assets=12 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=0 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1.4 \
+ task.initRandOpt.randObstacleOptions.orbit_density=0 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=0.67 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5
+}
+
+
+cd ../../../../../
+
+# 100 envs, 10 episodes per env
+# args: seed, checkpoint, num_envs, exp_name, num_ep, num_steps_save, ep_len
+run_out=$(run 0 $1 25 $2 10 50 100000)
+run_out=$(run 1 $1 25 $2 10 50 100000)
+run_out=$(run 2 $1 25 $2 10 50 100000)
+run_out=$(run 3 $1 25 $2 10 50 100000)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --traj_line_w 1.5
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l1.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l1.sh
new file mode 100755
index 000000000..5460e8cab
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l1.sh
@@ -0,0 +1,108 @@
+# similar to training env in train_rand_dr.sh
+
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRRandom \
+ seed=$1 \
+ checkpoint=$2 \
+ num_envs=$3 \
+ test=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$4 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=$5 \
+ task.env.logging.numStepsPerSave=$6 \
+ task.env.maxEpisodeLength=$7 \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=4 \
+ task.envCreator.num_tree_assets=4 \
+ task.envCreator.num_wall_actors=12 \
+ task.envCreator.num_wall_assets=12 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=-1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1.4 \
+ task.initRandOpt.randObstacleOptions.orbit_density=0 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=0.67 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5
+}
+
+
+cd ../../../../../
+
+# 100 envs, 10 episodes per env
+# args: seed, checkpoint, num_envs, exp_name, num_ep, num_steps_save, ep_len
+run_out=$(run 0 $1 25 $2 10 50 100000)
+run_out=$(run 1 $1 25 $2 10 50 100000)
+run_out=$(run 2 $1 25 $2 10 50 100000)
+run_out=$(run 3 $1 25 $2 10 50 100000)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --traj_line_w 1.5
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l1_quick.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l1_quick.sh
new file mode 100755
index 000000000..32cd4f7ad
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l1_quick.sh
@@ -0,0 +1,103 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRRandom \
+ seed=$1 \
+ checkpoint=$2 \
+ num_envs=$3 \
+ test=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$4 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=$5 \
+ task.env.logging.numStepsPerSave=$6 \
+ task.env.maxEpisodeLength=$7 \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=4 \
+ task.envCreator.num_tree_assets=4 \
+ task.envCreator.num_wall_actors=12 \
+ task.envCreator.num_wall_assets=12 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=-1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1.4 \
+ task.initRandOpt.randObstacleOptions.orbit_density=0 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=0.67 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5
+}
+
+
+cd ../../../../../
+
+# 100 envs, 10 episodes per env
+# args: seed, checkpoint, num_envs, exp_name, num_ep, num_steps_save, ep_len
+run_out=$(run 0 $1 2 $2 25 2000 100000)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --traj_line_w 0.75
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l2.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l2.sh
new file mode 100755
index 000000000..d17b4d39b
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l2.sh
@@ -0,0 +1,109 @@
+# similar to training env in train_rand_dr.sh
+# enable all physical gates
+
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRRandom \
+ seed=$1 \
+ checkpoint=$2 \
+ num_envs=$3 \
+ test=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$4 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=$5 \
+ task.env.logging.numStepsPerSave=$6 \
+ task.env.maxEpisodeLength=$7 \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=4 \
+ task.envCreator.num_tree_assets=4 \
+ task.envCreator.num_wall_actors=12 \
+ task.envCreator.num_wall_assets=12 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1.4 \
+ task.initRandOpt.randObstacleOptions.orbit_density=0 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=0.67 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5
+}
+
+
+cd ../../../../../
+
+# 100 envs, 10 episodes per env
+# args: seed, checkpoint, num_envs, exp_name, num_ep, num_steps_save, ep_len
+run_out=$(run 0 $1 25 $2 10 50 100000)
+run_out=$(run 1 $1 25 $2 10 50 100000)
+run_out=$(run 2 $1 25 $2 10 50 100000)
+run_out=$(run 3 $1 25 $2 10 50 100000)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --traj_line_w 1.5
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l3.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l3.sh
new file mode 100755
index 000000000..9dce055b2
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l3.sh
@@ -0,0 +1,109 @@
+# based on l2
+# double obstacles, enable all gates, extra_clearance 1.4->1, wall_dist_scale 0.67->1
+
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRRandom \
+ seed=$1 \
+ checkpoint=$2 \
+ num_envs=$3 \
+ test=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$4 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=$5 \
+ task.env.logging.numStepsPerSave=$6 \
+ task.env.maxEpisodeLength=$7 \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=8 \
+ task.envCreator.num_tree_assets=8 \
+ task.envCreator.num_wall_actors=24 \
+ task.envCreator.num_wall_assets=24 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1 \
+ task.initRandOpt.randObstacleOptions.orbit_density=0 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=1 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5
+}
+
+
+cd ../../../../../
+
+# 100 envs, 10 episodes per env
+# args: seed, checkpoint, num_envs, exp_name, num_ep, num_steps_save, ep_len
+run_out=$(run 0 $1 25 $2 10 50 100000)
+run_out=$(run 1 $1 25 $2 10 50 100000)
+run_out=$(run 2 $1 25 $2 10 50 100000)
+run_out=$(run 3 $1 25 $2 10 50 100000)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --traj_line_w 1.5
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l4.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l4.sh
new file mode 100755
index 000000000..578b4a8f5
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l4.sh
@@ -0,0 +1,109 @@
+# based on l3
+# add orbit obstacles
+
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRRandom \
+ seed=$1 \
+ checkpoint=$2 \
+ num_envs=$3 \
+ test=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$4 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=$5 \
+ task.env.logging.numStepsPerSave=$6 \
+ task.env.maxEpisodeLength=$7 \
+ task.envCreator.num_box_actors=10 \
+ task.envCreator.num_box_assets=10 \
+ task.envCreator.num_capsule_actors=10 \
+ task.envCreator.num_capsule_assets=10 \
+ task.envCreator.num_cuboid_wireframe_actors=10 \
+ task.envCreator.num_cuboid_wireframe_assets=10 \
+ task.envCreator.num_cylinder_actors=10 \
+ task.envCreator.num_cylinder_assets=10 \
+ task.envCreator.num_hollow_cuboid_actors=10 \
+ task.envCreator.num_hollow_cuboid_assets=10 \
+ task.envCreator.num_sphere_actors=10 \
+ task.envCreator.num_sphere_assets=10 \
+ task.envCreator.num_tree_actors=8 \
+ task.envCreator.num_tree_assets=8 \
+ task.envCreator.num_wall_actors=24 \
+ task.envCreator.num_wall_assets=24 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1 \
+ task.initRandOpt.randObstacleOptions.orbit_density=1 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=1 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5
+}
+
+
+cd ../../../../../
+
+# 100 envs, 10 episodes per env
+# args: seed, checkpoint, num_envs, exp_name, num_ep, num_steps_save, ep_len
+run_out=$(run 0 $1 25 $2 10 50 100000)
+run_out=$(run 1 $1 25 $2 10 50 100000)
+run_out=$(run 2 $1 25 $2 10 50 100000)
+run_out=$(run 3 $1 25 $2 10 50 100000)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --traj_line_w 1.5
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l5.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l5.sh
new file mode 100755
index 000000000..de4c97ce5
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rand_l5.sh
@@ -0,0 +1,109 @@
+# based on l4
+# harder waypoint layouts
+
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRRandom \
+ seed=$1 \
+ checkpoint=$2 \
+ num_envs=$3 \
+ test=True \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$4 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=$5 \
+ task.env.logging.numStepsPerSave=$6 \
+ task.env.maxEpisodeLength=$7 \
+ task.envCreator.num_box_actors=10 \
+ task.envCreator.num_box_assets=10 \
+ task.envCreator.num_capsule_actors=10 \
+ task.envCreator.num_capsule_assets=10 \
+ task.envCreator.num_cuboid_wireframe_actors=10 \
+ task.envCreator.num_cuboid_wireframe_assets=10 \
+ task.envCreator.num_cylinder_actors=10 \
+ task.envCreator.num_cylinder_assets=10 \
+ task.envCreator.num_hollow_cuboid_actors=10 \
+ task.envCreator.num_hollow_cuboid_assets=10 \
+ task.envCreator.num_sphere_actors=10 \
+ task.envCreator.num_sphere_assets=10 \
+ task.envCreator.num_tree_actors=8 \
+ task.envCreator.num_tree_assets=8 \
+ task.envCreator.num_wall_actors=24 \
+ task.envCreator.num_wall_assets=24 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.3 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.3 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=1.0 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.4 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.3 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1 \
+ task.initRandOpt.randObstacleOptions.orbit_density=1 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=1 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5
+}
+
+
+cd ../../../../../
+
+# 100 envs, 10 episodes per env
+# args: seed, checkpoint, num_envs, exp_name, num_ep, num_steps_save, ep_len
+run_out=$(run 0 $1 25 $2 10 50 100000)
+run_out=$(run 1 $1 25 $2 10 50 100000)
+run_out=$(run 2 $1 25 $2 10 50 100000)
+run_out=$(run 3 $1 25 $2 10 50 100000)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --traj_line_w 1.5
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rmua.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rmua.sh
new file mode 100755
index 000000000..f33f86598
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_rmua.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=rmua \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=0 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=4 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_simple_stick.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_simple_stick.sh
new file mode 100755
index 000000000..12d039905
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_simple_stick.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=50 \
+ task.assetName=simple_stick \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=2 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_simple_stick_no_obst.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_simple_stick_no_obst.sh
new file mode 100755
index 000000000..d72283b10
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_simple_stick_no_obst.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=50 \
+ task.assetName=simple_stick_no_obst \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=2 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_0.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_0.sh
new file mode 100755
index 000000000..f0e2ba21f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_0.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_3dc \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 0 0 0)
+run_out=$(run $1 $2 0 1 1)
+run_out=$(run $1 $2 0 2 2)
+run_out=$(run $1 $2 0 3 3)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=0 success_rate=12/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_12.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_12.sh
new file mode 100755
index 000000000..5a8f950df
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_12.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_3dc \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 12 0 30)
+run_out=$(run $1 $2 12 1 31)
+run_out=$(run $1 $2 12 2 32)
+run_out=$(run $1 $2 12 3 33)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=12 success_rate=0/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_16.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_16.sh
new file mode 100755
index 000000000..b26deea8c
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_16.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_3dc \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 16 0 50)
+run_out=$(run $1 $2 16 1 51)
+run_out=$(run $1 $2 16 2 52)
+run_out=$(run $1 $2 16 3 53)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=16 success_rate=2/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_4.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_4.sh
new file mode 100755
index 000000000..8f58c963a
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_4.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_3dc \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 4 0 10)
+run_out=$(run $1 $2 4 1 11)
+run_out=$(run $1 $2 4 2 12)
+run_out=$(run $1 $2 4 3 13)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=4 success_rate=9/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_8.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_8.sh
new file mode 100755
index 000000000..b915a5e00
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_3dc_8.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_3dc \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 8 0 20)
+run_out=$(run $1 $2 8 1 21)
+run_out=$(run $1 $2 8 2 22)
+run_out=$(run $1 $2 8 3 23)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=8 success_rate=1/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_0.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_0.sh
new file mode 100755
index 000000000..3e04d6179
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_0.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_ell \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 0 0 0)
+run_out=$(run $1 $2 0 1 1)
+run_out=$(run $1 $2 0 2 2)
+run_out=$(run $1 $2 0 3 3)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=0 success_rate=2/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_12.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_12.sh
new file mode 100755
index 000000000..db3181299
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_12.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_ell \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 12 0 30)
+run_out=$(run $1 $2 12 1 31)
+run_out=$(run $1 $2 12 2 32)
+run_out=$(run $1 $2 12 3 33)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=12 success_rate=0/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_18.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_18.sh
new file mode 100755
index 000000000..1ed841a20
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_18.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_ell \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 18 0 20)
+run_out=$(run $1 $2 18 1 21)
+run_out=$(run $1 $2 18 2 22)
+run_out=$(run $1 $2 18 3 23)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=18 success_rate=0/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_24.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_24.sh
new file mode 100755
index 000000000..981a58d6b
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_24.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_ell \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 24 0 50)
+run_out=$(run $1 $2 24 1 51)
+run_out=$(run $1 $2 24 2 52)
+run_out=$(run $1 $2 24 3 53)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=24 success_rate=0/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_6.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_6.sh
new file mode 100755
index 000000000..157532758
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_ell_6.sh
@@ -0,0 +1,74 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_ell \
+ task.sjtu_track.type_id=$4 \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$5
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 6 0 10)
+run_out=$(run $1 $2 6 1 11)
+run_out=$(run $1 $2 6 2 12)
+run_out=$(run $1 $2 6 3 13)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=6 success_rate=0/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_str.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_str.sh
new file mode 100755
index 000000000..d59229f3c
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_sjtu_str.sh
@@ -0,0 +1,77 @@
+if [ "$#" -ne 3 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name num_obstacles"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=sjtu_str \
+ task.sjtu_track.num_obstacles=$3 \
+ task.env.appendWpDist=5 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1 \
+ seed=$4
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2 $3 0)
+run_out=$(run $1 $2 $3 1)
+run_out=$(run $1 $2 $3 2)
+run_out=$(run $1 $2 $3 3)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --vel_max_cmap 20 \
+ --only_calc_metrics
+
+# num_obstacles=0 success_rate=2/100
+# num_obstacles=3 success_rate=0/100
+# num_obstacles=6 success_rate=0/100
+# num_obstacles=9 success_rate=0/100
+# num_obstacles=12 success_rate=0/100
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_turns.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_turns.sh
new file mode 100755
index 000000000..a2e9c876c
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_turns.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=turns \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=4 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_walls.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_walls.sh
new file mode 100755
index 000000000..f5543eeab
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_walls.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=walls \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=0 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=4 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_wavy_eight.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_wavy_eight.sh
new file mode 100755
index 000000000..879b3802d
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_wavy_eight.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=wavy_eight \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=4 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_wavy_eight_no_obst.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_wavy_eight_no_obst.sh
new file mode 100755
index 000000000..79b2a07a7
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_cam_wavy_eight_no_obst.sh
@@ -0,0 +1,67 @@
+if [ "$#" -ne 2 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint exp_name"
+ exit 1
+fi
+
+run() {
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=25 \
+ task.assetName=wavy_eight_no_obst \
+ task.env.appendWpDist=10 \
+ task.env.numObservations=120 \
+ task.env.obsImgMode=dce \
+ task.env.disableGround=True \
+ task.env.groundOffset=-10 \
+ task.env.enableCameraSensors=True \
+ task.env.enableDebugVis=False \
+ task.env.maxEpisodeLength=100000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$2 \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=4 \
+ task.env.logging.numStepsPerSave=50 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.1 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1.57 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=0.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=2.0 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=2.0 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.5 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.5 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.5 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1.0 \
+ task.initRandOpt.randDroneOptions.throttle_max=0.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+}
+
+ulimit -n 65535
+
+cd ../../../../../
+
+run_out=$(run $1 $2)
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 25
+
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs \
+ --only_traj_combine \
+ --vel_max_cmap 20
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_no_cam_splits.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_no_cam_splits.sh
new file mode 100755
index 000000000..0d3c59b47
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_no_cam_splits.sh
@@ -0,0 +1,50 @@
+if [ "$#" -ne 1 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint"
+ echo "Example: ./test_no_cam_splits.sh CHECKPOINT_PATH"
+ exit 1
+fi
+
+cd ../../../../../
+
+ts=$(date +"%Y%m%d%H%M%S")
+exp_name="${ts}_test_splits"
+
+run_out=$(
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=1 \
+ task.assetName=splits \
+ task.env.appendWpDist=0 \
+ task.env.disableGround=True \
+ task.env.enableCameraSensors=True \
+ task.env.maxEpisodeLength=1000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$exp_name \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=1000 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 10
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_no_cam_turns.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_no_cam_turns.sh
new file mode 100755
index 000000000..88180ae01
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test/test_no_cam_turns.sh
@@ -0,0 +1,50 @@
+if [ "$#" -ne 1 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: checkpoint"
+ echo "Example: ./test_no_cam_turns.sh CHECKPOINT_PATH"
+ exit 1
+fi
+
+cd ../../../../../
+
+ts=$(date +"%Y%m%d%H%M%S")
+exp_name="${ts}_test_turns"
+
+run_out=$(
+ python train.py task=DRAsset \
+ test=True \
+ num_envs=1 \
+ task.assetName=turns \
+ task.env.appendWpDist=0 \
+ task.env.disableGround=True \
+ task.env.enableCameraSensors=True \
+ task.env.maxEpisodeLength=1000 \
+ task.env.logging.enable=True \
+ task.env.logging.experimentName=$exp_name \
+ task.env.logging.logMainCam=True \
+ task.env.logging.logExtraCams=True \
+ task.env.logging.maxNumEpisodes=1 \
+ task.env.logging.numStepsPerSave=1000 \
+ task.droneSim.drone_asset_options.disable_visuals=True \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ checkpoint=$1
+)
+
+ulimit -n 65535
+
+# extract SH_LOG_DIR
+log_dir=$(echo "$run_out" | grep 'SH_IO_LOG_DIR:' | cut -d':' -f2- | xargs)
+exp_dir=$(dirname $log_dir)
+
+cd tasks/drone_racing/demos/
+
+# process logs, currently it requires logging also images
+python process_logs.py \
+ --exp_dir $exp_dir \
+ --pcd_update_itv 10
+
+# rerun experiment
+python rerun_exp.py \
+ --exp_dir $exp_dir \
+ --combine_envs
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_default_no_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_default_no_cam.sh
new file mode 100755
index 000000000..3326724a5
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_default_no_cam.sh
@@ -0,0 +1,37 @@
+run() {
+ python train.py task=DRRandom \
+ headless=True \
+ max_iterations=6 \
+ num_envs=$1 \
+ train.params.config.horizon_length=$2 \
+ train.params.config.minibatch_size=$3 \
+ task.env.obsImgMode=empty \
+ task.env.enableCameraSensors=False \
+ task.env.numObservations=56
+}
+
+cd ../../../../../
+
+run 1 50 10
+echo "finished: random default, 1, no cam, vram=880"
+
+run 512 50 5120
+echo "finished: random default, 512, no cam, vram=1272"
+
+run 1024 50 10240
+echo "finished: random default, 1024, no cam, vram=1732"
+
+run 2048 50 20480
+echo "finished: random default, 2048, no cam, vram=2368"
+
+run 4096 50 40960
+echo "finished: random default, 4096, no cam, vram=3822"
+
+run 8192 50 81920
+echo "finished: random default, 8192, no cam, vram=6710"
+
+run 16384 50 163840
+echo "finished: random default, 16384, no cam, vram=12356"
+
+run 24576 50 245760
+echo "finished: random default, 24576, no cam, vram=17554"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_default_with_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_default_with_cam.sh
new file mode 100755
index 000000000..66a3c6296
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_default_with_cam.sh
@@ -0,0 +1,37 @@
+run() {
+ python train.py task=DRRandom \
+ headless=False \
+ max_iterations=6 \
+ num_envs=$1 \
+ train.params.config.horizon_length=$2 \
+ train.params.config.minibatch_size=$3 \
+ task.env.obsImgMode=empty \
+ task.env.enableCameraSensors=True \
+ task.env.numObservations=56
+}
+
+cd ../../../../../
+
+run 1 50 10
+echo "finished: random default, 1, cam, vram=1438"
+
+run 200 50 2000
+echo "finished: random default, 200, cam, vram=4246"
+
+run 400 50 4000
+echo "finished: random default, 400, cam, vram=7058"
+
+run 600 50 6000
+echo "finished: random default, 600, cam, vram=9888"
+
+run 800 50 8000
+echo "finished: random default, 800, cam, vram=12628"
+
+run 1000 50 10000
+echo "finished: random default, 1000, cam, vram=15513"
+
+run 1200 50 12000
+echo "finished: random default, 1200, cam, vram=18298"
+
+run 1400 50 14000
+echo "finished: random default, 1400, cam, vram=21043"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_no_obstacle_no_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_no_obstacle_no_cam.sh
new file mode 100755
index 000000000..36779ec56
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_no_obstacle_no_cam.sh
@@ -0,0 +1,56 @@
+run() {
+ python train.py task=DRRandom \
+ num_envs=$1 \
+ max_iterations=$2 \
+ train.params.config.horizon_length=$3 \
+ train.params.config.minibatch_size=$4 \
+ headless=$5 \
+ wandb_activate=$6 \
+ task.disableObstacleManager=$7 \
+ task.env.enableDebugVis=$8 \
+ task.env.numObservations=56 \
+ task.env.obsImgMode=empty \
+ task.env.enableCameraSensors=False \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=0 \
+ task.envCreator.num_tree_assets=0 \
+ task.envCreator.num_wall_actors=0 \
+ task.envCreator.num_wall_assets=0
+}
+
+cd ../../../../../
+
+run 1 6 50 10 True False False False
+echo "finished: random no obstacle, 1, no cam, vram=880"
+
+run 512 6 50 5120 True False False False
+echo "finished: random no obstacle, 512, no cam, vram=1204"
+
+run 1024 6 50 10240 True False False False
+echo "finished: random no obstacle, 1024, no cam, vram=1466"
+
+run 2048 6 50 20480 True False False False
+echo "finished: random no obstacle, 2048, no cam, vram=2106"
+
+run 4096 6 50 40960 True False False False
+echo "finished: random no obstacle, 4096, no cam, vram=3272"
+
+run 8192 6 50 81920 True False False False
+echo "finished: random no obstacle, 8192, no cam, vram=5498"
+
+run 16384 6 50 163840 True False False False
+echo "finished: random no obstacle, 16384, no cam, vram=9990"
+
+run 24576 6 50 245760 True False False False
+echo "finished: random no obstacle, 24576, no cam, vram=14382"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_no_obstacle_with_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_no_obstacle_with_cam.sh
new file mode 100755
index 000000000..8c1ac2162
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_rand_no_obstacle_with_cam.sh
@@ -0,0 +1,56 @@
+run() {
+ python train.py task=DRRandom \
+ num_envs=$1 \
+ max_iterations=$2 \
+ train.params.config.horizon_length=$3 \
+ train.params.config.minibatch_size=$4 \
+ headless=$5 \
+ wandb_activate=$6 \
+ task.disableObstacleManager=$7 \
+ task.env.enableDebugVis=$8 \
+ task.env.numObservations=56 \
+ task.env.obsImgMode=empty \
+ task.env.enableCameraSensors=True \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=0 \
+ task.envCreator.num_tree_assets=0 \
+ task.envCreator.num_wall_actors=0 \
+ task.envCreator.num_wall_assets=0
+}
+
+cd ../../../../../
+
+run 1 6 50 10 False False False False
+echo "finished: random no obstacle, 1, cam, vram=1435"
+
+run 200 6 50 2000 False False False False
+echo "finished: random no obstacle, 200, cam, vram=4171"
+
+run 400 6 50 4000 False False False False
+echo "finished: random no obstacle, 400, cam, vram=6975"
+
+run 600 6 50 6000 False False False False
+echo "finished: random no obstacle, 600, cam, vram=9726"
+
+run 800 6 50 8000 False False False False
+echo "finished: random no obstacle, 800, cam, vram=12467"
+
+run 1000 6 50 10000 False False False False
+echo "finished: random no obstacle, 1000, cam, vram=15220"
+
+run 1200 6 50 12000 False False False False
+echo "finished: random no obstacle, 1200, cam, vram=17973"
+
+run 1400 6 50 14000 False False False False
+echo "finished: random no obstacle, 1400, cam, vram=20782"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_splits_no_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_splits_no_cam.sh
new file mode 100755
index 000000000..27cdd7a56
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_splits_no_cam.sh
@@ -0,0 +1,34 @@
+run() {
+ python train.py task=DRAsset \
+ headless=True \
+ max_iterations=6 \
+ num_envs=$1 \
+ train.params.config.horizon_length=$2 \
+ train.params.config.minibatch_size=$3
+}
+
+cd ../../../../../
+
+run 1 50 10
+echo "finished: splits, 1, no cam, vram=880"
+
+run 512 50 5120
+echo "finished: splits, 512, no cam, vram=1204"
+
+run 1024 50 10240
+echo "finished: splits, 1024, no cam, vram=1528"
+
+run 2048 50 20480
+echo "finished: splits, 2048, no cam, vram=2168"
+
+run 4096 50 40960
+echo "finished: splits, 4096, no cam, vram=3432"
+
+run 8192 50 81920
+echo "finished: splits, 8192, no cam, vram=5940"
+
+run 16384 50 163840
+echo "finished: splits, 16384, no cam, vram=10960"
+
+run 24576 50 245760
+echo "finished: splits, 24576, no cam, vram=16104"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_splits_with_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_splits_with_cam.sh
new file mode 100755
index 000000000..8d7017654
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/test_sim_perf/test_perf_splits_with_cam.sh
@@ -0,0 +1,35 @@
+run() {
+ python train.py task=DRAsset \
+ headless=False \
+ max_iterations=6 \
+ num_envs=$1 \
+ train.params.config.horizon_length=$2 \
+ train.params.config.minibatch_size=$3 \
+ task.env.enableCameraSensors=True
+}
+
+cd ../../../../../
+
+run 1 50 10
+echo "finished: splits, 1, cam, vram=1435"
+
+run 200 50 2000
+echo "finished: splits, 200, cam, vram=4238"
+
+run 400 50 4000
+echo "finished: splits, 400, cam, vram=6982"
+
+run 600 50 6000
+echo "finished: splits, 600, cam, vram=9799"
+
+run 800 50 8000
+echo "finished: splits, 800, cam, vram=12543"
+
+run 1000 50 10000
+echo "finished: splits, 1000, cam, vram=15302"
+
+run 1200 50 12000
+echo "finished: splits, 1200, cam, vram=18182"
+
+run 1400 50 14000
+echo "finished: splits, 1400, cam, vram=20926"
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_dr.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_dr.sh
new file mode 100755
index 000000000..b5f48b9ce
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_dr.sh
@@ -0,0 +1,77 @@
+if [ "$#" -ne 2 ] && [ "$#" -ne 3 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: wandb max_iter [checkpoint]"
+ echo "Example: ./train_rand_dr.sh True 150"
+ exit 1
+fi
+
+cd ../../../../../
+
+python train.py task=DRRandom \
+ headless=False \
+ wandb_activate=$1 \
+ max_iterations=$2 \
+ num_envs=512 \
+ task.droneSim.drone_asset_options.disable_visuals=False \
+ task.env.enableDebugVis=False \
+ task.env.logging.enable=False \
+ task.env.maxEpisodeLength=150 \
+ task.env.enableStrictCollision=True \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=4 \
+ task.envCreator.num_tree_assets=4 \
+ task.envCreator.num_wall_actors=12 \
+ task.envCreator.num_wall_assets=12 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.25 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=1 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=1 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=1 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=1 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=1 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=1 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.2 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.2 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.2 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=-0.5 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=-1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1.4 \
+ task.initRandOpt.randObstacleOptions.orbit_density=0 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=0.67 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5 \
+ train.params.algo.name=dr_continuous \
+ train.params.config.horizon_length=1024 \
+ train.params.config.minibatch_size=32768
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_naive.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_naive.sh
new file mode 100755
index 000000000..a206be7df
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_naive.sh
@@ -0,0 +1,77 @@
+if [ "$#" -ne 2 ] && [ "$#" -ne 3 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: wandb max_iter [checkpoint]"
+ echo "Example: ./train_rand_naive.sh True 150"
+ exit 1
+fi
+
+cd ../../../../../
+
+python train.py task=DRRandom \
+ headless=False \
+ wandb_activate=$1 \
+ max_iterations=$2 \
+ num_envs=512 \
+ task.droneSim.drone_asset_options.disable_visuals=False \
+ task.env.enableDebugVis=True \
+ task.env.logging.enable=False \
+ task.env.maxEpisodeLength=150 \
+ task.env.enableStrictCollision=True \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=4 \
+ task.envCreator.num_tree_assets=4 \
+ task.envCreator.num_wall_actors=12 \
+ task.envCreator.num_wall_assets=12 \
+ task.initRandOpt.randDroneOptions.dist_along_line_max=0.25 \
+ task.initRandOpt.randDroneOptions.drone_rotation_x_max=1 \
+ task.initRandOpt.randDroneOptions.dist_to_line_max=2.0 \
+ task.initRandOpt.randDroneOptions.lin_vel_x_max=1 \
+ task.initRandOpt.randDroneOptions.lin_vel_y_max=1 \
+ task.initRandOpt.randDroneOptions.lin_vel_z_max=1 \
+ task.initRandOpt.randDroneOptions.ang_vel_x_max=1 \
+ task.initRandOpt.randDroneOptions.ang_vel_y_max=1 \
+ task.initRandOpt.randDroneOptions.ang_vel_z_max=1 \
+ task.initRandOpt.randDroneOptions.aileron_max=0.2 \
+ task.initRandOpt.randDroneOptions.elevator_max=0.2 \
+ task.initRandOpt.randDroneOptions.rudder_max=0.2 \
+ task.initRandOpt.randDroneOptions.throttle_min=-1 \
+ task.initRandOpt.randDroneOptions.throttle_max=-0.5 \
+ task.initRandOpt.randCameraOptions.d_x_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_y_max=0 \
+ task.initRandOpt.randCameraOptions.d_z_max=0.01 \
+ task.initRandOpt.randCameraOptions.d_angle_max=5 \
+ task.initRandOpt.randWaypointOptions.wp_size_min=1.4 \
+ task.initRandOpt.randWaypointOptions.wp_size_max=2.0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.2 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=0.3 \
+ task.initRandOpt.randWaypointOptions.theta_max=0.3 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.2 \
+ task.initRandOpt.randWaypointOptions.r_min=6 \
+ task.initRandOpt.randWaypointOptions.r_max=18 \
+ task.initRandOpt.randWaypointOptions.force_gate_flag=-1 \
+ task.initRandOpt.randWaypointOptions.same_track=0 \
+ task.initRandOpt.randObstacleOptions.extra_clearance=1.4 \
+ task.initRandOpt.randObstacleOptions.orbit_density=0 \
+ task.initRandOpt.randObstacleOptions.tree_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_density=1 \
+ task.initRandOpt.randObstacleOptions.wall_dist_scale=0.67 \
+ task.initRandOpt.randObstacleOptions.std_dev_scale=1 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_min=2 \
+ task.initRandOpt.randObstacleOptions.gnd_distance_max=5 \
+ train.params.algo.name=a2c_continuous \
+ train.params.config.horizon_length=1024 \
+ train.params.config.minibatch_size=32768
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_no_obstacle_no_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_no_obstacle_no_cam.sh
new file mode 100755
index 000000000..aa0e0be48
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_rand_no_obstacle_no_cam.sh
@@ -0,0 +1,51 @@
+# make sure in virtual env
+
+if [ "$#" -ne 3 ] && [ "$#" -ne 4 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: headless wandb max_iter [checkpoint]"
+ echo "Example: ./train_rand_no_obstacle_no_cam.sh True True 150"
+ exit 1
+fi
+
+cd ../../../../../
+
+python train.py task=DRRandom \
+ num_envs=16384 \
+ headless=$1 \
+ wandb_activate=$2 \
+ max_iterations=$3 \
+ task.disableObstacleManager=False \
+ task.env.numObservations=56 \
+ task.env.obsImgMode=empty \
+ task.env.enableCameraSensors=False \
+ task.env.enableDebugVis=False \
+ task.envCreator.num_box_actors=0 \
+ task.envCreator.num_box_assets=0 \
+ task.envCreator.num_capsule_actors=0 \
+ task.envCreator.num_capsule_assets=0 \
+ task.envCreator.num_cuboid_wireframe_actors=0 \
+ task.envCreator.num_cuboid_wireframe_assets=0 \
+ task.envCreator.num_cylinder_actors=0 \
+ task.envCreator.num_cylinder_assets=0 \
+ task.envCreator.num_hollow_cuboid_actors=0 \
+ task.envCreator.num_hollow_cuboid_assets=0 \
+ task.envCreator.num_sphere_actors=0 \
+ task.envCreator.num_sphere_assets=0 \
+ task.envCreator.num_tree_actors=0 \
+ task.envCreator.num_tree_assets=0 \
+ task.envCreator.num_wall_actors=0 \
+ task.envCreator.num_wall_assets=0 \
+ task.initRandOpt.randWaypointOptions.init_roll_max=0.5 \
+ task.initRandOpt.randWaypointOptions.init_pitch_max=0.5 \
+ task.initRandOpt.randWaypointOptions.init_yaw_max=3.14 \
+ task.initRandOpt.randWaypointOptions.psi_max=1.57 \
+ task.initRandOpt.randWaypointOptions.theta_max=1.57 \
+ task.initRandOpt.randWaypointOptions.alpha_max=3.14 \
+ task.initRandOpt.randWaypointOptions.gamma_max=0.5 \
+ task.initRandOpt.randWaypointOptions.r_min=2.0 \
+ task.initRandOpt.randWaypointOptions.r_max=18.0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ train.params.config.horizon_length=100 \
+ train.params.config.minibatch_size=102400 \
+ checkpoint=$4
diff --git a/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_splits_no_cam.sh b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_splits_no_cam.sh
new file mode 100755
index 000000000..fec7e424e
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/sh/train/train_splits_no_cam.sh
@@ -0,0 +1,25 @@
+# make sure in virtual env
+
+if [ "$#" -ne 4 ] && [ "$#" -ne 5 ]; then
+ echo "Error: incorrect arg count"
+ echo "Require: headless wandb max_iter episode_len [checkpoint]"
+ echo "Example: ./train_splits_no_cam.sh True True 300 175"
+ exit 1
+fi
+
+cd ../../../../../
+
+python train.py task=DRAsset \
+ headless=$1 \
+ wandb_activate=$2 \
+ max_iterations=$3 \
+ num_envs=16384 \
+ task.assetName=splits \
+ task.env.maxEpisodeLength=$4 \
+ task.env.appendWpDist=0 \
+ task.mdp.reward.k_guidance=0 \
+ train.params.network.mlp.units="[256, 128, 128, 64]" \
+ train.params.config.normalize_input=False \
+ train.params.config.horizon_length=50 \
+ train.params.config.minibatch_size=51200 \
+ checkpoint=$5
diff --git a/isaacgymenvs/tasks/drone_racing/demos/spawn_collision.py b/isaacgymenvs/tasks/drone_racing/demos/spawn_collision.py
new file mode 100644
index 000000000..2cfb1ada4
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/spawn_collision.py
@@ -0,0 +1,59 @@
+from isaacgym import gymapi, gymtorch
+from isaacgymenvs.tasks.drone_racing.assets import (
+ create_drone_quadcopter,
+ DroneQuadcopterOptions,
+)
+
+sim_params = gymapi.SimParams()
+sim_params.use_gpu_pipeline = True
+sim_params.physx.use_gpu = True
+sim_params.physx.contact_collection = gymapi.CC_LAST_SUBSTEP
+sim_params.physx.max_depenetration_velocity = 0.001 # THIS PARAM IS IMPORTANT
+sim_params.up_axis = gymapi.UP_AXIS_Z
+sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
+sim_params.dt = 1 / 60
+plane_params = gymapi.PlaneParams()
+plane_params.normal = gymapi.Vec3(0, 0, 1)
+
+gym = gymapi.acquire_gym()
+sim = gym.create_sim(0, 0, gymapi.SIM_PHYSX, sim_params)
+gym.add_ground(sim, plane_params)
+env = gym.create_env(sim, gymapi.Vec3(-1, -1, 0), gymapi.Vec3(1, 1, 2), 0)
+
+spawn_tf = gymapi.Transform()
+
+spawn_tf.p = gymapi.Vec3(0.1, 0.1, 2.5)
+drone_asset = create_drone_quadcopter(gym, sim, DroneQuadcopterOptions())
+drone_actor = gym.create_actor(env, drone_asset, spawn_tf, "drone")
+
+spawn_tf.p = gymapi.Vec3(0.0, 0.0, 1.0)
+box_asset_opts = gymapi.AssetOptions()
+box_asset_opts.fix_base_link = True
+box_asset = gym.create_box(sim, 0.2, 0.2, 0.2, box_asset_opts)
+box_actor_0 = gym.create_actor(env, box_asset, spawn_tf, "box_0")
+
+spawn_tf.p = gymapi.Vec3(0.0, 0.0, 2.5)
+box_actor_1 = gym.create_actor(env, box_asset, spawn_tf, "box_1")
+
+spawn_tf.p = gymapi.Vec3(0.0, 0.9, 1.75)
+box_actor_2 = gym.create_actor(env, box_asset, spawn_tf, "box_2")
+
+contact_force = gymtorch.wrap_tensor(gym.acquire_net_contact_force_tensor(sim))
+
+gym.prepare_sim(sim)
+viewer = gym.create_viewer(sim, gymapi.CameraProperties())
+gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_SPACE, "step")
+gym.refresh_net_contact_force_tensor(sim)
+print(contact_force[0])
+
+while not gym.query_viewer_has_closed(viewer):
+ for evt in gym.query_viewer_action_events(viewer):
+ if evt.action == "step" and evt.value > 0:
+ gym.simulate(sim)
+ gym.fetch_results(sim, True)
+ gym.refresh_net_contact_force_tensor(sim)
+ print(contact_force[0])
+ gym.step_graphics(sim)
+
+ gym.draw_viewer(viewer, sim, True)
+ gym.sync_frame_time(sim)
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_ep_len.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_ep_len.csv
new file mode 100644
index 000000000..11511eed9
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_ep_len.csv
@@ -0,0 +1,1001 @@
+"global_step","DRRandom_04-01-36-40 - _step","DRRandom_04-01-36-40 - _step__MIN","DRRandom_04-01-36-40 - _step__MAX","DRRandom_04-01-36-40 - episode_lengths/step","DRRandom_04-01-36-40 - episode_lengths/step__MIN","DRRandom_04-01-36-40 - episode_lengths/step__MAX"
+"192","3","3","3","43.4499397277832","43.4499397277832","43.4499397277832"
+"524288","7","7","7","45.483154296875","45.483154296875","45.483154296875"
+"1048576","11","11","11","45.29814910888672","45.29814910888672","45.29814910888672"
+"1572864","15","15","15","41.103397369384766","41.103397369384766","41.103397369384766"
+"2097152","19","19","19","43.5052375793457","43.5052375793457","43.5052375793457"
+"2621440","23","23","23","42.19295883178711","42.19295883178711","42.19295883178711"
+"3145728","27","27","27","43.08821105957031","43.08821105957031","43.08821105957031"
+"3670016","31","31","31","40.21171188354492","40.21171188354492","40.21171188354492"
+"4194304","35","35","35","40.4779052734375","40.4779052734375","40.4779052734375"
+"4718592","39","39","39","39.081050872802734","39.081050872802734","39.081050872802734"
+"5242880","43","43","43","39.584983825683594","39.584983825683594","39.584983825683594"
+"5767168","47","47","47","37.40217971801758","37.40217971801758","37.40217971801758"
+"6291456","51","51","51","38.10734939575195","38.10734939575195","38.10734939575195"
+"6815744","55","55","55","36.64460754394531","36.64460754394531","36.64460754394531"
+"7340032","59","59","59","37.84260559082031","37.84260559082031","37.84260559082031"
+"7864320","63","63","63","39.43553161621094","39.43553161621094","39.43553161621094"
+"8388608","67","67","67","35.55320739746094","35.55320739746094","35.55320739746094"
+"8912896","71","71","71","39.94304275512695","39.94304275512695","39.94304275512695"
+"9437184","75","75","75","34.57059860229492","34.57059860229492","34.57059860229492"
+"9961472","79","79","79","35.41394805908203","35.41394805908203","35.41394805908203"
+"10485760","83","83","83","37.0859375","37.0859375","37.0859375"
+"11010048","87","87","87","37.828941345214844","37.828941345214844","37.828941345214844"
+"11534336","91","91","91","39.102596282958984","39.102596282958984","39.102596282958984"
+"12058624","95","95","95","39.06523895263672","39.06523895263672","39.06523895263672"
+"12582912","99","99","99","39.1135139465332","39.1135139465332","39.1135139465332"
+"13107200","103","103","103","40.40180206298828","40.40180206298828","40.40180206298828"
+"13631488","107","107","107","37.428871154785156","37.428871154785156","37.428871154785156"
+"14155776","111","111","111","34.34697723388672","34.34697723388672","34.34697723388672"
+"14680064","115","115","115","40.62482452392578","40.62482452392578","40.62482452392578"
+"15204352","119","119","119","40.26600646972656","40.26600646972656","40.26600646972656"
+"15728640","123","123","123","39.95928955078125","39.95928955078125","39.95928955078125"
+"16252928","127","127","127","37.63462829589844","37.63462829589844","37.63462829589844"
+"16777216","131","131","131","43.024871826171875","43.024871826171875","43.024871826171875"
+"17301504","135","135","135","41.51262664794922","41.51262664794922","41.51262664794922"
+"17825792","139","139","139","39.45404052734375","39.45404052734375","39.45404052734375"
+"18350080","143","143","143","48.165077209472656","48.165077209472656","48.165077209472656"
+"18874368","147","147","147","41.20634841918945","41.20634841918945","41.20634841918945"
+"19398656","151","151","151","37.80315017700195","37.80315017700195","37.80315017700195"
+"19922944","155","155","155","41.934226989746094","41.934226989746094","41.934226989746094"
+"20447232","159","159","159","41.63703918457031","41.63703918457031","41.63703918457031"
+"20971520","163","163","163","43.69829559326172","43.69829559326172","43.69829559326172"
+"21495808","167","167","167","39.78866195678711","39.78866195678711","39.78866195678711"
+"22020096","171","171","171","39.739749908447266","39.739749908447266","39.739749908447266"
+"22544384","175","175","175","39.892539978027344","39.892539978027344","39.892539978027344"
+"23068672","179","179","179","42.44145584106445","42.44145584106445","42.44145584106445"
+"23592960","183","183","183","45.51706314086914","45.51706314086914","45.51706314086914"
+"24117248","187","187","187","43.85375213623047","43.85375213623047","43.85375213623047"
+"24641536","191","191","191","40.96393585205078","40.96393585205078","40.96393585205078"
+"25165824","195","195","195","43.26435089111328","43.26435089111328","43.26435089111328"
+"25690112","199","199","199","41.88546371459961","41.88546371459961","41.88546371459961"
+"26214400","203","203","203","43.621185302734375","43.621185302734375","43.621185302734375"
+"26738688","207","207","207","43.60862350463867","43.60862350463867","43.60862350463867"
+"27262976","211","211","211","40.79332733154297","40.79332733154297","40.79332733154297"
+"27787264","215","215","215","48.20433807373047","48.20433807373047","48.20433807373047"
+"28311552","219","219","219","48.09791946411133","48.09791946411133","48.09791946411133"
+"28835840","223","223","223","51.86074447631836","51.86074447631836","51.86074447631836"
+"29360128","227","227","227","47.57075881958008","47.57075881958008","47.57075881958008"
+"29884416","231","231","231","46.45737838745117","46.45737838745117","46.45737838745117"
+"30408704","235","235","235","48.43655014038086","48.43655014038086","48.43655014038086"
+"30932992","239","239","239","42.68674087524414","42.68674087524414","42.68674087524414"
+"31457280","243","243","243","44.65381622314453","44.65381622314453","44.65381622314453"
+"31981568","247","247","247","45.976776123046875","45.976776123046875","45.976776123046875"
+"32505856","251","251","251","44.68500900268555","44.68500900268555","44.68500900268555"
+"33030144","255","255","255","44.84095764160156","44.84095764160156","44.84095764160156"
+"33554432","259","259","259","52.25755310058594","52.25755310058594","52.25755310058594"
+"34078720","263","263","263","45.9136848449707","45.9136848449707","45.9136848449707"
+"34603008","267","267","267","49.57923126220703","49.57923126220703","49.57923126220703"
+"35127296","271","271","271","54.99345016479492","54.99345016479492","54.99345016479492"
+"35651584","275","275","275","49.78350830078125","49.78350830078125","49.78350830078125"
+"36175872","279","279","279","52.56602478027344","52.56602478027344","52.56602478027344"
+"36700160","283","283","283","52.53903579711914","52.53903579711914","52.53903579711914"
+"37224448","287","287","287","50.38129806518555","50.38129806518555","50.38129806518555"
+"37748736","291","291","291","52.41360855102539","52.41360855102539","52.41360855102539"
+"38273024","295","295","295","49.79691696166992","49.79691696166992","49.79691696166992"
+"38797312","299","299","299","48.78662872314453","48.78662872314453","48.78662872314453"
+"39321600","303","303","303","54.74250030517578","54.74250030517578","54.74250030517578"
+"39845888","307","307","307","48.90058517456055","48.90058517456055","48.90058517456055"
+"40370176","311","311","311","49.60651779174805","49.60651779174805","49.60651779174805"
+"40894464","315","315","315","50.28068923950195","50.28068923950195","50.28068923950195"
+"41418752","319","319","319","55.13523483276367","55.13523483276367","55.13523483276367"
+"41943040","323","323","323","52.04958724975586","52.04958724975586","52.04958724975586"
+"42467328","327","327","327","50.312400817871094","50.312400817871094","50.312400817871094"
+"42991616","331","331","331","48.82675552368164","48.82675552368164","48.82675552368164"
+"43515904","335","335","335","51.04666519165039","51.04666519165039","51.04666519165039"
+"44040192","339","339","339","50.15492248535156","50.15492248535156","50.15492248535156"
+"44564480","343","343","343","52.23554992675781","52.23554992675781","52.23554992675781"
+"45088768","347","347","347","53.78116226196289","53.78116226196289","53.78116226196289"
+"45613056","351","351","351","54.53083038330078","54.53083038330078","54.53083038330078"
+"46137344","355","355","355","49.202816009521484","49.202816009521484","49.202816009521484"
+"46661632","359","359","359","53.60148239135742","53.60148239135742","53.60148239135742"
+"47185920","363","363","363","49.87460708618164","49.87460708618164","49.87460708618164"
+"47710208","367","367","367","53.37291717529297","53.37291717529297","53.37291717529297"
+"48234496","371","371","371","54.38157272338867","54.38157272338867","54.38157272338867"
+"48758784","375","375","375","54.55111312866211","54.55111312866211","54.55111312866211"
+"49283072","379","379","379","48.85597229003906","48.85597229003906","48.85597229003906"
+"49807360","383","383","383","52.26070022583008","52.26070022583008","52.26070022583008"
+"50331648","387","387","387","52.214012145996094","52.214012145996094","52.214012145996094"
+"50855936","391","391","391","53.086448669433594","53.086448669433594","53.086448669433594"
+"51380224","395","395","395","48.41831588745117","48.41831588745117","48.41831588745117"
+"51904512","399","399","399","51.18293380737305","51.18293380737305","51.18293380737305"
+"52428800","403","403","403","53.791053771972656","53.791053771972656","53.791053771972656"
+"52953088","407","407","407","54.525814056396484","54.525814056396484","54.525814056396484"
+"53477376","411","411","411","50.544677734375","50.544677734375","50.544677734375"
+"54001664","415","415","415","54.84874725341797","54.84874725341797","54.84874725341797"
+"54525952","419","419","419","54.89931869506836","54.89931869506836","54.89931869506836"
+"55050240","423","423","423","54.574989318847656","54.574989318847656","54.574989318847656"
+"55574528","427","427","427","51.55402374267578","51.55402374267578","51.55402374267578"
+"56098816","431","431","431","54.77630615234375","54.77630615234375","54.77630615234375"
+"56623104","435","435","435","57.78681564331055","57.78681564331055","57.78681564331055"
+"57147392","439","439","439","49.832767486572266","49.832767486572266","49.832767486572266"
+"57671680","443","443","443","53.22044372558594","53.22044372558594","53.22044372558594"
+"58195968","447","447","447","53.11619186401367","53.11619186401367","53.11619186401367"
+"58720256","451","451","451","52.393035888671875","52.393035888671875","52.393035888671875"
+"59244544","455","455","455","50.874290466308594","50.874290466308594","50.874290466308594"
+"59768832","459","459","459","54.114105224609375","54.114105224609375","54.114105224609375"
+"60293120","463","463","463","54.77348327636719","54.77348327636719","54.77348327636719"
+"60817408","467","467","467","52.86288070678711","52.86288070678711","52.86288070678711"
+"61341696","471","471","471","58.070556640625","58.070556640625","58.070556640625"
+"61865984","475","475","475","51.99178695678711","51.99178695678711","51.99178695678711"
+"62390272","479","479","479","55.005828857421875","55.005828857421875","55.005828857421875"
+"62914560","483","483","483","56.59724807739258","56.59724807739258","56.59724807739258"
+"63438848","487","487","487","55.97837448120117","55.97837448120117","55.97837448120117"
+"63963136","491","491","491","56.51508331298828","56.51508331298828","56.51508331298828"
+"64487424","495","495","495","55.45497131347656","55.45497131347656","55.45497131347656"
+"65011712","499","499","499","55.53252410888672","55.53252410888672","55.53252410888672"
+"65536000","503","503","503","52.83785629272461","52.83785629272461","52.83785629272461"
+"66060288","507","507","507","55.69106674194336","55.69106674194336","55.69106674194336"
+"66584576","511","511","511","57.108924865722656","57.108924865722656","57.108924865722656"
+"67108864","515","515","515","56.27996063232422","56.27996063232422","56.27996063232422"
+"67633152","519","519","519","50.38329315185547","50.38329315185547","50.38329315185547"
+"68157440","523","523","523","53.37443542480469","53.37443542480469","53.37443542480469"
+"68681728","527","527","527","53.980995178222656","53.980995178222656","53.980995178222656"
+"69206016","531","531","531","56.79262161254883","56.79262161254883","56.79262161254883"
+"69730304","535","535","535","56.793968200683594","56.793968200683594","56.793968200683594"
+"70254592","539","539","539","51.54168701171875","51.54168701171875","51.54168701171875"
+"70778880","543","543","543","55.052005767822266","55.052005767822266","55.052005767822266"
+"71303168","547","547","547","58.09518051147461","58.09518051147461","58.09518051147461"
+"71827456","551","551","551","57.20201110839844","57.20201110839844","57.20201110839844"
+"72351744","555","555","555","53.86937713623047","53.86937713623047","53.86937713623047"
+"72876032","559","559","559","55.11094665527344","55.11094665527344","55.11094665527344"
+"73400320","563","563","563","58.43466567993164","58.43466567993164","58.43466567993164"
+"73924608","567","567","567","54.82294464111328","54.82294464111328","54.82294464111328"
+"74448896","571","571","571","56.447601318359375","56.447601318359375","56.447601318359375"
+"74973184","575","575","575","52.176692962646484","52.176692962646484","52.176692962646484"
+"75497472","579","579","579","53.669734954833984","53.669734954833984","53.669734954833984"
+"76021760","583","583","583","57.25029754638672","57.25029754638672","57.25029754638672"
+"76546048","587","587","587","56.82904052734375","56.82904052734375","56.82904052734375"
+"77070336","591","591","591","56.542327880859375","56.542327880859375","56.542327880859375"
+"77594624","595","595","595","54.76693344116211","54.76693344116211","54.76693344116211"
+"78118912","599","599","599","58.120906829833984","58.120906829833984","58.120906829833984"
+"78643200","603","603","603","55.33457565307617","55.33457565307617","55.33457565307617"
+"79167488","607","607","607","55.98371124267578","55.98371124267578","55.98371124267578"
+"79691776","611","611","611","51.96614074707031","51.96614074707031","51.96614074707031"
+"80216064","615","615","615","54.28235626220703","54.28235626220703","54.28235626220703"
+"80740352","619","619","619","54.47388458251953","54.47388458251953","54.47388458251953"
+"81264640","623","623","623","53.836219787597656","53.836219787597656","53.836219787597656"
+"81788928","627","627","627","56.942440032958984","56.942440032958984","56.942440032958984"
+"82313216","631","631","631","54.83799743652344","54.83799743652344","54.83799743652344"
+"82837504","635","635","635","53.21935272216797","53.21935272216797","53.21935272216797"
+"83361792","639","639","639","54.1475830078125","54.1475830078125","54.1475830078125"
+"83886080","643","643","643","54.92839813232422","54.92839813232422","54.92839813232422"
+"84410368","647","647","647","56.135379791259766","56.135379791259766","56.135379791259766"
+"84934656","651","651","651","56.627586364746094","56.627586364746094","56.627586364746094"
+"85458944","655","655","655","55.115970611572266","55.115970611572266","55.115970611572266"
+"85983232","659","659","659","57.38220977783203","57.38220977783203","57.38220977783203"
+"86507520","663","663","663","58.321556091308594","58.321556091308594","58.321556091308594"
+"87031808","667","667","667","54.38328552246094","54.38328552246094","54.38328552246094"
+"87556096","671","671","671","57.26757049560547","57.26757049560547","57.26757049560547"
+"88080384","675","675","675","58.428226470947266","58.428226470947266","58.428226470947266"
+"88604672","679","679","679","55.54804611206055","55.54804611206055","55.54804611206055"
+"89128960","683","683","683","59.37060546875","59.37060546875","59.37060546875"
+"89653248","687","687","687","55.74885559082031","55.74885559082031","55.74885559082031"
+"90177536","691","691","691","57.22025680541992","57.22025680541992","57.22025680541992"
+"90701824","695","695","695","54.36190414428711","54.36190414428711","54.36190414428711"
+"91226112","699","699","699","54.134334564208984","54.134334564208984","54.134334564208984"
+"91750400","703","703","703","56.25709533691406","56.25709533691406","56.25709533691406"
+"92274688","707","707","707","53.76372528076172","53.76372528076172","53.76372528076172"
+"92798976","711","711","711","54.76603317260742","54.76603317260742","54.76603317260742"
+"93323264","715","715","715","55.756996154785156","55.756996154785156","55.756996154785156"
+"93847552","719","719","719","53.044212341308594","53.044212341308594","53.044212341308594"
+"94371840","723","723","723","51.68387222290039","51.68387222290039","51.68387222290039"
+"94896128","727","727","727","54.99467086791992","54.99467086791992","54.99467086791992"
+"95420416","731","731","731","57.56486511230469","57.56486511230469","57.56486511230469"
+"95944704","735","735","735","53.54360580444336","53.54360580444336","53.54360580444336"
+"96468992","739","739","739","53.57935333251953","53.57935333251953","53.57935333251953"
+"96993280","743","743","743","53.70418930053711","53.70418930053711","53.70418930053711"
+"97517568","747","747","747","55.07126998901367","55.07126998901367","55.07126998901367"
+"98041856","751","751","751","53.13759994506836","53.13759994506836","53.13759994506836"
+"98566144","755","755","755","53.9378547668457","53.9378547668457","53.9378547668457"
+"99090432","759","759","759","53.468074798583984","53.468074798583984","53.468074798583984"
+"99614720","763","763","763","56.838924407958984","56.838924407958984","56.838924407958984"
+"100139008","767","767","767","59.38041305541992","59.38041305541992","59.38041305541992"
+"100663296","771","771","771","53.74677658081055","53.74677658081055","53.74677658081055"
+"101187584","775","775","775","57.03127670288086","57.03127670288086","57.03127670288086"
+"101711872","779","779","779","53.97590637207031","53.97590637207031","53.97590637207031"
+"102236160","783","783","783","55.676849365234375","55.676849365234375","55.676849365234375"
+"102760448","787","787","787","53.16404342651367","53.16404342651367","53.16404342651367"
+"103284736","791","791","791","55.40207290649414","55.40207290649414","55.40207290649414"
+"103809024","795","795","795","52.561912536621094","52.561912536621094","52.561912536621094"
+"104333312","799","799","799","52.78872299194336","52.78872299194336","52.78872299194336"
+"104857600","803","803","803","54.947776794433594","54.947776794433594","54.947776794433594"
+"105381888","807","807","807","53.62624740600586","53.62624740600586","53.62624740600586"
+"105906176","811","811","811","55.89345169067383","55.89345169067383","55.89345169067383"
+"106430464","815","815","815","53.0533447265625","53.0533447265625","53.0533447265625"
+"106954752","819","819","819","54.876522064208984","54.876522064208984","54.876522064208984"
+"107479040","823","823","823","56.26941680908203","56.26941680908203","56.26941680908203"
+"108003328","827","827","827","56.65855407714844","56.65855407714844","56.65855407714844"
+"108527616","831","831","831","55.48557662963867","55.48557662963867","55.48557662963867"
+"109051904","835","835","835","59.9107780456543","59.9107780456543","59.9107780456543"
+"109576192","839","839","839","57.12611770629883","57.12611770629883","57.12611770629883"
+"110100480","843","843","843","55.75122833251953","55.75122833251953","55.75122833251953"
+"110624768","847","847","847","55.76258850097656","55.76258850097656","55.76258850097656"
+"111149056","851","851","851","55.871063232421875","55.871063232421875","55.871063232421875"
+"111673344","855","855","855","57.6172981262207","57.6172981262207","57.6172981262207"
+"112197632","859","859","859","57.02699661254883","57.02699661254883","57.02699661254883"
+"112721920","863","863","863","59.99913787841797","59.99913787841797","59.99913787841797"
+"113246208","867","867","867","59.573299407958984","59.573299407958984","59.573299407958984"
+"113770496","871","871","871","54.82742691040039","54.82742691040039","54.82742691040039"
+"114294784","875","875","875","57.50784683227539","57.50784683227539","57.50784683227539"
+"114819072","879","879","879","55.144657135009766","55.144657135009766","55.144657135009766"
+"115343360","883","883","883","56.378265380859375","56.378265380859375","56.378265380859375"
+"115867648","887","887","887","56.95456314086914","56.95456314086914","56.95456314086914"
+"116391936","891","891","891","51.97715759277344","51.97715759277344","51.97715759277344"
+"116916224","895","895","895","53.57731246948242","53.57731246948242","53.57731246948242"
+"117440512","899","899","899","55.30495071411133","55.30495071411133","55.30495071411133"
+"117964800","903","903","903","52.25337600708008","52.25337600708008","52.25337600708008"
+"118489088","907","907","907","59.18804931640625","59.18804931640625","59.18804931640625"
+"119013376","911","911","911","56.05707550048828","56.05707550048828","56.05707550048828"
+"119537664","915","915","915","54.34000778198242","54.34000778198242","54.34000778198242"
+"120061952","919","919","919","55.87764358520508","55.87764358520508","55.87764358520508"
+"120586240","923","923","923","54.617347717285156","54.617347717285156","54.617347717285156"
+"121110528","927","927","927","52.8010139465332","52.8010139465332","52.8010139465332"
+"121634816","931","931","931","55.61173629760742","55.61173629760742","55.61173629760742"
+"122159104","935","935","935","54.61643600463867","54.61643600463867","54.61643600463867"
+"122683392","939","939","939","57.01868438720703","57.01868438720703","57.01868438720703"
+"123207680","943","943","943","59.13240051269531","59.13240051269531","59.13240051269531"
+"123731968","947","947","947","54.81086349487305","54.81086349487305","54.81086349487305"
+"124256256","951","951","951","54.99141311645508","54.99141311645508","54.99141311645508"
+"124780544","955","955","955","56.168739318847656","56.168739318847656","56.168739318847656"
+"125304832","959","959","959","56.21263885498047","56.21263885498047","56.21263885498047"
+"125829120","963","963","963","57.65719985961914","57.65719985961914","57.65719985961914"
+"126353408","967","967","967","54.74425506591797","54.74425506591797","54.74425506591797"
+"126877696","971","971","971","58.40815734863281","58.40815734863281","58.40815734863281"
+"127401984","975","975","975","55.94773483276367","55.94773483276367","55.94773483276367"
+"127926272","979","979","979","51.67703628540039","51.67703628540039","51.67703628540039"
+"128450560","983","983","983","52.1243896484375","52.1243896484375","52.1243896484375"
+"128974848","987","987","987","57.31809997558594","57.31809997558594","57.31809997558594"
+"129499136","991","991","991","54.91078567504883","54.91078567504883","54.91078567504883"
+"130023424","995","995","995","53.02058792114258","53.02058792114258","53.02058792114258"
+"130547712","999","999","999","55.091278076171875","55.091278076171875","55.091278076171875"
+"131072000","1003","1003","1003","56.63490676879883","56.63490676879883","56.63490676879883"
+"131596288","1007","1007","1007","52.30791473388672","52.30791473388672","52.30791473388672"
+"132120576","1011","1011","1011","53.592498779296875","53.592498779296875","53.592498779296875"
+"132644864","1015","1015","1015","51.70012664794922","51.70012664794922","51.70012664794922"
+"133169152","1019","1019","1019","54.7945556640625","54.7945556640625","54.7945556640625"
+"133693440","1023","1023","1023","55.46860885620117","55.46860885620117","55.46860885620117"
+"134217728","1027","1027","1027","51.22406768798828","51.22406768798828","51.22406768798828"
+"134742016","1031","1031","1031","53.825687408447266","53.825687408447266","53.825687408447266"
+"135266304","1035","1035","1035","52.76879119873047","52.76879119873047","52.76879119873047"
+"135790592","1039","1039","1039","55.31688690185547","55.31688690185547","55.31688690185547"
+"136314880","1043","1043","1043","54.36344528198242","54.36344528198242","54.36344528198242"
+"136839168","1047","1047","1047","55.621219635009766","55.621219635009766","55.621219635009766"
+"137363456","1051","1051","1051","55.64823913574219","55.64823913574219","55.64823913574219"
+"137887744","1055","1055","1055","53.90279769897461","53.90279769897461","53.90279769897461"
+"138412032","1059","1059","1059","53.41330337524414","53.41330337524414","53.41330337524414"
+"138936320","1063","1063","1063","52.82585906982422","52.82585906982422","52.82585906982422"
+"139460608","1067","1067","1067","59.7662353515625","59.7662353515625","59.7662353515625"
+"139984896","1071","1071","1071","51.1325569152832","51.1325569152832","51.1325569152832"
+"140509184","1075","1075","1075","55.56426239013672","55.56426239013672","55.56426239013672"
+"141033472","1079","1079","1079","54.46338653564453","54.46338653564453","54.46338653564453"
+"141557760","1083","1083","1083","56.41911315917969","56.41911315917969","56.41911315917969"
+"142082048","1087","1087","1087","56.20288848876953","56.20288848876953","56.20288848876953"
+"142606336","1091","1091","1091","52.34842300415039","52.34842300415039","52.34842300415039"
+"143130624","1095","1095","1095","55.21105194091797","55.21105194091797","55.21105194091797"
+"143654912","1099","1099","1099","55.65037536621094","55.65037536621094","55.65037536621094"
+"144179200","1103","1103","1103","56.759437561035156","56.759437561035156","56.759437561035156"
+"144703488","1107","1107","1107","55.62010192871094","55.62010192871094","55.62010192871094"
+"145227776","1111","1111","1111","54.94300079345703","54.94300079345703","54.94300079345703"
+"145752064","1115","1115","1115","54.28123092651367","54.28123092651367","54.28123092651367"
+"146276352","1119","1119","1119","55.955467224121094","55.955467224121094","55.955467224121094"
+"146800640","1123","1123","1123","53.397274017333984","53.397274017333984","53.397274017333984"
+"147324928","1127","1127","1127","55.27056121826172","55.27056121826172","55.27056121826172"
+"147849216","1131","1131","1131","56.73810577392578","56.73810577392578","56.73810577392578"
+"148373504","1135","1135","1135","54.49154281616211","54.49154281616211","54.49154281616211"
+"148897792","1139","1139","1139","57.10354232788086","57.10354232788086","57.10354232788086"
+"149422080","1143","1143","1143","56.54018783569336","56.54018783569336","56.54018783569336"
+"149946368","1147","1147","1147","53.321800231933594","53.321800231933594","53.321800231933594"
+"150470656","1151","1151","1151","55.55837631225586","55.55837631225586","55.55837631225586"
+"150994944","1155","1155","1155","57.4149169921875","57.4149169921875","57.4149169921875"
+"151519232","1159","1159","1159","54.22358322143555","54.22358322143555","54.22358322143555"
+"152043520","1163","1163","1163","57.54444885253906","57.54444885253906","57.54444885253906"
+"152567808","1167","1167","1167","56.3275032043457","56.3275032043457","56.3275032043457"
+"153092096","1171","1171","1171","55.16183853149414","55.16183853149414","55.16183853149414"
+"153616384","1175","1175","1175","54.02752685546875","54.02752685546875","54.02752685546875"
+"154140672","1179","1179","1179","55.90492630004883","55.90492630004883","55.90492630004883"
+"154664960","1183","1183","1183","58.14524841308594","58.14524841308594","58.14524841308594"
+"155189248","1187","1187","1187","56.4898567199707","56.4898567199707","56.4898567199707"
+"155713536","1191","1191","1191","55.386356353759766","55.386356353759766","55.386356353759766"
+"156237824","1195","1195","1195","56.17142105102539","56.17142105102539","56.17142105102539"
+"156762112","1199","1199","1199","58.23343276977539","58.23343276977539","58.23343276977539"
+"157286400","1203","1203","1203","57.066444396972656","57.066444396972656","57.066444396972656"
+"157810688","1207","1207","1207","55.581199645996094","55.581199645996094","55.581199645996094"
+"158334976","1211","1211","1211","55.29412078857422","55.29412078857422","55.29412078857422"
+"158859264","1215","1215","1215","56.28982925415039","56.28982925415039","56.28982925415039"
+"159383552","1219","1219","1219","57.41342544555664","57.41342544555664","57.41342544555664"
+"159907840","1223","1223","1223","57.22916793823242","57.22916793823242","57.22916793823242"
+"160432128","1227","1227","1227","56.214046478271484","56.214046478271484","56.214046478271484"
+"160956416","1231","1231","1231","57.47529220581055","57.47529220581055","57.47529220581055"
+"161480704","1235","1235","1235","56.708396911621094","56.708396911621094","56.708396911621094"
+"162004992","1239","1239","1239","59.79405212402344","59.79405212402344","59.79405212402344"
+"162529280","1243","1243","1243","60.01500701904297","60.01500701904297","60.01500701904297"
+"163053568","1247","1247","1247","57.734310150146484","57.734310150146484","57.734310150146484"
+"163577856","1251","1251","1251","56.58372497558594","56.58372497558594","56.58372497558594"
+"164102144","1255","1255","1255","56.34893035888672","56.34893035888672","56.34893035888672"
+"164626432","1259","1259","1259","56.84306335449219","56.84306335449219","56.84306335449219"
+"165150720","1263","1263","1263","58.33332061767578","58.33332061767578","58.33332061767578"
+"165675008","1267","1267","1267","55.69057083129883","55.69057083129883","55.69057083129883"
+"166199296","1271","1271","1271","57.53445053100586","57.53445053100586","57.53445053100586"
+"166723584","1275","1275","1275","59.34804153442383","59.34804153442383","59.34804153442383"
+"167247872","1279","1279","1279","58.04621124267578","58.04621124267578","58.04621124267578"
+"167772160","1283","1283","1283","57.69853210449219","57.69853210449219","57.69853210449219"
+"168296448","1287","1287","1287","56.20775604248047","56.20775604248047","56.20775604248047"
+"168820736","1291","1291","1291","55.97829055786133","55.97829055786133","55.97829055786133"
+"169345024","1295","1295","1295","54.89008331298828","54.89008331298828","54.89008331298828"
+"169869312","1299","1299","1299","58.13859558105469","58.13859558105469","58.13859558105469"
+"170393600","1303","1303","1303","54.07334899902344","54.07334899902344","54.07334899902344"
+"170917888","1307","1307","1307","54.647796630859375","54.647796630859375","54.647796630859375"
+"171442176","1311","1311","1311","56.80205535888672","56.80205535888672","56.80205535888672"
+"171966464","1315","1315","1315","59.18836212158203","59.18836212158203","59.18836212158203"
+"172490752","1319","1319","1319","57.78115463256836","57.78115463256836","57.78115463256836"
+"173015040","1323","1323","1323","56.525672912597656","56.525672912597656","56.525672912597656"
+"173539328","1327","1327","1327","54.6531867980957","54.6531867980957","54.6531867980957"
+"174063616","1331","1331","1331","55.537479400634766","55.537479400634766","55.537479400634766"
+"174587904","1335","1335","1335","58.8180046081543","58.8180046081543","58.8180046081543"
+"175112192","1339","1339","1339","57.9908332824707","57.9908332824707","57.9908332824707"
+"175636480","1343","1343","1343","58.155731201171875","58.155731201171875","58.155731201171875"
+"176160768","1347","1347","1347","55.59607696533203","55.59607696533203","55.59607696533203"
+"176685056","1351","1351","1351","56.77947998046875","56.77947998046875","56.77947998046875"
+"177209344","1355","1355","1355","56.60075378417969","56.60075378417969","56.60075378417969"
+"177733632","1359","1359","1359","54.67876434326172","54.67876434326172","54.67876434326172"
+"178257920","1363","1363","1363","58.99138641357422","58.99138641357422","58.99138641357422"
+"178782208","1367","1367","1367","57.414852142333984","57.414852142333984","57.414852142333984"
+"179306496","1371","1371","1371","57.53254699707031","57.53254699707031","57.53254699707031"
+"179830784","1375","1375","1375","55.69622802734375","55.69622802734375","55.69622802734375"
+"180355072","1379","1379","1379","56.8375129699707","56.8375129699707","56.8375129699707"
+"180879360","1383","1383","1383","56.99812316894531","56.99812316894531","56.99812316894531"
+"181403648","1387","1387","1387","61.13040542602539","61.13040542602539","61.13040542602539"
+"181927936","1391","1391","1391","55.373714447021484","55.373714447021484","55.373714447021484"
+"182452224","1395","1395","1395","56.35654830932617","56.35654830932617","56.35654830932617"
+"182976512","1399","1399","1399","57.88974380493164","57.88974380493164","57.88974380493164"
+"183500800","1403","1403","1403","58.537322998046875","58.537322998046875","58.537322998046875"
+"184025088","1407","1407","1407","59.67573547363281","59.67573547363281","59.67573547363281"
+"184549376","1411","1411","1411","57.60582733154297","57.60582733154297","57.60582733154297"
+"185073664","1415","1415","1415","58.77989196777344","58.77989196777344","58.77989196777344"
+"185597952","1419","1419","1419","59.150169372558594","59.150169372558594","59.150169372558594"
+"186122240","1423","1423","1423","58.58348846435547","58.58348846435547","58.58348846435547"
+"186646528","1427","1427","1427","59.304290771484375","59.304290771484375","59.304290771484375"
+"187170816","1431","1431","1431","59.8878173828125","59.8878173828125","59.8878173828125"
+"187695104","1435","1435","1435","57.57251739501953","57.57251739501953","57.57251739501953"
+"188219392","1439","1439","1439","60.86934280395508","60.86934280395508","60.86934280395508"
+"188743680","1443","1443","1443","59.64753341674805","59.64753341674805","59.64753341674805"
+"189267968","1447","1447","1447","58.92128372192383","58.92128372192383","58.92128372192383"
+"189792256","1451","1451","1451","58.636375427246094","58.636375427246094","58.636375427246094"
+"190316544","1455","1455","1455","60.05632019042969","60.05632019042969","60.05632019042969"
+"190840832","1459","1459","1459","59.3383674621582","59.3383674621582","59.3383674621582"
+"191365120","1463","1463","1463","58.66619110107422","58.66619110107422","58.66619110107422"
+"191889408","1467","1467","1467","56.76365661621094","56.76365661621094","56.76365661621094"
+"192413696","1471","1471","1471","60.711097717285156","60.711097717285156","60.711097717285156"
+"192937984","1475","1475","1475","58.15534591674805","58.15534591674805","58.15534591674805"
+"193462272","1479","1479","1479","60.58076095581055","60.58076095581055","60.58076095581055"
+"193986560","1483","1483","1483","57.70038986206055","57.70038986206055","57.70038986206055"
+"194510848","1487","1487","1487","59.96482467651367","59.96482467651367","59.96482467651367"
+"195035136","1491","1491","1491","59.3648796081543","59.3648796081543","59.3648796081543"
+"195559424","1495","1495","1495","60.8913459777832","60.8913459777832","60.8913459777832"
+"196083712","1499","1499","1499","61.17986297607422","61.17986297607422","61.17986297607422"
+"196608000","1503","1503","1503","58.65708541870117","58.65708541870117","58.65708541870117"
+"197132288","1507","1507","1507","59.44513702392578","59.44513702392578","59.44513702392578"
+"197656576","1511","1511","1511","57.68056869506836","57.68056869506836","57.68056869506836"
+"198180864","1515","1515","1515","57.28187561035156","57.28187561035156","57.28187561035156"
+"198705152","1519","1519","1519","60.80417251586914","60.80417251586914","60.80417251586914"
+"199229440","1523","1523","1523","58.05095672607422","58.05095672607422","58.05095672607422"
+"199753728","1527","1527","1527","57.23497009277344","57.23497009277344","57.23497009277344"
+"200278016","1531","1531","1531","59.02280044555664","59.02280044555664","59.02280044555664"
+"200802304","1535","1535","1535","56.87960433959961","56.87960433959961","56.87960433959961"
+"201326592","1539","1539","1539","59.4319953918457","59.4319953918457","59.4319953918457"
+"201850880","1543","1543","1543","59.27257537841797","59.27257537841797","59.27257537841797"
+"202375168","1547","1547","1547","61.59602355957031","61.59602355957031","61.59602355957031"
+"202899456","1551","1551","1551","60.55632781982422","60.55632781982422","60.55632781982422"
+"203423744","1555","1555","1555","60.72696304321289","60.72696304321289","60.72696304321289"
+"203948032","1559","1559","1559","59.03784942626953","59.03784942626953","59.03784942626953"
+"204472320","1563","1563","1563","60.74446105957031","60.74446105957031","60.74446105957031"
+"204996608","1567","1567","1567","59.867820739746094","59.867820739746094","59.867820739746094"
+"205520896","1571","1571","1571","60.04303741455078","60.04303741455078","60.04303741455078"
+"206045184","1575","1575","1575","58.30607604980469","58.30607604980469","58.30607604980469"
+"206569472","1579","1579","1579","61.65383529663086","61.65383529663086","61.65383529663086"
+"207093760","1583","1583","1583","57.53477478027344","57.53477478027344","57.53477478027344"
+"207618048","1587","1587","1587","58.10987091064453","58.10987091064453","58.10987091064453"
+"208142336","1591","1591","1591","58.59800338745117","58.59800338745117","58.59800338745117"
+"208666624","1595","1595","1595","58.95646667480469","58.95646667480469","58.95646667480469"
+"209190912","1599","1599","1599","60.84099578857422","60.84099578857422","60.84099578857422"
+"209715200","1603","1603","1603","61.50893783569336","61.50893783569336","61.50893783569336"
+"210239488","1607","1607","1607","58.544837951660156","58.544837951660156","58.544837951660156"
+"210763776","1611","1611","1611","60.1420783996582","60.1420783996582","60.1420783996582"
+"211288064","1615","1615","1615","58.643211364746094","58.643211364746094","58.643211364746094"
+"211812352","1619","1619","1619","59.2571907043457","59.2571907043457","59.2571907043457"
+"212336640","1623","1623","1623","60.24994659423828","60.24994659423828","60.24994659423828"
+"212860928","1627","1627","1627","61.68698501586914","61.68698501586914","61.68698501586914"
+"213385216","1631","1631","1631","59.170223236083984","59.170223236083984","59.170223236083984"
+"213909504","1635","1635","1635","56.67714309692383","56.67714309692383","56.67714309692383"
+"214433792","1639","1639","1639","60.42799758911133","60.42799758911133","60.42799758911133"
+"214958080","1643","1643","1643","59.91259765625","59.91259765625","59.91259765625"
+"215482368","1647","1647","1647","60.70083999633789","60.70083999633789","60.70083999633789"
+"216006656","1651","1651","1651","60.45603561401367","60.45603561401367","60.45603561401367"
+"216530944","1655","1655","1655","59.90034866333008","59.90034866333008","59.90034866333008"
+"217055232","1659","1659","1659","62.3609619140625","62.3609619140625","62.3609619140625"
+"217579520","1663","1663","1663","59.88651657104492","59.88651657104492","59.88651657104492"
+"218103808","1667","1667","1667","63.27571487426758","63.27571487426758","63.27571487426758"
+"218628096","1671","1671","1671","61.180267333984375","61.180267333984375","61.180267333984375"
+"219152384","1675","1675","1675","59.90470886230469","59.90470886230469","59.90470886230469"
+"219676672","1679","1679","1679","61.3205451965332","61.3205451965332","61.3205451965332"
+"220200960","1683","1683","1683","58.91713333129883","58.91713333129883","58.91713333129883"
+"220725248","1687","1687","1687","57.48529052734375","57.48529052734375","57.48529052734375"
+"221249536","1691","1691","1691","59.40604019165039","59.40604019165039","59.40604019165039"
+"221773824","1695","1695","1695","59.95090866088867","59.95090866088867","59.95090866088867"
+"222298112","1699","1699","1699","58.640262603759766","58.640262603759766","58.640262603759766"
+"222822400","1703","1703","1703","60.43452453613281","60.43452453613281","60.43452453613281"
+"223346688","1707","1707","1707","59.191322326660156","59.191322326660156","59.191322326660156"
+"223870976","1711","1711","1711","59.63203048706055","59.63203048706055","59.63203048706055"
+"224395264","1715","1715","1715","60.924129486083984","60.924129486083984","60.924129486083984"
+"224919552","1719","1719","1719","59.3992919921875","59.3992919921875","59.3992919921875"
+"225443840","1723","1723","1723","60.054344177246094","60.054344177246094","60.054344177246094"
+"225968128","1727","1727","1727","59.55426025390625","59.55426025390625","59.55426025390625"
+"226492416","1731","1731","1731","60.29377365112305","60.29377365112305","60.29377365112305"
+"227016704","1735","1735","1735","60.88164520263672","60.88164520263672","60.88164520263672"
+"227540992","1739","1739","1739","62.05886459350586","62.05886459350586","62.05886459350586"
+"228065280","1743","1743","1743","60.80459213256836","60.80459213256836","60.80459213256836"
+"228589568","1747","1747","1747","61.56342315673828","61.56342315673828","61.56342315673828"
+"229113856","1751","1751","1751","61.073246002197266","61.073246002197266","61.073246002197266"
+"229638144","1755","1755","1755","61.32489013671875","61.32489013671875","61.32489013671875"
+"230162432","1759","1759","1759","59.064002990722656","59.064002990722656","59.064002990722656"
+"230686720","1763","1763","1763","60.06829833984375","60.06829833984375","60.06829833984375"
+"231211008","1767","1767","1767","59.39692687988281","59.39692687988281","59.39692687988281"
+"231735296","1771","1771","1771","62.213768005371094","62.213768005371094","62.213768005371094"
+"232259584","1775","1775","1775","61.25121307373047","61.25121307373047","61.25121307373047"
+"232783872","1779","1779","1779","61.93516159057617","61.93516159057617","61.93516159057617"
+"233308160","1783","1783","1783","61.39554977416992","61.39554977416992","61.39554977416992"
+"233832448","1787","1787","1787","60.02572250366211","60.02572250366211","60.02572250366211"
+"234356736","1791","1791","1791","59.9697265625","59.9697265625","59.9697265625"
+"234881024","1795","1795","1795","61.07982635498047","61.07982635498047","61.07982635498047"
+"235405312","1799","1799","1799","61.532928466796875","61.532928466796875","61.532928466796875"
+"235929600","1803","1803","1803","62.19686508178711","62.19686508178711","62.19686508178711"
+"236453888","1807","1807","1807","62.11956024169922","62.11956024169922","62.11956024169922"
+"236978176","1811","1811","1811","63.8182487487793","63.8182487487793","63.8182487487793"
+"237502464","1815","1815","1815","61.09371566772461","61.09371566772461","61.09371566772461"
+"238026752","1819","1819","1819","63.83015441894531","63.83015441894531","63.83015441894531"
+"238551040","1823","1823","1823","63.42703628540039","63.42703628540039","63.42703628540039"
+"239075328","1827","1827","1827","62.71445846557617","62.71445846557617","62.71445846557617"
+"239599616","1831","1831","1831","60.04975891113281","60.04975891113281","60.04975891113281"
+"240123904","1835","1835","1835","63.2608642578125","63.2608642578125","63.2608642578125"
+"240648192","1839","1839","1839","64.15184020996094","64.15184020996094","64.15184020996094"
+"241172480","1843","1843","1843","62.94550704956055","62.94550704956055","62.94550704956055"
+"241696768","1847","1847","1847","64.53389739990234","64.53389739990234","64.53389739990234"
+"242221056","1851","1851","1851","59.62118911743164","59.62118911743164","59.62118911743164"
+"242745344","1855","1855","1855","63.63681411743164","63.63681411743164","63.63681411743164"
+"243269632","1859","1859","1859","62.961673736572266","62.961673736572266","62.961673736572266"
+"243793920","1863","1863","1863","62.32405090332031","62.32405090332031","62.32405090332031"
+"244318208","1867","1867","1867","63.77408218383789","63.77408218383789","63.77408218383789"
+"244842496","1871","1871","1871","63.1581916809082","63.1581916809082","63.1581916809082"
+"245366784","1875","1875","1875","63.94620895385742","63.94620895385742","63.94620895385742"
+"245891072","1879","1879","1879","63.77744674682617","63.77744674682617","63.77744674682617"
+"246415360","1883","1883","1883","63.34357833862305","63.34357833862305","63.34357833862305"
+"246939648","1887","1887","1887","64.07331848144531","64.07331848144531","64.07331848144531"
+"247463936","1891","1891","1891","63.45240020751953","63.45240020751953","63.45240020751953"
+"247988224","1895","1895","1895","61.703773498535156","61.703773498535156","61.703773498535156"
+"248512512","1899","1899","1899","61.76910400390625","61.76910400390625","61.76910400390625"
+"249036800","1903","1903","1903","62.89304733276367","62.89304733276367","62.89304733276367"
+"249561088","1907","1907","1907","63.23183822631836","63.23183822631836","63.23183822631836"
+"250085376","1911","1911","1911","63.84391403198242","63.84391403198242","63.84391403198242"
+"250609664","1915","1915","1915","62.45213317871094","62.45213317871094","62.45213317871094"
+"251133952","1919","1919","1919","62.83034896850586","62.83034896850586","62.83034896850586"
+"251658240","1923","1923","1923","63.326141357421875","63.326141357421875","63.326141357421875"
+"252182528","1927","1927","1927","62.715213775634766","62.715213775634766","62.715213775634766"
+"252706816","1931","1931","1931","62.465003967285156","62.465003967285156","62.465003967285156"
+"253231104","1935","1935","1935","61.428504943847656","61.428504943847656","61.428504943847656"
+"253755392","1939","1939","1939","61.67119598388672","61.67119598388672","61.67119598388672"
+"254279680","1943","1943","1943","63.74500274658203","63.74500274658203","63.74500274658203"
+"254803968","1947","1947","1947","62.560760498046875","62.560760498046875","62.560760498046875"
+"255328256","1951","1951","1951","62.83820724487305","62.83820724487305","62.83820724487305"
+"255852544","1955","1955","1955","61.77914047241211","61.77914047241211","61.77914047241211"
+"256376832","1959","1959","1959","63.98127365112305","63.98127365112305","63.98127365112305"
+"256901120","1963","1963","1963","60.56419372558594","60.56419372558594","60.56419372558594"
+"257425408","1967","1967","1967","63.263240814208984","63.263240814208984","63.263240814208984"
+"257949696","1971","1971","1971","66.1895751953125","66.1895751953125","66.1895751953125"
+"258473984","1975","1975","1975","62.457401275634766","62.457401275634766","62.457401275634766"
+"258998272","1979","1979","1979","63.31708526611328","63.31708526611328","63.31708526611328"
+"259522560","1983","1983","1983","62.49838638305664","62.49838638305664","62.49838638305664"
+"260046848","1987","1987","1987","65.17388916015625","65.17388916015625","65.17388916015625"
+"260571136","1991","1991","1991","66.23514556884766","66.23514556884766","66.23514556884766"
+"261095424","1995","1995","1995","62.50825119018555","62.50825119018555","62.50825119018555"
+"261619712","1999","1999","1999","63.06073760986328","63.06073760986328","63.06073760986328"
+"262144000","2003","2003","2003","65.01263427734375","65.01263427734375","65.01263427734375"
+"262668288","2007","2007","2007","64.0395736694336","64.0395736694336","64.0395736694336"
+"263192576","2011","2011","2011","62.81535339355469","62.81535339355469","62.81535339355469"
+"263716864","2015","2015","2015","64.41584014892578","64.41584014892578","64.41584014892578"
+"264241152","2019","2019","2019","64.23533630371094","64.23533630371094","64.23533630371094"
+"264765440","2023","2023","2023","63.02476501464844","63.02476501464844","63.02476501464844"
+"265289728","2027","2027","2027","64.27960968017578","64.27960968017578","64.27960968017578"
+"265814016","2031","2031","2031","61.75523376464844","61.75523376464844","61.75523376464844"
+"266338304","2035","2035","2035","62.8640251159668","62.8640251159668","62.8640251159668"
+"266862592","2039","2039","2039","64.1041030883789","64.1041030883789","64.1041030883789"
+"267386880","2043","2043","2043","61.6949577331543","61.6949577331543","61.6949577331543"
+"267911168","2047","2047","2047","61.17451477050781","61.17451477050781","61.17451477050781"
+"268435456","2051","2051","2051","62.50859069824219","62.50859069824219","62.50859069824219"
+"268959744","2055","2055","2055","62.11734390258789","62.11734390258789","62.11734390258789"
+"269484032","2059","2059","2059","62.41065216064453","62.41065216064453","62.41065216064453"
+"270008320","2063","2063","2063","62.19158935546875","62.19158935546875","62.19158935546875"
+"270532608","2067","2067","2067","62.93135452270508","62.93135452270508","62.93135452270508"
+"271056896","2071","2071","2071","64.16558837890625","64.16558837890625","64.16558837890625"
+"271581184","2075","2075","2075","62.89292526245117","62.89292526245117","62.89292526245117"
+"272105472","2079","2079","2079","64.65062713623047","64.65062713623047","64.65062713623047"
+"272629760","2083","2083","2083","64.55636596679688","64.55636596679688","64.55636596679688"
+"273154048","2087","2087","2087","62.68961715698242","62.68961715698242","62.68961715698242"
+"273678336","2091","2091","2091","61.479705810546875","61.479705810546875","61.479705810546875"
+"274202624","2095","2095","2095","60.78036117553711","60.78036117553711","60.78036117553711"
+"274726912","2099","2099","2099","61.60922622680664","61.60922622680664","61.60922622680664"
+"275251200","2103","2103","2103","63.859378814697266","63.859378814697266","63.859378814697266"
+"275775488","2107","2107","2107","64.32440948486328","64.32440948486328","64.32440948486328"
+"276299776","2111","2111","2111","63.495574951171875","63.495574951171875","63.495574951171875"
+"276824064","2115","2115","2115","61.81763458251953","61.81763458251953","61.81763458251953"
+"277348352","2119","2119","2119","61.97660446166992","61.97660446166992","61.97660446166992"
+"277872640","2123","2123","2123","62.64421844482422","62.64421844482422","62.64421844482422"
+"278396928","2127","2127","2127","59.0889778137207","59.0889778137207","59.0889778137207"
+"278921216","2131","2131","2131","63.51023483276367","63.51023483276367","63.51023483276367"
+"279445504","2135","2135","2135","61.62010955810547","61.62010955810547","61.62010955810547"
+"279969792","2139","2139","2139","63.44777297973633","63.44777297973633","63.44777297973633"
+"280494080","2143","2143","2143","62.93443298339844","62.93443298339844","62.93443298339844"
+"281018368","2147","2147","2147","61.83591842651367","61.83591842651367","61.83591842651367"
+"281542656","2151","2151","2151","64.52871704101562","64.52871704101562","64.52871704101562"
+"282066944","2155","2155","2155","65.49501037597656","65.49501037597656","65.49501037597656"
+"282591232","2159","2159","2159","62.69575500488281","62.69575500488281","62.69575500488281"
+"283115520","2163","2163","2163","63.755252838134766","63.755252838134766","63.755252838134766"
+"283639808","2167","2167","2167","64.372314453125","64.372314453125","64.372314453125"
+"284164096","2171","2171","2171","64.98361206054688","64.98361206054688","64.98361206054688"
+"284688384","2175","2175","2175","63.69981384277344","63.69981384277344","63.69981384277344"
+"285212672","2179","2179","2179","62.423675537109375","62.423675537109375","62.423675537109375"
+"285736960","2183","2183","2183","63.08547592163086","63.08547592163086","63.08547592163086"
+"286261248","2187","2187","2187","65.30268859863281","65.30268859863281","65.30268859863281"
+"286785536","2191","2191","2191","64.46923065185547","64.46923065185547","64.46923065185547"
+"287309824","2195","2195","2195","64.18067932128906","64.18067932128906","64.18067932128906"
+"287834112","2199","2199","2199","63.28699493408203","63.28699493408203","63.28699493408203"
+"288358400","2203","2203","2203","62.03573226928711","62.03573226928711","62.03573226928711"
+"288882688","2207","2207","2207","63.80065155029297","63.80065155029297","63.80065155029297"
+"289406976","2211","2211","2211","62.78409957885742","62.78409957885742","62.78409957885742"
+"289931264","2215","2215","2215","63.99978256225586","63.99978256225586","63.99978256225586"
+"290455552","2219","2219","2219","62.57464599609375","62.57464599609375","62.57464599609375"
+"290979840","2223","2223","2223","62.378387451171875","62.378387451171875","62.378387451171875"
+"291504128","2227","2227","2227","61.11417007446289","61.11417007446289","61.11417007446289"
+"292028416","2231","2231","2231","61.4486198425293","61.4486198425293","61.4486198425293"
+"292552704","2235","2235","2235","64.5801773071289","64.5801773071289","64.5801773071289"
+"293076992","2239","2239","2239","64.01583099365234","64.01583099365234","64.01583099365234"
+"293601280","2243","2243","2243","63.37886428833008","63.37886428833008","63.37886428833008"
+"294125568","2247","2247","2247","62.74309539794922","62.74309539794922","62.74309539794922"
+"294649856","2251","2251","2251","65.38043975830078","65.38043975830078","65.38043975830078"
+"295174144","2255","2255","2255","63.79602813720703","63.79602813720703","63.79602813720703"
+"295698432","2259","2259","2259","62.34005355834961","62.34005355834961","62.34005355834961"
+"296222720","2263","2263","2263","61.05173110961914","61.05173110961914","61.05173110961914"
+"296747008","2267","2267","2267","63.04880905151367","63.04880905151367","63.04880905151367"
+"297271296","2271","2271","2271","63.0188102722168","63.0188102722168","63.0188102722168"
+"297795584","2275","2275","2275","65.17830657958984","65.17830657958984","65.17830657958984"
+"298319872","2279","2279","2279","63.22684097290039","63.22684097290039","63.22684097290039"
+"298844160","2283","2283","2283","63.14492416381836","63.14492416381836","63.14492416381836"
+"299368448","2287","2287","2287","62.886322021484375","62.886322021484375","62.886322021484375"
+"299892736","2291","2291","2291","63.22588348388672","63.22588348388672","63.22588348388672"
+"300417024","2295","2295","2295","60.86265182495117","60.86265182495117","60.86265182495117"
+"300941312","2299","2299","2299","64.00386810302734","64.00386810302734","64.00386810302734"
+"301465600","2303","2303","2303","62.158172607421875","62.158172607421875","62.158172607421875"
+"301989888","2307","2307","2307","60.62030029296875","60.62030029296875","60.62030029296875"
+"302514176","2311","2311","2311","61.86820602416992","61.86820602416992","61.86820602416992"
+"303038464","2315","2315","2315","62.55779266357422","62.55779266357422","62.55779266357422"
+"303562752","2319","2319","2319","62.560081481933594","62.560081481933594","62.560081481933594"
+"304087040","2323","2323","2323","62.39745330810547","62.39745330810547","62.39745330810547"
+"304611328","2327","2327","2327","62.72347640991211","62.72347640991211","62.72347640991211"
+"305135616","2331","2331","2331","62.2504997253418","62.2504997253418","62.2504997253418"
+"305659904","2335","2335","2335","63.381248474121094","63.381248474121094","63.381248474121094"
+"306184192","2339","2339","2339","62.55337142944336","62.55337142944336","62.55337142944336"
+"306708480","2343","2343","2343","65.3228530883789","65.3228530883789","65.3228530883789"
+"307232768","2347","2347","2347","60.59780502319336","60.59780502319336","60.59780502319336"
+"307757056","2351","2351","2351","62.531005859375","62.531005859375","62.531005859375"
+"308281344","2355","2355","2355","64.7091064453125","64.7091064453125","64.7091064453125"
+"308805632","2359","2359","2359","63.86561965942383","63.86561965942383","63.86561965942383"
+"309329920","2363","2363","2363","60.38583755493164","60.38583755493164","60.38583755493164"
+"309854208","2367","2367","2367","61.99456787109375","61.99456787109375","61.99456787109375"
+"310378496","2371","2371","2371","62.14643859863281","62.14643859863281","62.14643859863281"
+"310902784","2375","2375","2375","60.56208801269531","60.56208801269531","60.56208801269531"
+"311427072","2379","2379","2379","62.98328399658203","62.98328399658203","62.98328399658203"
+"311951360","2383","2383","2383","61.179134368896484","61.179134368896484","61.179134368896484"
+"312475648","2387","2387","2387","61.654266357421875","61.654266357421875","61.654266357421875"
+"312999936","2391","2391","2391","61.28993606567383","61.28993606567383","61.28993606567383"
+"313524224","2395","2395","2395","62.34329605102539","62.34329605102539","62.34329605102539"
+"314048512","2399","2399","2399","60.743812561035156","60.743812561035156","60.743812561035156"
+"314572800","2403","2403","2403","61.77951431274414","61.77951431274414","61.77951431274414"
+"315097088","2407","2407","2407","61.66852569580078","61.66852569580078","61.66852569580078"
+"315621376","2411","2411","2411","61.76982116699219","61.76982116699219","61.76982116699219"
+"316145664","2415","2415","2415","62.895687103271484","62.895687103271484","62.895687103271484"
+"316669952","2419","2419","2419","61.15913009643555","61.15913009643555","61.15913009643555"
+"317194240","2423","2423","2423","61.8051643371582","61.8051643371582","61.8051643371582"
+"317718528","2427","2427","2427","63.65115737915039","63.65115737915039","63.65115737915039"
+"318242816","2431","2431","2431","59.98978805541992","59.98978805541992","59.98978805541992"
+"318767104","2435","2435","2435","60.5356330871582","60.5356330871582","60.5356330871582"
+"319291392","2439","2439","2439","62.0826530456543","62.0826530456543","62.0826530456543"
+"319815680","2443","2443","2443","61.07522201538086","61.07522201538086","61.07522201538086"
+"320339968","2447","2447","2447","60.88374710083008","60.88374710083008","60.88374710083008"
+"320864256","2451","2451","2451","62.1511116027832","62.1511116027832","62.1511116027832"
+"321388544","2455","2455","2455","61.92063522338867","61.92063522338867","61.92063522338867"
+"321912832","2459","2459","2459","63.350765228271484","63.350765228271484","63.350765228271484"
+"322437120","2463","2463","2463","62.304622650146484","62.304622650146484","62.304622650146484"
+"322961408","2467","2467","2467","60.33829879760742","60.33829879760742","60.33829879760742"
+"323485696","2471","2471","2471","61.94978332519531","61.94978332519531","61.94978332519531"
+"324009984","2475","2475","2475","59.75309371948242","59.75309371948242","59.75309371948242"
+"324534272","2479","2479","2479","61.06528854370117","61.06528854370117","61.06528854370117"
+"325058560","2483","2483","2483","60.15198516845703","60.15198516845703","60.15198516845703"
+"325582848","2487","2487","2487","60.469539642333984","60.469539642333984","60.469539642333984"
+"326107136","2491","2491","2491","60.68805694580078","60.68805694580078","60.68805694580078"
+"326631424","2495","2495","2495","62.32078170776367","62.32078170776367","62.32078170776367"
+"327155712","2499","2499","2499","63.434326171875","63.434326171875","63.434326171875"
+"327680000","2503","2503","2503","60.70003128051758","60.70003128051758","60.70003128051758"
+"328204288","2507","2507","2507","62.56221008300781","62.56221008300781","62.56221008300781"
+"328728576","2511","2511","2511","61.06088638305664","61.06088638305664","61.06088638305664"
+"329252864","2515","2515","2515","61.33478546142578","61.33478546142578","61.33478546142578"
+"329777152","2519","2519","2519","59.74412155151367","59.74412155151367","59.74412155151367"
+"330301440","2523","2523","2523","61.441932678222656","61.441932678222656","61.441932678222656"
+"330825728","2527","2527","2527","61.32310485839844","61.32310485839844","61.32310485839844"
+"331350016","2531","2531","2531","61.77032470703125","61.77032470703125","61.77032470703125"
+"331874304","2535","2535","2535","61.8638916015625","61.8638916015625","61.8638916015625"
+"332398592","2539","2539","2539","61.24184799194336","61.24184799194336","61.24184799194336"
+"332922880","2543","2543","2543","61.45927429199219","61.45927429199219","61.45927429199219"
+"333447168","2547","2547","2547","61.45449447631836","61.45449447631836","61.45449447631836"
+"333971456","2551","2551","2551","60.98225402832031","60.98225402832031","60.98225402832031"
+"334495744","2555","2555","2555","60.67939376831055","60.67939376831055","60.67939376831055"
+"335020032","2559","2559","2559","64.5963363647461","64.5963363647461","64.5963363647461"
+"335544320","2563","2563","2563","62.5375862121582","62.5375862121582","62.5375862121582"
+"336068608","2567","2567","2567","61.38118362426758","61.38118362426758","61.38118362426758"
+"336592896","2571","2571","2571","61.32973861694336","61.32973861694336","61.32973861694336"
+"337117184","2575","2575","2575","62.73893356323242","62.73893356323242","62.73893356323242"
+"337641472","2579","2579","2579","61.43117904663086","61.43117904663086","61.43117904663086"
+"338165760","2583","2583","2583","61.44200134277344","61.44200134277344","61.44200134277344"
+"338690048","2587","2587","2587","63.3760871887207","63.3760871887207","63.3760871887207"
+"339214336","2591","2591","2591","59.73139190673828","59.73139190673828","59.73139190673828"
+"339738624","2595","2595","2595","61.184661865234375","61.184661865234375","61.184661865234375"
+"340262912","2599","2599","2599","62.361053466796875","62.361053466796875","62.361053466796875"
+"340787200","2603","2603","2603","60.633113861083984","60.633113861083984","60.633113861083984"
+"341311488","2607","2607","2607","62.157440185546875","62.157440185546875","62.157440185546875"
+"341835776","2611","2611","2611","60.12508010864258","60.12508010864258","60.12508010864258"
+"342360064","2615","2615","2615","61.7855110168457","61.7855110168457","61.7855110168457"
+"342884352","2619","2619","2619","63.577659606933594","63.577659606933594","63.577659606933594"
+"343408640","2623","2623","2623","64.01907348632812","64.01907348632812","64.01907348632812"
+"343932928","2627","2627","2627","63.534847259521484","63.534847259521484","63.534847259521484"
+"344457216","2631","2631","2631","63.350433349609375","63.350433349609375","63.350433349609375"
+"344981504","2635","2635","2635","61.10936737060547","61.10936737060547","61.10936737060547"
+"345505792","2639","2639","2639","60.637001037597656","60.637001037597656","60.637001037597656"
+"346030080","2643","2643","2643","63.23590850830078","63.23590850830078","63.23590850830078"
+"346554368","2647","2647","2647","62.84688186645508","62.84688186645508","62.84688186645508"
+"347078656","2651","2651","2651","60.9062385559082","60.9062385559082","60.9062385559082"
+"347602944","2655","2655","2655","63.36465835571289","63.36465835571289","63.36465835571289"
+"348127232","2659","2659","2659","62.40274429321289","62.40274429321289","62.40274429321289"
+"348651520","2663","2663","2663","60.31591796875","60.31591796875","60.31591796875"
+"349175808","2667","2667","2667","63.16893005371094","63.16893005371094","63.16893005371094"
+"349700096","2671","2671","2671","62.81526565551758","62.81526565551758","62.81526565551758"
+"350224384","2675","2675","2675","64.49227142333984","64.49227142333984","64.49227142333984"
+"350748672","2679","2679","2679","61.47041702270508","61.47041702270508","61.47041702270508"
+"351272960","2683","2683","2683","62.99509048461914","62.99509048461914","62.99509048461914"
+"351797248","2687","2687","2687","61.326942443847656","61.326942443847656","61.326942443847656"
+"352321536","2691","2691","2691","62.87727355957031","62.87727355957031","62.87727355957031"
+"352845824","2695","2695","2695","63.6063232421875","63.6063232421875","63.6063232421875"
+"353370112","2699","2699","2699","63.209564208984375","63.209564208984375","63.209564208984375"
+"353894400","2703","2703","2703","62.27708053588867","62.27708053588867","62.27708053588867"
+"354418688","2707","2707","2707","63.74250793457031","63.74250793457031","63.74250793457031"
+"354942976","2711","2711","2711","63.22309494018555","63.22309494018555","63.22309494018555"
+"355467264","2715","2715","2715","62.51585388183594","62.51585388183594","62.51585388183594"
+"355991552","2719","2719","2719","62.79290008544922","62.79290008544922","62.79290008544922"
+"356515840","2723","2723","2723","63.20482635498047","63.20482635498047","63.20482635498047"
+"357040128","2727","2727","2727","63.2633171081543","63.2633171081543","63.2633171081543"
+"357564416","2731","2731","2731","62.83933639526367","62.83933639526367","62.83933639526367"
+"358088704","2735","2735","2735","61.94850540161133","61.94850540161133","61.94850540161133"
+"358612992","2739","2739","2739","62.16694259643555","62.16694259643555","62.16694259643555"
+"359137280","2743","2743","2743","60.473793029785156","60.473793029785156","60.473793029785156"
+"359661568","2747","2747","2747","62.142425537109375","62.142425537109375","62.142425537109375"
+"360185856","2751","2751","2751","62.31974411010742","62.31974411010742","62.31974411010742"
+"360710144","2755","2755","2755","60.56294250488281","60.56294250488281","60.56294250488281"
+"361234432","2759","2759","2759","62.2495002746582","62.2495002746582","62.2495002746582"
+"361758720","2763","2763","2763","60.9962043762207","60.9962043762207","60.9962043762207"
+"362283008","2767","2767","2767","62.01378631591797","62.01378631591797","62.01378631591797"
+"362807296","2771","2771","2771","61.7618293762207","61.7618293762207","61.7618293762207"
+"363331584","2775","2775","2775","62.37274932861328","62.37274932861328","62.37274932861328"
+"363855872","2779","2779","2779","61.30591583251953","61.30591583251953","61.30591583251953"
+"364380160","2783","2783","2783","60.92583465576172","60.92583465576172","60.92583465576172"
+"364904448","2787","2787","2787","61.972537994384766","61.972537994384766","61.972537994384766"
+"365428736","2791","2791","2791","61.96847915649414","61.96847915649414","61.96847915649414"
+"365953024","2795","2795","2795","64.05081176757812","64.05081176757812","64.05081176757812"
+"366477312","2799","2799","2799","61.00436019897461","61.00436019897461","61.00436019897461"
+"367001600","2803","2803","2803","63.28178024291992","63.28178024291992","63.28178024291992"
+"367525888","2807","2807","2807","60.67517852783203","60.67517852783203","60.67517852783203"
+"368050176","2811","2811","2811","61.845375061035156","61.845375061035156","61.845375061035156"
+"368574464","2815","2815","2815","61.08356857299805","61.08356857299805","61.08356857299805"
+"369098752","2819","2819","2819","63.40243911743164","63.40243911743164","63.40243911743164"
+"369623040","2823","2823","2823","61.71462631225586","61.71462631225586","61.71462631225586"
+"370147328","2827","2827","2827","63.59551239013672","63.59551239013672","63.59551239013672"
+"370671616","2831","2831","2831","63.16429901123047","63.16429901123047","63.16429901123047"
+"371195904","2835","2835","2835","62.00571823120117","62.00571823120117","62.00571823120117"
+"371720192","2839","2839","2839","62.399871826171875","62.399871826171875","62.399871826171875"
+"372244480","2843","2843","2843","64.04756927490234","64.04756927490234","64.04756927490234"
+"372768768","2847","2847","2847","62.62449264526367","62.62449264526367","62.62449264526367"
+"373293056","2851","2851","2851","61.39771270751953","61.39771270751953","61.39771270751953"
+"373817344","2855","2855","2855","61.543846130371094","61.543846130371094","61.543846130371094"
+"374341632","2859","2859","2859","61.46337890625","61.46337890625","61.46337890625"
+"374865920","2863","2863","2863","63.21284866333008","63.21284866333008","63.21284866333008"
+"375390208","2867","2867","2867","61.50856399536133","61.50856399536133","61.50856399536133"
+"375914496","2871","2871","2871","62.30818557739258","62.30818557739258","62.30818557739258"
+"376438784","2875","2875","2875","62.37699508666992","62.37699508666992","62.37699508666992"
+"376963072","2879","2879","2879","60.40598678588867","60.40598678588867","60.40598678588867"
+"377487360","2883","2883","2883","63.01976013183594","63.01976013183594","63.01976013183594"
+"378011648","2887","2887","2887","62.51777648925781","62.51777648925781","62.51777648925781"
+"378535936","2891","2891","2891","59.98557662963867","59.98557662963867","59.98557662963867"
+"379060224","2895","2895","2895","62.018104553222656","62.018104553222656","62.018104553222656"
+"379584512","2899","2899","2899","60.286781311035156","60.286781311035156","60.286781311035156"
+"380108800","2903","2903","2903","61.82871627807617","61.82871627807617","61.82871627807617"
+"380633088","2907","2907","2907","60.74306106567383","60.74306106567383","60.74306106567383"
+"381157376","2911","2911","2911","61.039920806884766","61.039920806884766","61.039920806884766"
+"381681664","2915","2915","2915","61.41294860839844","61.41294860839844","61.41294860839844"
+"382205952","2919","2919","2919","61.36243438720703","61.36243438720703","61.36243438720703"
+"382730240","2923","2923","2923","61.36260223388672","61.36260223388672","61.36260223388672"
+"383254528","2927","2927","2927","63.12525177001953","63.12525177001953","63.12525177001953"
+"383778816","2931","2931","2931","61.82804489135742","61.82804489135742","61.82804489135742"
+"384303104","2935","2935","2935","62.99101257324219","62.99101257324219","62.99101257324219"
+"384827392","2939","2939","2939","61.83382034301758","61.83382034301758","61.83382034301758"
+"385351680","2943","2943","2943","61.108524322509766","61.108524322509766","61.108524322509766"
+"385875968","2947","2947","2947","61.534149169921875","61.534149169921875","61.534149169921875"
+"386400256","2951","2951","2951","61.468196868896484","61.468196868896484","61.468196868896484"
+"386924544","2955","2955","2955","61.81074905395508","61.81074905395508","61.81074905395508"
+"387448832","2959","2959","2959","60.894432067871094","60.894432067871094","60.894432067871094"
+"387973120","2963","2963","2963","62.81321716308594","62.81321716308594","62.81321716308594"
+"388497408","2967","2967","2967","61.64955520629883","61.64955520629883","61.64955520629883"
+"389021696","2971","2971","2971","61.5854377746582","61.5854377746582","61.5854377746582"
+"389545984","2975","2975","2975","62.29813003540039","62.29813003540039","62.29813003540039"
+"390070272","2979","2979","2979","60.30878829956055","60.30878829956055","60.30878829956055"
+"390594560","2983","2983","2983","60.91538619995117","60.91538619995117","60.91538619995117"
+"391118848","2987","2987","2987","63.70137405395508","63.70137405395508","63.70137405395508"
+"391643136","2991","2991","2991","62.2218017578125","62.2218017578125","62.2218017578125"
+"392167424","2995","2995","2995","59.76592254638672","59.76592254638672","59.76592254638672"
+"392691712","2999","2999","2999","60.488895416259766","60.488895416259766","60.488895416259766"
+"393216000","3003","3003","3003","61.57825469970703","61.57825469970703","61.57825469970703"
+"393740288","3007","3007","3007","63.73362350463867","63.73362350463867","63.73362350463867"
+"394264576","3011","3011","3011","59.66373825073242","59.66373825073242","59.66373825073242"
+"394788864","3015","3015","3015","60.28769302368164","60.28769302368164","60.28769302368164"
+"395313152","3019","3019","3019","61.3414192199707","61.3414192199707","61.3414192199707"
+"395837440","3023","3023","3023","62.039608001708984","62.039608001708984","62.039608001708984"
+"396361728","3027","3027","3027","61.301795959472656","61.301795959472656","61.301795959472656"
+"396886016","3031","3031","3031","61.47064971923828","61.47064971923828","61.47064971923828"
+"397410304","3035","3035","3035","63.36606979370117","63.36606979370117","63.36606979370117"
+"397934592","3039","3039","3039","62.016536712646484","62.016536712646484","62.016536712646484"
+"398458880","3043","3043","3043","62.772884368896484","62.772884368896484","62.772884368896484"
+"398983168","3047","3047","3047","60.82975387573242","60.82975387573242","60.82975387573242"
+"399507456","3051","3051","3051","61.93006134033203","61.93006134033203","61.93006134033203"
+"400031744","3055","3055","3055","59.779300689697266","59.779300689697266","59.779300689697266"
+"400556032","3059","3059","3059","64.61743927001953","64.61743927001953","64.61743927001953"
+"401080320","3063","3063","3063","60.921180725097656","60.921180725097656","60.921180725097656"
+"401604608","3067","3067","3067","60.310546875","60.310546875","60.310546875"
+"402128896","3071","3071","3071","60.234012603759766","60.234012603759766","60.234012603759766"
+"402653184","3075","3075","3075","60.573246002197266","60.573246002197266","60.573246002197266"
+"403177472","3079","3079","3079","62.48672103881836","62.48672103881836","62.48672103881836"
+"403701760","3083","3083","3083","62.237239837646484","62.237239837646484","62.237239837646484"
+"404226048","3087","3087","3087","60.308837890625","60.308837890625","60.308837890625"
+"404750336","3091","3091","3091","63.8034553527832","63.8034553527832","63.8034553527832"
+"405274624","3095","3095","3095","62.265541076660156","62.265541076660156","62.265541076660156"
+"405798912","3099","3099","3099","59.721248626708984","59.721248626708984","59.721248626708984"
+"406323200","3103","3103","3103","62.41391372680664","62.41391372680664","62.41391372680664"
+"406847488","3107","3107","3107","61.9290657043457","61.9290657043457","61.9290657043457"
+"407371776","3111","3111","3111","62.94412612915039","62.94412612915039","62.94412612915039"
+"407896064","3115","3115","3115","63.48972702026367","63.48972702026367","63.48972702026367"
+"408420352","3119","3119","3119","60.65314865112305","60.65314865112305","60.65314865112305"
+"408944640","3123","3123","3123","62.70185470581055","62.70185470581055","62.70185470581055"
+"409468928","3127","3127","3127","60.54952621459961","60.54952621459961","60.54952621459961"
+"409993216","3131","3131","3131","61.33066940307617","61.33066940307617","61.33066940307617"
+"410517504","3135","3135","3135","61.15034866333008","61.15034866333008","61.15034866333008"
+"411041792","3139","3139","3139","60.1933708190918","60.1933708190918","60.1933708190918"
+"411566080","3143","3143","3143","61.581565856933594","61.581565856933594","61.581565856933594"
+"412090368","3147","3147","3147","62.493919372558594","62.493919372558594","62.493919372558594"
+"412614656","3151","3151","3151","60.678436279296875","60.678436279296875","60.678436279296875"
+"413138944","3155","3155","3155","58.78569793701172","58.78569793701172","58.78569793701172"
+"413663232","3159","3159","3159","61.64788055419922","61.64788055419922","61.64788055419922"
+"414187520","3163","3163","3163","62.661102294921875","62.661102294921875","62.661102294921875"
+"414711808","3167","3167","3167","59.50447463989258","59.50447463989258","59.50447463989258"
+"415236096","3171","3171","3171","62.58085250854492","62.58085250854492","62.58085250854492"
+"415760384","3175","3175","3175","60.5330810546875","60.5330810546875","60.5330810546875"
+"416284672","3179","3179","3179","60.29218673706055","60.29218673706055","60.29218673706055"
+"416808960","3183","3183","3183","59.096092224121094","59.096092224121094","59.096092224121094"
+"417333248","3187","3187","3187","62.6514778137207","62.6514778137207","62.6514778137207"
+"417857536","3191","3191","3191","61.10954284667969","61.10954284667969","61.10954284667969"
+"418381824","3195","3195","3195","61.19260025024414","61.19260025024414","61.19260025024414"
+"418906112","3199","3199","3199","61.71366882324219","61.71366882324219","61.71366882324219"
+"419430400","3203","3203","3203","59.29921340942383","59.29921340942383","59.29921340942383"
+"419954688","3207","3207","3207","61.321693420410156","61.321693420410156","61.321693420410156"
+"420478976","3211","3211","3211","60.04356384277344","60.04356384277344","60.04356384277344"
+"421003264","3215","3215","3215","59.96870040893555","59.96870040893555","59.96870040893555"
+"421527552","3219","3219","3219","59.5892333984375","59.5892333984375","59.5892333984375"
+"422051840","3223","3223","3223","62.33134078979492","62.33134078979492","62.33134078979492"
+"422576128","3227","3227","3227","60.67345428466797","60.67345428466797","60.67345428466797"
+"423100416","3231","3231","3231","62.43039321899414","62.43039321899414","62.43039321899414"
+"423624704","3235","3235","3235","61.85441589355469","61.85441589355469","61.85441589355469"
+"424148992","3239","3239","3239","62.05644989013672","62.05644989013672","62.05644989013672"
+"424673280","3243","3243","3243","61.34465789794922","61.34465789794922","61.34465789794922"
+"425197568","3247","3247","3247","63.77851486206055","63.77851486206055","63.77851486206055"
+"425721856","3251","3251","3251","61.95744323730469","61.95744323730469","61.95744323730469"
+"426246144","3255","3255","3255","59.52126693725586","59.52126693725586","59.52126693725586"
+"426770432","3259","3259","3259","60.20452880859375","60.20452880859375","60.20452880859375"
+"427294720","3263","3263","3263","62.66075134277344","62.66075134277344","62.66075134277344"
+"427819008","3267","3267","3267","60.42724609375","60.42724609375","60.42724609375"
+"428343296","3271","3271","3271","63.48213195800781","63.48213195800781","63.48213195800781"
+"428867584","3275","3275","3275","60.69400405883789","60.69400405883789","60.69400405883789"
+"429391872","3279","3279","3279","60.75303268432617","60.75303268432617","60.75303268432617"
+"429916160","3283","3283","3283","61.54719161987305","61.54719161987305","61.54719161987305"
+"430440448","3287","3287","3287","62.7725830078125","62.7725830078125","62.7725830078125"
+"430964736","3291","3291","3291","61.08135223388672","61.08135223388672","61.08135223388672"
+"431489024","3295","3295","3295","61.14830017089844","61.14830017089844","61.14830017089844"
+"432013312","3299","3299","3299","63.18914031982422","63.18914031982422","63.18914031982422"
+"432537600","3303","3303","3303","60.255706787109375","60.255706787109375","60.255706787109375"
+"433061888","3307","3307","3307","59.72360610961914","59.72360610961914","59.72360610961914"
+"433586176","3311","3311","3311","62.32326126098633","62.32326126098633","62.32326126098633"
+"434110464","3315","3315","3315","60.07070541381836","60.07070541381836","60.07070541381836"
+"434634752","3319","3319","3319","64.33171844482422","64.33171844482422","64.33171844482422"
+"435159040","3323","3323","3323","61.828147888183594","61.828147888183594","61.828147888183594"
+"435683328","3327","3327","3327","59.770790100097656","59.770790100097656","59.770790100097656"
+"436207616","3331","3331","3331","61.02109146118164","61.02109146118164","61.02109146118164"
+"436731904","3335","3335","3335","61.42064666748047","61.42064666748047","61.42064666748047"
+"437256192","3339","3339","3339","59.94964599609375","59.94964599609375","59.94964599609375"
+"437780480","3343","3343","3343","60.12651062011719","60.12651062011719","60.12651062011719"
+"438304768","3347","3347","3347","60.77405548095703","60.77405548095703","60.77405548095703"
+"438829056","3351","3351","3351","60.36280059814453","60.36280059814453","60.36280059814453"
+"439353344","3355","3355","3355","60.28885269165039","60.28885269165039","60.28885269165039"
+"439877632","3359","3359","3359","61.1416130065918","61.1416130065918","61.1416130065918"
+"440401920","3363","3363","3363","59.51070022583008","59.51070022583008","59.51070022583008"
+"440926208","3367","3367","3367","60.70942687988281","60.70942687988281","60.70942687988281"
+"441450496","3371","3371","3371","59.36654281616211","59.36654281616211","59.36654281616211"
+"441974784","3375","3375","3375","60.92522430419922","60.92522430419922","60.92522430419922"
+"442499072","3379","3379","3379","59.608680725097656","59.608680725097656","59.608680725097656"
+"443023360","3383","3383","3383","58.62530517578125","58.62530517578125","58.62530517578125"
+"443547648","3387","3387","3387","59.15380096435547","59.15380096435547","59.15380096435547"
+"444071936","3391","3391","3391","59.168670654296875","59.168670654296875","59.168670654296875"
+"444596224","3395","3395","3395","61.12752914428711","61.12752914428711","61.12752914428711"
+"445120512","3399","3399","3399","61.51913070678711","61.51913070678711","61.51913070678711"
+"445644800","3403","3403","3403","61.59685516357422","61.59685516357422","61.59685516357422"
+"446169088","3407","3407","3407","60.10417938232422","60.10417938232422","60.10417938232422"
+"446693376","3411","3411","3411","60.00666427612305","60.00666427612305","60.00666427612305"
+"447217664","3415","3415","3415","62.92542266845703","62.92542266845703","62.92542266845703"
+"447741952","3419","3419","3419","60.20878219604492","60.20878219604492","60.20878219604492"
+"448266240","3423","3423","3423","58.15325927734375","58.15325927734375","58.15325927734375"
+"448790528","3427","3427","3427","60.200199127197266","60.200199127197266","60.200199127197266"
+"449314816","3431","3431","3431","60.3042106628418","60.3042106628418","60.3042106628418"
+"449839104","3435","3435","3435","59.23680877685547","59.23680877685547","59.23680877685547"
+"450363392","3439","3439","3439","59.28142547607422","59.28142547607422","59.28142547607422"
+"450887680","3443","3443","3443","59.57393264770508","59.57393264770508","59.57393264770508"
+"451411968","3447","3447","3447","60.4154167175293","60.4154167175293","60.4154167175293"
+"451936256","3451","3451","3451","59.90383529663086","59.90383529663086","59.90383529663086"
+"452460544","3455","3455","3455","58.19211196899414","58.19211196899414","58.19211196899414"
+"452984832","3459","3459","3459","62.1361083984375","62.1361083984375","62.1361083984375"
+"453509120","3463","3463","3463","59.543479919433594","59.543479919433594","59.543479919433594"
+"454033408","3467","3467","3467","60.445068359375","60.445068359375","60.445068359375"
+"454557696","3471","3471","3471","60.03316116333008","60.03316116333008","60.03316116333008"
+"455081984","3475","3475","3475","60.59521484375","60.59521484375","60.59521484375"
+"455606272","3479","3479","3479","61.474822998046875","61.474822998046875","61.474822998046875"
+"456130560","3483","3483","3483","57.93115234375","57.93115234375","57.93115234375"
+"456654848","3487","3487","3487","61.41173553466797","61.41173553466797","61.41173553466797"
+"457179136","3491","3491","3491","58.88302993774414","58.88302993774414","58.88302993774414"
+"457703424","3495","3495","3495","60.2317008972168","60.2317008972168","60.2317008972168"
+"458227712","3499","3499","3499","60.4130859375","60.4130859375","60.4130859375"
+"458752000","3503","3503","3503","59.7039794921875","59.7039794921875","59.7039794921875"
+"459276288","3507","3507","3507","60.59096908569336","60.59096908569336","60.59096908569336"
+"459800576","3511","3511","3511","59.5068244934082","59.5068244934082","59.5068244934082"
+"460324864","3515","3515","3515","60.22103500366211","60.22103500366211","60.22103500366211"
+"460849152","3519","3519","3519","60.45689392089844","60.45689392089844","60.45689392089844"
+"461373440","3523","3523","3523","59.340721130371094","59.340721130371094","59.340721130371094"
+"461897728","3527","3527","3527","59.3755989074707","59.3755989074707","59.3755989074707"
+"462422016","3531","3531","3531","58.94630813598633","58.94630813598633","58.94630813598633"
+"462946304","3535","3535","3535","59.76064682006836","59.76064682006836","59.76064682006836"
+"463470592","3539","3539","3539","58.95783233642578","58.95783233642578","58.95783233642578"
+"463994880","3543","3543","3543","58.32074737548828","58.32074737548828","58.32074737548828"
+"464519168","3547","3547","3547","60.1705436706543","60.1705436706543","60.1705436706543"
+"465043456","3551","3551","3551","60.33665084838867","60.33665084838867","60.33665084838867"
+"465567744","3555","3555","3555","59.05884552001953","59.05884552001953","59.05884552001953"
+"466092032","3559","3559","3559","59.53653335571289","59.53653335571289","59.53653335571289"
+"466616320","3563","3563","3563","59.77467727661133","59.77467727661133","59.77467727661133"
+"467140608","3567","3567","3567","59.018035888671875","59.018035888671875","59.018035888671875"
+"467664896","3571","3571","3571","59.06706237792969","59.06706237792969","59.06706237792969"
+"468189184","3575","3575","3575","59.545326232910156","59.545326232910156","59.545326232910156"
+"468713472","3579","3579","3579","60.42410659790039","60.42410659790039","60.42410659790039"
+"469237760","3583","3583","3583","57.75897979736328","57.75897979736328","57.75897979736328"
+"469762048","3587","3587","3587","60.13484191894531","60.13484191894531","60.13484191894531"
+"470286336","3591","3591","3591","60.86051559448242","60.86051559448242","60.86051559448242"
+"470810624","3595","3595","3595","59.26345443725586","59.26345443725586","59.26345443725586"
+"471334912","3599","3599","3599","60.6803092956543","60.6803092956543","60.6803092956543"
+"471859200","3603","3603","3603","60.21306610107422","60.21306610107422","60.21306610107422"
+"472383488","3607","3607","3607","59.29559326171875","59.29559326171875","59.29559326171875"
+"472907776","3611","3611","3611","58.8199462890625","58.8199462890625","58.8199462890625"
+"473432064","3615","3615","3615","58.57258605957031","58.57258605957031","58.57258605957031"
+"473956352","3619","3619","3619","60.69327163696289","60.69327163696289","60.69327163696289"
+"474480640","3623","3623","3623","59.85091018676758","59.85091018676758","59.85091018676758"
+"475004928","3627","3627","3627","61.96398162841797","61.96398162841797","61.96398162841797"
+"475529216","3631","3631","3631","59.958396911621094","59.958396911621094","59.958396911621094"
+"476053504","3635","3635","3635","59.43694305419922","59.43694305419922","59.43694305419922"
+"476577792","3639","3639","3639","60.227840423583984","60.227840423583984","60.227840423583984"
+"477102080","3643","3643","3643","59.76113510131836","59.76113510131836","59.76113510131836"
+"477626368","3647","3647","3647","61.50362777709961","61.50362777709961","61.50362777709961"
+"478150656","3651","3651","3651","61.373313903808594","61.373313903808594","61.373313903808594"
+"478674944","3655","3655","3655","59.319740295410156","59.319740295410156","59.319740295410156"
+"479199232","3659","3659","3659","61.94820022583008","61.94820022583008","61.94820022583008"
+"479723520","3663","3663","3663","60.79231643676758","60.79231643676758","60.79231643676758"
+"480247808","3667","3667","3667","58.83429718017578","58.83429718017578","58.83429718017578"
+"480772096","3671","3671","3671","60.64426803588867","60.64426803588867","60.64426803588867"
+"481296384","3675","3675","3675","59.279296875","59.279296875","59.279296875"
+"481820672","3679","3679","3679","60.297889709472656","60.297889709472656","60.297889709472656"
+"482344960","3683","3683","3683","60.42818832397461","60.42818832397461","60.42818832397461"
+"482869248","3687","3687","3687","60.17034149169922","60.17034149169922","60.17034149169922"
+"483393536","3691","3691","3691","60.23216247558594","60.23216247558594","60.23216247558594"
+"483917824","3695","3695","3695","61.651248931884766","61.651248931884766","61.651248931884766"
+"484442112","3699","3699","3699","59.11526107788086","59.11526107788086","59.11526107788086"
+"484966400","3703","3703","3703","60.84279251098633","60.84279251098633","60.84279251098633"
+"485490688","3707","3707","3707","60.854408264160156","60.854408264160156","60.854408264160156"
+"486014976","3711","3711","3711","60.21649932861328","60.21649932861328","60.21649932861328"
+"486539264","3715","3715","3715","59.33319091796875","59.33319091796875","59.33319091796875"
+"487063552","3719","3719","3719","59.90266418457031","59.90266418457031","59.90266418457031"
+"487587840","3723","3723","3723","59.75349807739258","59.75349807739258","59.75349807739258"
+"488112128","3727","3727","3727","59.24295425415039","59.24295425415039","59.24295425415039"
+"488636416","3731","3731","3731","60.97904586791992","60.97904586791992","60.97904586791992"
+"489160704","3735","3735","3735","61.48204040527344","61.48204040527344","61.48204040527344"
+"489684992","3739","3739","3739","59.98061752319336","59.98061752319336","59.98061752319336"
+"490209280","3743","3743","3743","61.221214294433594","61.221214294433594","61.221214294433594"
+"490733568","3747","3747","3747","59.11982727050781","59.11982727050781","59.11982727050781"
+"491257856","3751","3751","3751","60.33238983154297","60.33238983154297","60.33238983154297"
+"491782144","3755","3755","3755","58.62887954711914","58.62887954711914","58.62887954711914"
+"492306432","3759","3759","3759","60.920166015625","60.920166015625","60.920166015625"
+"492830720","3763","3763","3763","61.61090850830078","61.61090850830078","61.61090850830078"
+"493355008","3767","3767","3767","57.933876037597656","57.933876037597656","57.933876037597656"
+"493879296","3771","3771","3771","59.8871955871582","59.8871955871582","59.8871955871582"
+"494403584","3775","3775","3775","59.448974609375","59.448974609375","59.448974609375"
+"494927872","3779","3779","3779","59.41244888305664","59.41244888305664","59.41244888305664"
+"495452160","3783","3783","3783","59.4481086730957","59.4481086730957","59.4481086730957"
+"495976448","3787","3787","3787","59.94738006591797","59.94738006591797","59.94738006591797"
+"496500736","3791","3791","3791","60.052860260009766","60.052860260009766","60.052860260009766"
+"497025024","3795","3795","3795","62.06536102294922","62.06536102294922","62.06536102294922"
+"497549312","3799","3799","3799","61.2891960144043","61.2891960144043","61.2891960144043"
+"498073600","3803","3803","3803","58.46656036376953","58.46656036376953","58.46656036376953"
+"498597888","3807","3807","3807","61.85420227050781","61.85420227050781","61.85420227050781"
+"499122176","3811","3811","3811","61.20445251464844","61.20445251464844","61.20445251464844"
+"499646464","3815","3815","3815","60.29484176635742","60.29484176635742","60.29484176635742"
+"500170752","3819","3819","3819","60.75999069213867","60.75999069213867","60.75999069213867"
+"500695040","3823","3823","3823","60.76865768432617","60.76865768432617","60.76865768432617"
+"501219328","3827","3827","3827","60.1015510559082","60.1015510559082","60.1015510559082"
+"501743616","3831","3831","3831","60.29496765136719","60.29496765136719","60.29496765136719"
+"502267904","3835","3835","3835","58.09121322631836","58.09121322631836","58.09121322631836"
+"502792192","3839","3839","3839","60.6954460144043","60.6954460144043","60.6954460144043"
+"503316480","3843","3843","3843","62.413265228271484","62.413265228271484","62.413265228271484"
+"503840768","3847","3847","3847","58.22809600830078","58.22809600830078","58.22809600830078"
+"504365056","3851","3851","3851","60.98783874511719","60.98783874511719","60.98783874511719"
+"504889344","3855","3855","3855","60.5434684753418","60.5434684753418","60.5434684753418"
+"505413632","3859","3859","3859","58.195159912109375","58.195159912109375","58.195159912109375"
+"505937920","3863","3863","3863","60.47108840942383","60.47108840942383","60.47108840942383"
+"506462208","3867","3867","3867","60.26930618286133","60.26930618286133","60.26930618286133"
+"506986496","3871","3871","3871","59.02424621582031","59.02424621582031","59.02424621582031"
+"507510784","3875","3875","3875","61.60749816894531","61.60749816894531","61.60749816894531"
+"508035072","3879","3879","3879","59.90770721435547","59.90770721435547","59.90770721435547"
+"508559360","3883","3883","3883","60.4090461730957","60.4090461730957","60.4090461730957"
+"509083648","3887","3887","3887","61.61797332763672","61.61797332763672","61.61797332763672"
+"509607936","3891","3891","3891","61.8780403137207","61.8780403137207","61.8780403137207"
+"510132224","3895","3895","3895","63.26082992553711","63.26082992553711","63.26082992553711"
+"510656512","3899","3899","3899","59.82273864746094","59.82273864746094","59.82273864746094"
+"511180800","3903","3903","3903","60.76416015625","60.76416015625","60.76416015625"
+"511705088","3907","3907","3907","57.786468505859375","57.786468505859375","57.786468505859375"
+"512229376","3911","3911","3911","60.7449836730957","60.7449836730957","60.7449836730957"
+"512753664","3915","3915","3915","61.293479919433594","61.293479919433594","61.293479919433594"
+"513277952","3919","3919","3919","58.31304168701172","58.31304168701172","58.31304168701172"
+"513802240","3923","3923","3923","61.58084487915039","61.58084487915039","61.58084487915039"
+"514326528","3927","3927","3927","60.98858642578125","60.98858642578125","60.98858642578125"
+"514850816","3931","3931","3931","60.76093673706055","60.76093673706055","60.76093673706055"
+"515375104","3935","3935","3935","60.00802993774414","60.00802993774414","60.00802993774414"
+"515899392","3939","3939","3939","59.59425735473633","59.59425735473633","59.59425735473633"
+"516423680","3943","3943","3943","59.95510482788086","59.95510482788086","59.95510482788086"
+"516947968","3947","3947","3947","59.831111907958984","59.831111907958984","59.831111907958984"
+"517472256","3951","3951","3951","58.35224533081055","58.35224533081055","58.35224533081055"
+"517996544","3955","3955","3955","58.90814208984375","58.90814208984375","58.90814208984375"
+"518520832","3959","3959","3959","58.861732482910156","58.861732482910156","58.861732482910156"
+"519045120","3963","3963","3963","60.213035583496094","60.213035583496094","60.213035583496094"
+"519569408","3967","3967","3967","60.44744873046875","60.44744873046875","60.44744873046875"
+"520093696","3971","3971","3971","60.1468391418457","60.1468391418457","60.1468391418457"
+"520617984","3975","3975","3975","61.56852722167969","61.56852722167969","61.56852722167969"
+"521142272","3979","3979","3979","57.85920715332031","57.85920715332031","57.85920715332031"
+"521666560","3983","3983","3983","62.53982925415039","62.53982925415039","62.53982925415039"
+"522190848","3987","3987","3987","61.48202133178711","61.48202133178711","61.48202133178711"
+"522715136","3991","3991","3991","59.46062469482422","59.46062469482422","59.46062469482422"
+"523239424","3995","3995","3995","57.686981201171875","57.686981201171875","57.686981201171875"
+"523763712","3999","3999","3999","60.42996597290039","60.42996597290039","60.42996597290039"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew.csv
new file mode 100644
index 000000000..d7dfb168f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew.csv
@@ -0,0 +1,1001 @@
+"global_step","DRRandom_04-01-36-40 - _step","DRRandom_04-01-36-40 - _step__MIN","DRRandom_04-01-36-40 - _step__MAX","DRRandom_04-01-36-40 - rewards/step","DRRandom_04-01-36-40 - rewards/step__MIN","DRRandom_04-01-36-40 - rewards/step__MAX"
+"0","0","0","0","-23.526214599609375","-23.526214599609375","-23.526214599609375"
+"524288","5","5","5","-22.994211196899414","-22.994211196899414","-22.994211196899414"
+"1048576","9","9","9","-21.17962074279785","-21.17962074279785","-21.17962074279785"
+"1572864","13","13","13","-19.40107536315918","-19.40107536315918","-19.40107536315918"
+"2097152","17","17","17","-19.21596336364746","-19.21596336364746","-19.21596336364746"
+"2621440","21","21","21","-16.6650390625","-16.6650390625","-16.6650390625"
+"3145728","25","25","25","-15.960874557495117","-15.960874557495117","-15.960874557495117"
+"3670016","29","29","29","-13.611604690551758","-13.611604690551758","-13.611604690551758"
+"4194304","33","33","33","-13.760234832763672","-13.760234832763672","-13.760234832763672"
+"4718592","37","37","37","-12.706364631652832","-12.706364631652832","-12.706364631652832"
+"5242880","41","41","41","-11.743274688720703","-11.743274688720703","-11.743274688720703"
+"5767168","45","45","45","-11.312955856323242","-11.312955856323242","-11.312955856323242"
+"6291456","49","49","49","-11.831311225891113","-11.831311225891113","-11.831311225891113"
+"6815744","53","53","53","-9.809112548828125","-9.809112548828125","-9.809112548828125"
+"7340032","57","57","57","-10.217702865600586","-10.217702865600586","-10.217702865600586"
+"7864320","61","61","61","-10.19293212890625","-10.19293212890625","-10.19293212890625"
+"8388608","65","65","65","-9.55364990234375","-9.55364990234375","-9.55364990234375"
+"8912896","69","69","69","-10.058866500854492","-10.058866500854492","-10.058866500854492"
+"9437184","73","73","73","-8.56247615814209","-8.56247615814209","-8.56247615814209"
+"9961472","77","77","77","-7.999983787536621","-7.999983787536621","-7.999983787536621"
+"10485760","81","81","81","-8.097939491271973","-8.097939491271973","-8.097939491271973"
+"11010048","85","85","85","-7.44113826751709","-7.44113826751709","-7.44113826751709"
+"11534336","89","89","89","-6.968357563018799","-6.968357563018799","-6.968357563018799"
+"12058624","93","93","93","-7.306329727172852","-7.306329727172852","-7.306329727172852"
+"12582912","97","97","97","-5.555099964141846","-5.555099964141846","-5.555099964141846"
+"13107200","101","101","101","-5.1313157081604","-5.1313157081604","-5.1313157081604"
+"13631488","105","105","105","-5.48049259185791","-5.48049259185791","-5.48049259185791"
+"14155776","109","109","109","-3.9789812564849854","-3.9789812564849854","-3.9789812564849854"
+"14680064","113","113","113","-3.4834389686584473","-3.4834389686584473","-3.4834389686584473"
+"15204352","117","117","117","-2.91048526763916","-2.91048526763916","-2.91048526763916"
+"15728640","121","121","121","-4.904036045074463","-4.904036045074463","-4.904036045074463"
+"16252928","125","125","125","-3.308891773223877","-3.308891773223877","-3.308891773223877"
+"16777216","129","129","129","-3.5233218669891357","-3.5233218669891357","-3.5233218669891357"
+"17301504","133","133","133","-2.2566425800323486","-2.2566425800323486","-2.2566425800323486"
+"17825792","137","137","137","-2.021012544631958","-2.021012544631958","-2.021012544631958"
+"18350080","141","141","141","-1.0952593088150024","-1.0952593088150024","-1.0952593088150024"
+"18874368","145","145","145","-2.3064515590667725","-2.3064515590667725","-2.3064515590667725"
+"19398656","149","149","149","-0.7895950675010681","-0.7895950675010681","-0.7895950675010681"
+"19922944","153","153","153","1.0160956382751465","1.0160956382751465","1.0160956382751465"
+"20447232","157","157","157","0.5348525643348694","0.5348525643348694","0.5348525643348694"
+"20971520","161","161","161","1.406390905380249","1.406390905380249","1.406390905380249"
+"21495808","165","165","165","1.1337844133377075","1.1337844133377075","1.1337844133377075"
+"22020096","169","169","169","0.49820199608802795","0.49820199608802795","0.49820199608802795"
+"22544384","173","173","173","0.2826424539089203","0.2826424539089203","0.2826424539089203"
+"23068672","177","177","177","2.4055871963500977","2.4055871963500977","2.4055871963500977"
+"23592960","181","181","181","1.4335482120513916","1.4335482120513916","1.4335482120513916"
+"24117248","185","185","185","2.696253538131714","2.696253538131714","2.696253538131714"
+"24641536","189","189","189","2.398153066635132","2.398153066635132","2.398153066635132"
+"25165824","193","193","193","2.4099087715148926","2.4099087715148926","2.4099087715148926"
+"25690112","197","197","197","2.7465898990631104","2.7465898990631104","2.7465898990631104"
+"26214400","201","201","201","3.97249174118042","3.97249174118042","3.97249174118042"
+"26738688","205","205","205","3.346561908721924","3.346561908721924","3.346561908721924"
+"27262976","209","209","209","3.4159841537475586","3.4159841537475586","3.4159841537475586"
+"27787264","213","213","213","3.327515125274658","3.327515125274658","3.327515125274658"
+"28311552","217","217","217","5.5967912673950195","5.5967912673950195","5.5967912673950195"
+"28835840","221","221","221","4.548314571380615","4.548314571380615","4.548314571380615"
+"29360128","225","225","225","4.858432292938232","4.858432292938232","4.858432292938232"
+"29884416","229","229","229","4.444987773895264","4.444987773895264","4.444987773895264"
+"30408704","233","233","233","4.528277397155762","4.528277397155762","4.528277397155762"
+"30932992","237","237","237","4.35915994644165","4.35915994644165","4.35915994644165"
+"31457280","241","241","241","5.180097579956055","5.180097579956055","5.180097579956055"
+"31981568","245","245","245","5.711843967437744","5.711843967437744","5.711843967437744"
+"32505856","249","249","249","5.015649795532227","5.015649795532227","5.015649795532227"
+"33030144","253","253","253","5.632214069366455","5.632214069366455","5.632214069366455"
+"33554432","257","257","257","6.483635902404785","6.483635902404785","6.483635902404785"
+"34078720","261","261","261","5.238961219787598","5.238961219787598","5.238961219787598"
+"34603008","265","265","265","5.3114824295043945","5.3114824295043945","5.3114824295043945"
+"35127296","269","269","269","5.898423194885254","5.898423194885254","5.898423194885254"
+"35651584","273","273","273","5.857895851135254","5.857895851135254","5.857895851135254"
+"36175872","277","277","277","7.495978832244873","7.495978832244873","7.495978832244873"
+"36700160","281","281","281","7.69796085357666","7.69796085357666","7.69796085357666"
+"37224448","285","285","285","7.598081588745117","7.598081588745117","7.598081588745117"
+"37748736","289","289","289","7.032157897949219","7.032157897949219","7.032157897949219"
+"38273024","293","293","293","8.196883201599121","8.196883201599121","8.196883201599121"
+"38797312","297","297","297","7.076263427734375","7.076263427734375","7.076263427734375"
+"39321600","301","301","301","6.355807781219482","6.355807781219482","6.355807781219482"
+"39845888","305","305","305","6.956582069396973","6.956582069396973","6.956582069396973"
+"40370176","309","309","309","8.02377986907959","8.02377986907959","8.02377986907959"
+"40894464","313","313","313","7.461781978607178","7.461781978607178","7.461781978607178"
+"41418752","317","317","317","9.390264511108398","9.390264511108398","9.390264511108398"
+"41943040","321","321","321","8.135637283325195","8.135637283325195","8.135637283325195"
+"42467328","325","325","325","8.685413360595703","8.685413360595703","8.685413360595703"
+"42991616","329","329","329","8.45504093170166","8.45504093170166","8.45504093170166"
+"43515904","333","333","333","9.237274169921875","9.237274169921875","9.237274169921875"
+"44040192","337","337","337","9.003511428833008","9.003511428833008","9.003511428833008"
+"44564480","341","341","341","9.735776901245117","9.735776901245117","9.735776901245117"
+"45088768","345","345","345","8.842029571533203","8.842029571533203","8.842029571533203"
+"45613056","349","349","349","8.356009483337402","8.356009483337402","8.356009483337402"
+"46137344","353","353","353","8.78186321258545","8.78186321258545","8.78186321258545"
+"46661632","357","357","357","8.473501205444336","8.473501205444336","8.473501205444336"
+"47185920","361","361","361","7.875216484069824","7.875216484069824","7.875216484069824"
+"47710208","365","365","365","10.863561630249023","10.863561630249023","10.863561630249023"
+"48234496","369","369","369","10.92870807647705","10.92870807647705","10.92870807647705"
+"48758784","373","373","373","9.891996383666992","9.891996383666992","9.891996383666992"
+"49283072","377","377","377","10.581414222717285","10.581414222717285","10.581414222717285"
+"49807360","381","381","381","11.111297607421875","11.111297607421875","11.111297607421875"
+"50331648","385","385","385","11.202489852905273","11.202489852905273","11.202489852905273"
+"50855936","389","389","389","9.717202186584473","9.717202186584473","9.717202186584473"
+"51380224","393","393","393","9.249502182006836","9.249502182006836","9.249502182006836"
+"51904512","397","397","397","11.455327033996582","11.455327033996582","11.455327033996582"
+"52428800","401","401","401","12.160061836242676","12.160061836242676","12.160061836242676"
+"52953088","405","405","405","11.170998573303223","11.170998573303223","11.170998573303223"
+"53477376","409","409","409","10.826078414916992","10.826078414916992","10.826078414916992"
+"54001664","413","413","413","13.39550495147705","13.39550495147705","13.39550495147705"
+"54525952","417","417","417","11.6703462600708","11.6703462600708","11.6703462600708"
+"55050240","421","421","421","12.425067901611328","12.425067901611328","12.425067901611328"
+"55574528","425","425","425","12.645621299743652","12.645621299743652","12.645621299743652"
+"56098816","429","429","429","12.416131019592285","12.416131019592285","12.416131019592285"
+"56623104","433","433","433","13.557757377624512","13.557757377624512","13.557757377624512"
+"57147392","437","437","437","12.933839797973633","12.933839797973633","12.933839797973633"
+"57671680","441","441","441","12.24813175201416","12.24813175201416","12.24813175201416"
+"58195968","445","445","445","13.285407066345215","13.285407066345215","13.285407066345215"
+"58720256","449","449","449","12.08979606628418","12.08979606628418","12.08979606628418"
+"59244544","453","453","453","11.925048828125","11.925048828125","11.925048828125"
+"59768832","457","457","457","12.318099021911621","12.318099021911621","12.318099021911621"
+"60293120","461","461","461","13.294046401977539","13.294046401977539","13.294046401977539"
+"60817408","465","465","465","11.868478775024414","11.868478775024414","11.868478775024414"
+"61341696","469","469","469","14.093385696411133","14.093385696411133","14.093385696411133"
+"61865984","473","473","473","12.793441772460938","12.793441772460938","12.793441772460938"
+"62390272","477","477","477","12.845634460449219","12.845634460449219","12.845634460449219"
+"62914560","481","481","481","13.926803588867188","13.926803588867188","13.926803588867188"
+"63438848","485","485","485","14.211867332458496","14.211867332458496","14.211867332458496"
+"63963136","489","489","489","14.255495071411133","14.255495071411133","14.255495071411133"
+"64487424","493","493","493","13.504536628723145","13.504536628723145","13.504536628723145"
+"65011712","497","497","497","14.64664363861084","14.64664363861084","14.64664363861084"
+"65536000","501","501","501","13.615312576293945","13.615312576293945","13.615312576293945"
+"66060288","505","505","505","13.114545822143555","13.114545822143555","13.114545822143555"
+"66584576","509","509","509","15.031878471374512","15.031878471374512","15.031878471374512"
+"67108864","513","513","513","14.217687606811523","14.217687606811523","14.217687606811523"
+"67633152","517","517","517","12.881147384643555","12.881147384643555","12.881147384643555"
+"68157440","521","521","521","13.610173225402832","13.610173225402832","13.610173225402832"
+"68681728","525","525","525","14.072223663330078","14.072223663330078","14.072223663330078"
+"69206016","529","529","529","14.5737943649292","14.5737943649292","14.5737943649292"
+"69730304","533","533","533","14.36269474029541","14.36269474029541","14.36269474029541"
+"70254592","537","537","537","14.458353996276855","14.458353996276855","14.458353996276855"
+"70778880","541","541","541","13.039351463317871","13.039351463317871","13.039351463317871"
+"71303168","545","545","545","14.832974433898926","14.832974433898926","14.832974433898926"
+"71827456","549","549","549","15.995213508605957","15.995213508605957","15.995213508605957"
+"72351744","553","553","553","14.184707641601562","14.184707641601562","14.184707641601562"
+"72876032","557","557","557","13.48001480102539","13.48001480102539","13.48001480102539"
+"73400320","561","561","561","14.84802532196045","14.84802532196045","14.84802532196045"
+"73924608","565","565","565","14.988025665283203","14.988025665283203","14.988025665283203"
+"74448896","569","569","569","15.083688735961914","15.083688735961914","15.083688735961914"
+"74973184","573","573","573","13.321744918823242","13.321744918823242","13.321744918823242"
+"75497472","577","577","577","14.231606483459473","14.231606483459473","14.231606483459473"
+"76021760","581","581","581","15.187663078308105","15.187663078308105","15.187663078308105"
+"76546048","585","585","585","16.567981719970703","16.567981719970703","16.567981719970703"
+"77070336","589","589","589","14.17117691040039","14.17117691040039","14.17117691040039"
+"77594624","593","593","593","14.805374145507812","14.805374145507812","14.805374145507812"
+"78118912","597","597","597","14.506991386413574","14.506991386413574","14.506991386413574"
+"78643200","601","601","601","15.177936553955078","15.177936553955078","15.177936553955078"
+"79167488","605","605","605","14.984538078308105","14.984538078308105","14.984538078308105"
+"79691776","609","609","609","14.295291900634766","14.295291900634766","14.295291900634766"
+"80216064","613","613","613","16.02602767944336","16.02602767944336","16.02602767944336"
+"80740352","617","617","617","15.80523681640625","15.80523681640625","15.80523681640625"
+"81264640","621","621","621","14.19070816040039","14.19070816040039","14.19070816040039"
+"81788928","625","625","625","15.096528053283691","15.096528053283691","15.096528053283691"
+"82313216","629","629","629","15.63527774810791","15.63527774810791","15.63527774810791"
+"82837504","633","633","633","15.652462005615234","15.652462005615234","15.652462005615234"
+"83361792","637","637","637","16.2967529296875","16.2967529296875","16.2967529296875"
+"83886080","641","641","641","16.67084503173828","16.67084503173828","16.67084503173828"
+"84410368","645","645","645","16.566181182861328","16.566181182861328","16.566181182861328"
+"84934656","649","649","649","15.385445594787598","15.385445594787598","15.385445594787598"
+"85458944","653","653","653","17.715370178222656","17.715370178222656","17.715370178222656"
+"85983232","657","657","657","15.970561027526855","15.970561027526855","15.970561027526855"
+"86507520","661","661","661","18.263521194458008","18.263521194458008","18.263521194458008"
+"87031808","665","665","665","17.351469039916992","17.351469039916992","17.351469039916992"
+"87556096","669","669","669","16.560077667236328","16.560077667236328","16.560077667236328"
+"88080384","673","673","673","17.897634506225586","17.897634506225586","17.897634506225586"
+"88604672","677","677","677","17.310874938964844","17.310874938964844","17.310874938964844"
+"89128960","681","681","681","18.29283332824707","18.29283332824707","18.29283332824707"
+"89653248","685","685","685","16.425058364868164","16.425058364868164","16.425058364868164"
+"90177536","689","689","689","16.884002685546875","16.884002685546875","16.884002685546875"
+"90701824","693","693","693","16.1484317779541","16.1484317779541","16.1484317779541"
+"91226112","697","697","697","16.963987350463867","16.963987350463867","16.963987350463867"
+"91750400","701","701","701","17.442874908447266","17.442874908447266","17.442874908447266"
+"92274688","705","705","705","16.396068572998047","16.396068572998047","16.396068572998047"
+"92798976","709","709","709","16.272077560424805","16.272077560424805","16.272077560424805"
+"93323264","713","713","713","16.53850555419922","16.53850555419922","16.53850555419922"
+"93847552","717","717","717","17.38491439819336","17.38491439819336","17.38491439819336"
+"94371840","721","721","721","15.965706825256348","15.965706825256348","15.965706825256348"
+"94896128","725","725","725","17.038002014160156","17.038002014160156","17.038002014160156"
+"95420416","729","729","729","17.55840301513672","17.55840301513672","17.55840301513672"
+"95944704","733","733","733","16.809335708618164","16.809335708618164","16.809335708618164"
+"96468992","737","737","737","16.871936798095703","16.871936798095703","16.871936798095703"
+"96993280","741","741","741","15.455503463745117","15.455503463745117","15.455503463745117"
+"97517568","745","745","745","17.690086364746094","17.690086364746094","17.690086364746094"
+"98041856","749","749","749","15.902101516723633","15.902101516723633","15.902101516723633"
+"98566144","753","753","753","16.764707565307617","16.764707565307617","16.764707565307617"
+"99090432","757","757","757","15.998292922973633","15.998292922973633","15.998292922973633"
+"99614720","761","761","761","17.107608795166016","17.107608795166016","17.107608795166016"
+"100139008","765","765","765","17.985027313232422","17.985027313232422","17.985027313232422"
+"100663296","769","769","769","17.392263412475586","17.392263412475586","17.392263412475586"
+"101187584","773","773","773","16.993005752563477","16.993005752563477","16.993005752563477"
+"101711872","777","777","777","17.269752502441406","17.269752502441406","17.269752502441406"
+"102236160","781","781","781","17.84700584411621","17.84700584411621","17.84700584411621"
+"102760448","785","785","785","16.59161376953125","16.59161376953125","16.59161376953125"
+"103284736","789","789","789","18.790855407714844","18.790855407714844","18.790855407714844"
+"103809024","793","793","793","16.701332092285156","16.701332092285156","16.701332092285156"
+"104333312","797","797","797","17.463119506835938","17.463119506835938","17.463119506835938"
+"104857600","801","801","801","17.86277961730957","17.86277961730957","17.86277961730957"
+"105381888","805","805","805","17.67930793762207","17.67930793762207","17.67930793762207"
+"105906176","809","809","809","16.704235076904297","16.704235076904297","16.704235076904297"
+"106430464","813","813","813","17.214380264282227","17.214380264282227","17.214380264282227"
+"106954752","817","817","817","17.956201553344727","17.956201553344727","17.956201553344727"
+"107479040","821","821","821","17.487735748291016","17.487735748291016","17.487735748291016"
+"108003328","825","825","825","16.650890350341797","16.650890350341797","16.650890350341797"
+"108527616","829","829","829","17.702327728271484","17.702327728271484","17.702327728271484"
+"109051904","833","833","833","18.731836318969727","18.731836318969727","18.731836318969727"
+"109576192","837","837","837","17.77153778076172","17.77153778076172","17.77153778076172"
+"110100480","841","841","841","16.265533447265625","16.265533447265625","16.265533447265625"
+"110624768","845","845","845","16.20798110961914","16.20798110961914","16.20798110961914"
+"111149056","849","849","849","16.805805206298828","16.805805206298828","16.805805206298828"
+"111673344","853","853","853","18.205427169799805","18.205427169799805","18.205427169799805"
+"112197632","857","857","857","15.137115478515625","15.137115478515625","15.137115478515625"
+"112721920","861","861","861","18.92324447631836","18.92324447631836","18.92324447631836"
+"113246208","865","865","865","17.50577163696289","17.50577163696289","17.50577163696289"
+"113770496","869","869","869","17.724130630493164","17.724130630493164","17.724130630493164"
+"114294784","873","873","873","18.013927459716797","18.013927459716797","18.013927459716797"
+"114819072","877","877","877","17.67316436767578","17.67316436767578","17.67316436767578"
+"115343360","881","881","881","18.29081153869629","18.29081153869629","18.29081153869629"
+"115867648","885","885","885","17.222124099731445","17.222124099731445","17.222124099731445"
+"116391936","889","889","889","15.867828369140625","15.867828369140625","15.867828369140625"
+"116916224","893","893","893","17.77008056640625","17.77008056640625","17.77008056640625"
+"117440512","897","897","897","19.53740882873535","19.53740882873535","19.53740882873535"
+"117964800","901","901","901","17.444637298583984","17.444637298583984","17.444637298583984"
+"118489088","905","905","905","17.575620651245117","17.575620651245117","17.575620651245117"
+"119013376","909","909","909","18.102182388305664","18.102182388305664","18.102182388305664"
+"119537664","913","913","913","17.76811981201172","17.76811981201172","17.76811981201172"
+"120061952","917","917","917","19.237674713134766","19.237674713134766","19.237674713134766"
+"120586240","921","921","921","19.45903205871582","19.45903205871582","19.45903205871582"
+"121110528","925","925","925","17.631460189819336","17.631460189819336","17.631460189819336"
+"121634816","929","929","929","18.288610458374023","18.288610458374023","18.288610458374023"
+"122159104","933","933","933","18.93093490600586","18.93093490600586","18.93093490600586"
+"122683392","937","937","937","19.945600509643555","19.945600509643555","19.945600509643555"
+"123207680","941","941","941","18.339038848876953","18.339038848876953","18.339038848876953"
+"123731968","945","945","945","18.302593231201172","18.302593231201172","18.302593231201172"
+"124256256","949","949","949","18.15715980529785","18.15715980529785","18.15715980529785"
+"124780544","953","953","953","17.94386863708496","17.94386863708496","17.94386863708496"
+"125304832","957","957","957","17.260969161987305","17.260969161987305","17.260969161987305"
+"125829120","961","961","961","19.87352180480957","19.87352180480957","19.87352180480957"
+"126353408","965","965","965","19.03064727783203","19.03064727783203","19.03064727783203"
+"126877696","969","969","969","19.035905838012695","19.035905838012695","19.035905838012695"
+"127401984","973","973","973","19.56495475769043","19.56495475769043","19.56495475769043"
+"127926272","977","977","977","18.90170669555664","18.90170669555664","18.90170669555664"
+"128450560","981","981","981","16.69009017944336","16.69009017944336","16.69009017944336"
+"128974848","985","985","985","20.09821319580078","20.09821319580078","20.09821319580078"
+"129499136","989","989","989","18.921838760375977","18.921838760375977","18.921838760375977"
+"130023424","993","993","993","19.033994674682617","19.033994674682617","19.033994674682617"
+"130547712","997","997","997","19.97804832458496","19.97804832458496","19.97804832458496"
+"131072000","1001","1001","1001","18.95407485961914","18.95407485961914","18.95407485961914"
+"131596288","1005","1005","1005","17.053464889526367","17.053464889526367","17.053464889526367"
+"132120576","1009","1009","1009","18.605226516723633","18.605226516723633","18.605226516723633"
+"132644864","1013","1013","1013","18.444868087768555","18.444868087768555","18.444868087768555"
+"133169152","1017","1017","1017","19.311338424682617","19.311338424682617","19.311338424682617"
+"133693440","1021","1021","1021","17.823732376098633","17.823732376098633","17.823732376098633"
+"134217728","1025","1025","1025","18.34840202331543","18.34840202331543","18.34840202331543"
+"134742016","1029","1029","1029","18.89936637878418","18.89936637878418","18.89936637878418"
+"135266304","1033","1033","1033","17.103801727294922","17.103801727294922","17.103801727294922"
+"135790592","1037","1037","1037","20.090726852416992","20.090726852416992","20.090726852416992"
+"136314880","1041","1041","1041","20.04531478881836","20.04531478881836","20.04531478881836"
+"136839168","1045","1045","1045","19.39667510986328","19.39667510986328","19.39667510986328"
+"137363456","1049","1049","1049","20.140832901000977","20.140832901000977","20.140832901000977"
+"137887744","1053","1053","1053","18.41566276550293","18.41566276550293","18.41566276550293"
+"138412032","1057","1057","1057","20.79224967956543","20.79224967956543","20.79224967956543"
+"138936320","1061","1061","1061","18.63809585571289","18.63809585571289","18.63809585571289"
+"139460608","1065","1065","1065","20.733606338500977","20.733606338500977","20.733606338500977"
+"139984896","1069","1069","1069","17.112146377563477","17.112146377563477","17.112146377563477"
+"140509184","1073","1073","1073","19.06810760498047","19.06810760498047","19.06810760498047"
+"141033472","1077","1077","1077","17.50244140625","17.50244140625","17.50244140625"
+"141557760","1081","1081","1081","18.958232879638672","18.958232879638672","18.958232879638672"
+"142082048","1085","1085","1085","19.678985595703125","19.678985595703125","19.678985595703125"
+"142606336","1089","1089","1089","18.804880142211914","18.804880142211914","18.804880142211914"
+"143130624","1093","1093","1093","19.926301956176758","19.926301956176758","19.926301956176758"
+"143654912","1097","1097","1097","20.809574127197266","20.809574127197266","20.809574127197266"
+"144179200","1101","1101","1101","19.68830680847168","19.68830680847168","19.68830680847168"
+"144703488","1105","1105","1105","20.323955535888672","20.323955535888672","20.323955535888672"
+"145227776","1109","1109","1109","19.482879638671875","19.482879638671875","19.482879638671875"
+"145752064","1113","1113","1113","18.735668182373047","18.735668182373047","18.735668182373047"
+"146276352","1117","1117","1117","20.530317306518555","20.530317306518555","20.530317306518555"
+"146800640","1121","1121","1121","19.84680938720703","19.84680938720703","19.84680938720703"
+"147324928","1125","1125","1125","20.3435001373291","20.3435001373291","20.3435001373291"
+"147849216","1129","1129","1129","19.566450119018555","19.566450119018555","19.566450119018555"
+"148373504","1133","1133","1133","18.7947940826416","18.7947940826416","18.7947940826416"
+"148897792","1137","1137","1137","20.646312713623047","20.646312713623047","20.646312713623047"
+"149422080","1141","1141","1141","21.101102828979492","21.101102828979492","21.101102828979492"
+"149946368","1145","1145","1145","21.168840408325195","21.168840408325195","21.168840408325195"
+"150470656","1149","1149","1149","20.98623275756836","20.98623275756836","20.98623275756836"
+"150994944","1153","1153","1153","22.0360050201416","22.0360050201416","22.0360050201416"
+"151519232","1157","1157","1157","20.00628662109375","20.00628662109375","20.00628662109375"
+"152043520","1161","1161","1161","21.690837860107422","21.690837860107422","21.690837860107422"
+"152567808","1165","1165","1165","20.03672218322754","20.03672218322754","20.03672218322754"
+"153092096","1169","1169","1169","20.100364685058594","20.100364685058594","20.100364685058594"
+"153616384","1173","1173","1173","19.22365951538086","19.22365951538086","19.22365951538086"
+"154140672","1177","1177","1177","20.53072738647461","20.53072738647461","20.53072738647461"
+"154664960","1181","1181","1181","20.65635871887207","20.65635871887207","20.65635871887207"
+"155189248","1185","1185","1185","19.94749641418457","19.94749641418457","19.94749641418457"
+"155713536","1189","1189","1189","19.074411392211914","19.074411392211914","19.074411392211914"
+"156237824","1193","1193","1193","20.407791137695312","20.407791137695312","20.407791137695312"
+"156762112","1197","1197","1197","21.590404510498047","21.590404510498047","21.590404510498047"
+"157286400","1201","1201","1201","20.276805877685547","20.276805877685547","20.276805877685547"
+"157810688","1205","1205","1205","20.114177703857422","20.114177703857422","20.114177703857422"
+"158334976","1209","1209","1209","19.68995475769043","19.68995475769043","19.68995475769043"
+"158859264","1213","1213","1213","20.724609375","20.724609375","20.724609375"
+"159383552","1217","1217","1217","20.660024642944336","20.660024642944336","20.660024642944336"
+"159907840","1221","1221","1221","21.72004508972168","21.72004508972168","21.72004508972168"
+"160432128","1225","1225","1225","20.3411865234375","20.3411865234375","20.3411865234375"
+"160956416","1229","1229","1229","21.670373916625977","21.670373916625977","21.670373916625977"
+"161480704","1233","1233","1233","20.68627166748047","20.68627166748047","20.68627166748047"
+"162004992","1237","1237","1237","22.88677978515625","22.88677978515625","22.88677978515625"
+"162529280","1241","1241","1241","19.746999740600586","19.746999740600586","19.746999740600586"
+"163053568","1245","1245","1245","21.57329559326172","21.57329559326172","21.57329559326172"
+"163577856","1249","1249","1249","21.742496490478516","21.742496490478516","21.742496490478516"
+"164102144","1253","1253","1253","21.07940673828125","21.07940673828125","21.07940673828125"
+"164626432","1257","1257","1257","21.93360710144043","21.93360710144043","21.93360710144043"
+"165150720","1261","1261","1261","20.649383544921875","20.649383544921875","20.649383544921875"
+"165675008","1265","1265","1265","21.320709228515625","21.320709228515625","21.320709228515625"
+"166199296","1269","1269","1269","21.199941635131836","21.199941635131836","21.199941635131836"
+"166723584","1273","1273","1273","21.394664764404297","21.394664764404297","21.394664764404297"
+"167247872","1277","1277","1277","21.74620819091797","21.74620819091797","21.74620819091797"
+"167772160","1281","1281","1281","21.925777435302734","21.925777435302734","21.925777435302734"
+"168296448","1285","1285","1285","21.326128005981445","21.326128005981445","21.326128005981445"
+"168820736","1289","1289","1289","22.95232391357422","22.95232391357422","22.95232391357422"
+"169345024","1293","1293","1293","19.294021606445312","19.294021606445312","19.294021606445312"
+"169869312","1297","1297","1297","22.264944076538086","22.264944076538086","22.264944076538086"
+"170393600","1301","1301","1301","21.08346176147461","21.08346176147461","21.08346176147461"
+"170917888","1305","1305","1305","20.475942611694336","20.475942611694336","20.475942611694336"
+"171442176","1309","1309","1309","21.852764129638672","21.852764129638672","21.852764129638672"
+"171966464","1313","1313","1313","22.760475158691406","22.760475158691406","22.760475158691406"
+"172490752","1317","1317","1317","22.602746963500977","22.602746963500977","22.602746963500977"
+"173015040","1321","1321","1321","21.87034797668457","21.87034797668457","21.87034797668457"
+"173539328","1325","1325","1325","21.34390640258789","21.34390640258789","21.34390640258789"
+"174063616","1329","1329","1329","21.359289169311523","21.359289169311523","21.359289169311523"
+"174587904","1333","1333","1333","21.15892791748047","21.15892791748047","21.15892791748047"
+"175112192","1337","1337","1337","22.49742889404297","22.49742889404297","22.49742889404297"
+"175636480","1341","1341","1341","22.084930419921875","22.084930419921875","22.084930419921875"
+"176160768","1345","1345","1345","22.35869026184082","22.35869026184082","22.35869026184082"
+"176685056","1349","1349","1349","22.68336296081543","22.68336296081543","22.68336296081543"
+"177209344","1353","1353","1353","21.627092361450195","21.627092361450195","21.627092361450195"
+"177733632","1357","1357","1357","21.424203872680664","21.424203872680664","21.424203872680664"
+"178257920","1361","1361","1361","23.195480346679688","23.195480346679688","23.195480346679688"
+"178782208","1365","1365","1365","23.203197479248047","23.203197479248047","23.203197479248047"
+"179306496","1369","1369","1369","22.91529655456543","22.91529655456543","22.91529655456543"
+"179830784","1373","1373","1373","22.704946517944336","22.704946517944336","22.704946517944336"
+"180355072","1377","1377","1377","21.412776947021484","21.412776947021484","21.412776947021484"
+"180879360","1381","1381","1381","22.230804443359375","22.230804443359375","22.230804443359375"
+"181403648","1385","1385","1385","22.22483253479004","22.22483253479004","22.22483253479004"
+"181927936","1389","1389","1389","22.24211883544922","22.24211883544922","22.24211883544922"
+"182452224","1393","1393","1393","21.054906845092773","21.054906845092773","21.054906845092773"
+"182976512","1397","1397","1397","21.66803741455078","21.66803741455078","21.66803741455078"
+"183500800","1401","1401","1401","23.816190719604492","23.816190719604492","23.816190719604492"
+"184025088","1405","1405","1405","22.68573760986328","22.68573760986328","22.68573760986328"
+"184549376","1409","1409","1409","23.052291870117188","23.052291870117188","23.052291870117188"
+"185073664","1413","1413","1413","22.981727600097656","22.981727600097656","22.981727600097656"
+"185597952","1417","1417","1417","23.066869735717773","23.066869735717773","23.066869735717773"
+"186122240","1421","1421","1421","22.162372589111328","22.162372589111328","22.162372589111328"
+"186646528","1425","1425","1425","22.000436782836914","22.000436782836914","22.000436782836914"
+"187170816","1429","1429","1429","23.527990341186523","23.527990341186523","23.527990341186523"
+"187695104","1433","1433","1433","22.694116592407227","22.694116592407227","22.694116592407227"
+"188219392","1437","1437","1437","23.55553436279297","23.55553436279297","23.55553436279297"
+"188743680","1441","1441","1441","23.333036422729492","23.333036422729492","23.333036422729492"
+"189267968","1445","1445","1445","24.270410537719727","24.270410537719727","24.270410537719727"
+"189792256","1449","1449","1449","23.168195724487305","23.168195724487305","23.168195724487305"
+"190316544","1453","1453","1453","22.74358558654785","22.74358558654785","22.74358558654785"
+"190840832","1457","1457","1457","23.148221969604492","23.148221969604492","23.148221969604492"
+"191365120","1461","1461","1461","22.77355194091797","22.77355194091797","22.77355194091797"
+"191889408","1465","1465","1465","22.89710235595703","22.89710235595703","22.89710235595703"
+"192413696","1469","1469","1469","22.23617935180664","22.23617935180664","22.23617935180664"
+"192937984","1473","1473","1473","22.423553466796875","22.423553466796875","22.423553466796875"
+"193462272","1477","1477","1477","23.25737953186035","23.25737953186035","23.25737953186035"
+"193986560","1481","1481","1481","22.52599334716797","22.52599334716797","22.52599334716797"
+"194510848","1485","1485","1485","23.740507125854492","23.740507125854492","23.740507125854492"
+"195035136","1489","1489","1489","22.005475997924805","22.005475997924805","22.005475997924805"
+"195559424","1493","1493","1493","23.080644607543945","23.080644607543945","23.080644607543945"
+"196083712","1497","1497","1497","23.824359893798828","23.824359893798828","23.824359893798828"
+"196608000","1501","1501","1501","21.46715545654297","21.46715545654297","21.46715545654297"
+"197132288","1505","1505","1505","24.200946807861328","24.200946807861328","24.200946807861328"
+"197656576","1509","1509","1509","23.44317626953125","23.44317626953125","23.44317626953125"
+"198180864","1513","1513","1513","22.482362747192383","22.482362747192383","22.482362747192383"
+"198705152","1517","1517","1517","23.63792610168457","23.63792610168457","23.63792610168457"
+"199229440","1521","1521","1521","22.806243896484375","22.806243896484375","22.806243896484375"
+"199753728","1525","1525","1525","21.941919326782227","21.941919326782227","21.941919326782227"
+"200278016","1529","1529","1529","22.14963150024414","22.14963150024414","22.14963150024414"
+"200802304","1533","1533","1533","23.58561897277832","23.58561897277832","23.58561897277832"
+"201326592","1537","1537","1537","24.073434829711914","24.073434829711914","24.073434829711914"
+"201850880","1541","1541","1541","22.329309463500977","22.329309463500977","22.329309463500977"
+"202375168","1545","1545","1545","22.6103515625","22.6103515625","22.6103515625"
+"202899456","1549","1549","1549","22.84874725341797","22.84874725341797","22.84874725341797"
+"203423744","1553","1553","1553","22.332685470581055","22.332685470581055","22.332685470581055"
+"203948032","1557","1557","1557","23.452688217163086","23.452688217163086","23.452688217163086"
+"204472320","1561","1561","1561","24.547428131103516","24.547428131103516","24.547428131103516"
+"204996608","1565","1565","1565","23.11661148071289","23.11661148071289","23.11661148071289"
+"205520896","1569","1569","1569","23.63306427001953","23.63306427001953","23.63306427001953"
+"206045184","1573","1573","1573","21.95720672607422","21.95720672607422","21.95720672607422"
+"206569472","1577","1577","1577","24.62854766845703","24.62854766845703","24.62854766845703"
+"207093760","1581","1581","1581","22.660934448242188","22.660934448242188","22.660934448242188"
+"207618048","1585","1585","1585","23.189958572387695","23.189958572387695","23.189958572387695"
+"208142336","1589","1589","1589","22.267324447631836","22.267324447631836","22.267324447631836"
+"208666624","1593","1593","1593","23.830814361572266","23.830814361572266","23.830814361572266"
+"209190912","1597","1597","1597","24.526378631591797","24.526378631591797","24.526378631591797"
+"209715200","1601","1601","1601","23.598012924194336","23.598012924194336","23.598012924194336"
+"210239488","1605","1605","1605","23.645320892333984","23.645320892333984","23.645320892333984"
+"210763776","1609","1609","1609","22.873449325561523","22.873449325561523","22.873449325561523"
+"211288064","1613","1613","1613","23.954872131347656","23.954872131347656","23.954872131347656"
+"211812352","1617","1617","1617","22.254413604736328","22.254413604736328","22.254413604736328"
+"212336640","1621","1621","1621","24.150447845458984","24.150447845458984","24.150447845458984"
+"212860928","1625","1625","1625","23.54986000061035","23.54986000061035","23.54986000061035"
+"213385216","1629","1629","1629","23.344562530517578","23.344562530517578","23.344562530517578"
+"213909504","1633","1633","1633","21.659135818481445","21.659135818481445","21.659135818481445"
+"214433792","1637","1637","1637","23.93239402770996","23.93239402770996","23.93239402770996"
+"214958080","1641","1641","1641","23.193490982055664","23.193490982055664","23.193490982055664"
+"215482368","1645","1645","1645","23.0076904296875","23.0076904296875","23.0076904296875"
+"216006656","1649","1649","1649","23.79112434387207","23.79112434387207","23.79112434387207"
+"216530944","1653","1653","1653","23.945226669311523","23.945226669311523","23.945226669311523"
+"217055232","1657","1657","1657","24.325695037841797","24.325695037841797","24.325695037841797"
+"217579520","1661","1661","1661","22.726764678955078","22.726764678955078","22.726764678955078"
+"218103808","1665","1665","1665","24.472341537475586","24.472341537475586","24.472341537475586"
+"218628096","1669","1669","1669","24.79014015197754","24.79014015197754","24.79014015197754"
+"219152384","1673","1673","1673","22.717689514160156","22.717689514160156","22.717689514160156"
+"219676672","1677","1677","1677","24.687816619873047","24.687816619873047","24.687816619873047"
+"220200960","1681","1681","1681","22.4017276763916","22.4017276763916","22.4017276763916"
+"220725248","1685","1685","1685","23.580427169799805","23.580427169799805","23.580427169799805"
+"221249536","1689","1689","1689","23.165719985961914","23.165719985961914","23.165719985961914"
+"221773824","1693","1693","1693","23.789119720458984","23.789119720458984","23.789119720458984"
+"222298112","1697","1697","1697","24.15776252746582","24.15776252746582","24.15776252746582"
+"222822400","1701","1701","1701","23.87459373474121","23.87459373474121","23.87459373474121"
+"223346688","1705","1705","1705","23.6396427154541","23.6396427154541","23.6396427154541"
+"223870976","1709","1709","1709","23.846471786499023","23.846471786499023","23.846471786499023"
+"224395264","1713","1713","1713","24.213085174560547","24.213085174560547","24.213085174560547"
+"224919552","1717","1717","1717","23.429533004760742","23.429533004760742","23.429533004760742"
+"225443840","1721","1721","1721","24.626441955566406","24.626441955566406","24.626441955566406"
+"225968128","1725","1725","1725","23.64611053466797","23.64611053466797","23.64611053466797"
+"226492416","1729","1729","1729","23.963668823242188","23.963668823242188","23.963668823242188"
+"227016704","1733","1733","1733","25.661073684692383","25.661073684692383","25.661073684692383"
+"227540992","1737","1737","1737","25.388683319091797","25.388683319091797","25.388683319091797"
+"228065280","1741","1741","1741","23.60181427001953","23.60181427001953","23.60181427001953"
+"228589568","1745","1745","1745","25.180248260498047","25.180248260498047","25.180248260498047"
+"229113856","1749","1749","1749","23.393850326538086","23.393850326538086","23.393850326538086"
+"229638144","1753","1753","1753","23.944414138793945","23.944414138793945","23.944414138793945"
+"230162432","1757","1757","1757","22.937625885009766","22.937625885009766","22.937625885009766"
+"230686720","1761","1761","1761","25.160919189453125","25.160919189453125","25.160919189453125"
+"231211008","1765","1765","1765","23.63105010986328","23.63105010986328","23.63105010986328"
+"231735296","1769","1769","1769","24.694843292236328","24.694843292236328","24.694843292236328"
+"232259584","1773","1773","1773","23.313310623168945","23.313310623168945","23.313310623168945"
+"232783872","1777","1777","1777","24.750062942504883","24.750062942504883","24.750062942504883"
+"233308160","1781","1781","1781","23.803552627563477","23.803552627563477","23.803552627563477"
+"233832448","1785","1785","1785","23.552433013916016","23.552433013916016","23.552433013916016"
+"234356736","1789","1789","1789","23.05740737915039","23.05740737915039","23.05740737915039"
+"234881024","1793","1793","1793","24.11182403564453","24.11182403564453","24.11182403564453"
+"235405312","1797","1797","1797","23.42162322998047","23.42162322998047","23.42162322998047"
+"235929600","1801","1801","1801","25.64834976196289","25.64834976196289","25.64834976196289"
+"236453888","1805","1805","1805","24.49558448791504","24.49558448791504","24.49558448791504"
+"236978176","1809","1809","1809","24.997060775756836","24.997060775756836","24.997060775756836"
+"237502464","1813","1813","1813","23.548200607299805","23.548200607299805","23.548200607299805"
+"238026752","1817","1817","1817","26.51605987548828","26.51605987548828","26.51605987548828"
+"238551040","1821","1821","1821","24.90121078491211","24.90121078491211","24.90121078491211"
+"239075328","1825","1825","1825","24.93843650817871","24.93843650817871","24.93843650817871"
+"239599616","1829","1829","1829","22.98322868347168","22.98322868347168","22.98322868347168"
+"240123904","1833","1833","1833","23.82862663269043","23.82862663269043","23.82862663269043"
+"240648192","1837","1837","1837","26.05046844482422","26.05046844482422","26.05046844482422"
+"241172480","1841","1841","1841","24.8929386138916","24.8929386138916","24.8929386138916"
+"241696768","1845","1845","1845","25.25403594970703","25.25403594970703","25.25403594970703"
+"242221056","1849","1849","1849","23.793514251708984","23.793514251708984","23.793514251708984"
+"242745344","1853","1853","1853","24.22068977355957","24.22068977355957","24.22068977355957"
+"243269632","1857","1857","1857","25.423274993896484","25.423274993896484","25.423274993896484"
+"243793920","1861","1861","1861","25.433719635009766","25.433719635009766","25.433719635009766"
+"244318208","1865","1865","1865","25.959794998168945","25.959794998168945","25.959794998168945"
+"244842496","1869","1869","1869","24.296083450317383","24.296083450317383","24.296083450317383"
+"245366784","1873","1873","1873","25.6658878326416","25.6658878326416","25.6658878326416"
+"245891072","1877","1877","1877","25.833234786987305","25.833234786987305","25.833234786987305"
+"246415360","1881","1881","1881","25.490015029907227","25.490015029907227","25.490015029907227"
+"246939648","1885","1885","1885","25.077777862548828","25.077777862548828","25.077777862548828"
+"247463936","1889","1889","1889","25.574548721313477","25.574548721313477","25.574548721313477"
+"247988224","1893","1893","1893","24.207265853881836","24.207265853881836","24.207265853881836"
+"248512512","1897","1897","1897","25.66935920715332","25.66935920715332","25.66935920715332"
+"249036800","1901","1901","1901","24.765958786010742","24.765958786010742","24.765958786010742"
+"249561088","1905","1905","1905","24.56288719177246","24.56288719177246","24.56288719177246"
+"250085376","1909","1909","1909","27.403730392456055","27.403730392456055","27.403730392456055"
+"250609664","1913","1913","1913","25.45460319519043","25.45460319519043","25.45460319519043"
+"251133952","1917","1917","1917","24.127538681030273","24.127538681030273","24.127538681030273"
+"251658240","1921","1921","1921","24.880578994750977","24.880578994750977","24.880578994750977"
+"252182528","1925","1925","1925","24.94021224975586","24.94021224975586","24.94021224975586"
+"252706816","1929","1929","1929","24.914255142211914","24.914255142211914","24.914255142211914"
+"253231104","1933","1933","1933","25.412757873535156","25.412757873535156","25.412757873535156"
+"253755392","1937","1937","1937","24.388187408447266","24.388187408447266","24.388187408447266"
+"254279680","1941","1941","1941","24.13939094543457","24.13939094543457","24.13939094543457"
+"254803968","1945","1945","1945","25.322845458984375","25.322845458984375","25.322845458984375"
+"255328256","1949","1949","1949","24.74098014831543","24.74098014831543","24.74098014831543"
+"255852544","1953","1953","1953","23.853315353393555","23.853315353393555","23.853315353393555"
+"256376832","1957","1957","1957","25.68372917175293","25.68372917175293","25.68372917175293"
+"256901120","1961","1961","1961","24.438180923461914","24.438180923461914","24.438180923461914"
+"257425408","1965","1965","1965","25.31140899658203","25.31140899658203","25.31140899658203"
+"257949696","1969","1969","1969","26.34123420715332","26.34123420715332","26.34123420715332"
+"258473984","1973","1973","1973","24.26748275756836","24.26748275756836","24.26748275756836"
+"258998272","1977","1977","1977","25.117231369018555","25.117231369018555","25.117231369018555"
+"259522560","1981","1981","1981","23.20004653930664","23.20004653930664","23.20004653930664"
+"260046848","1985","1985","1985","27.06376838684082","27.06376838684082","27.06376838684082"
+"260571136","1989","1989","1989","24.482128143310547","24.482128143310547","24.482128143310547"
+"261095424","1993","1993","1993","25.426218032836914","25.426218032836914","25.426218032836914"
+"261619712","1997","1997","1997","24.687068939208984","24.687068939208984","24.687068939208984"
+"262144000","2001","2001","2001","24.4033203125","24.4033203125","24.4033203125"
+"262668288","2005","2005","2005","25.704730987548828","25.704730987548828","25.704730987548828"
+"263192576","2009","2009","2009","25.544965744018555","25.544965744018555","25.544965744018555"
+"263716864","2013","2013","2013","26.56644630432129","26.56644630432129","26.56644630432129"
+"264241152","2017","2017","2017","24.428197860717773","24.428197860717773","24.428197860717773"
+"264765440","2021","2021","2021","25.47721290588379","25.47721290588379","25.47721290588379"
+"265289728","2025","2025","2025","24.909481048583984","24.909481048583984","24.909481048583984"
+"265814016","2029","2029","2029","24.44765853881836","24.44765853881836","24.44765853881836"
+"266338304","2033","2033","2033","26.21437644958496","26.21437644958496","26.21437644958496"
+"266862592","2037","2037","2037","24.95969581604004","24.95969581604004","24.95969581604004"
+"267386880","2041","2041","2041","24.900896072387695","24.900896072387695","24.900896072387695"
+"267911168","2045","2045","2045","23.798446655273438","23.798446655273438","23.798446655273438"
+"268435456","2049","2049","2049","23.103031158447266","23.103031158447266","23.103031158447266"
+"268959744","2053","2053","2053","25.09625244140625","25.09625244140625","25.09625244140625"
+"269484032","2057","2057","2057","24.07876968383789","24.07876968383789","24.07876968383789"
+"270008320","2061","2061","2061","23.638654708862305","23.638654708862305","23.638654708862305"
+"270532608","2065","2065","2065","24.691434860229492","24.691434860229492","24.691434860229492"
+"271056896","2069","2069","2069","25.610971450805664","25.610971450805664","25.610971450805664"
+"271581184","2073","2073","2073","23.95549964904785","23.95549964904785","23.95549964904785"
+"272105472","2077","2077","2077","24.67525863647461","24.67525863647461","24.67525863647461"
+"272629760","2081","2081","2081","25.47637939453125","25.47637939453125","25.47637939453125"
+"273154048","2085","2085","2085","24.64419937133789","24.64419937133789","24.64419937133789"
+"273678336","2089","2089","2089","23.94721794128418","23.94721794128418","23.94721794128418"
+"274202624","2093","2093","2093","23.356794357299805","23.356794357299805","23.356794357299805"
+"274726912","2097","2097","2097","24.761831283569336","24.761831283569336","24.761831283569336"
+"275251200","2101","2101","2101","25.679855346679688","25.679855346679688","25.679855346679688"
+"275775488","2105","2105","2105","25.093290328979492","25.093290328979492","25.093290328979492"
+"276299776","2109","2109","2109","25.975460052490234","25.975460052490234","25.975460052490234"
+"276824064","2113","2113","2113","25.104312896728516","25.104312896728516","25.104312896728516"
+"277348352","2117","2117","2117","24.755268096923828","24.755268096923828","24.755268096923828"
+"277872640","2121","2121","2121","25.581647872924805","25.581647872924805","25.581647872924805"
+"278396928","2125","2125","2125","22.77000617980957","22.77000617980957","22.77000617980957"
+"278921216","2129","2129","2129","25.958717346191406","25.958717346191406","25.958717346191406"
+"279445504","2133","2133","2133","24.874958038330078","24.874958038330078","24.874958038330078"
+"279969792","2137","2137","2137","24.067699432373047","24.067699432373047","24.067699432373047"
+"280494080","2141","2141","2141","24.571605682373047","24.571605682373047","24.571605682373047"
+"281018368","2145","2145","2145","24.795724868774414","24.795724868774414","24.795724868774414"
+"281542656","2149","2149","2149","25.670745849609375","25.670745849609375","25.670745849609375"
+"282066944","2153","2153","2153","25.525741577148438","25.525741577148438","25.525741577148438"
+"282591232","2157","2157","2157","24.578092575073242","24.578092575073242","24.578092575073242"
+"283115520","2161","2161","2161","25.66545867919922","25.66545867919922","25.66545867919922"
+"283639808","2165","2165","2165","26.153627395629883","26.153627395629883","26.153627395629883"
+"284164096","2169","2169","2169","26.479387283325195","26.479387283325195","26.479387283325195"
+"284688384","2173","2173","2173","25.33707618713379","25.33707618713379","25.33707618713379"
+"285212672","2177","2177","2177","25.210168838500977","25.210168838500977","25.210168838500977"
+"285736960","2181","2181","2181","24.979957580566406","24.979957580566406","24.979957580566406"
+"286261248","2185","2185","2185","26.14785385131836","26.14785385131836","26.14785385131836"
+"286785536","2189","2189","2189","26.26738929748535","26.26738929748535","26.26738929748535"
+"287309824","2193","2193","2193","26.304323196411133","26.304323196411133","26.304323196411133"
+"287834112","2197","2197","2197","23.82052230834961","23.82052230834961","23.82052230834961"
+"288358400","2201","2201","2201","23.69721794128418","23.69721794128418","23.69721794128418"
+"288882688","2205","2205","2205","26.148439407348633","26.148439407348633","26.148439407348633"
+"289406976","2209","2209","2209","24.07625961303711","24.07625961303711","24.07625961303711"
+"289931264","2213","2213","2213","24.36518669128418","24.36518669128418","24.36518669128418"
+"290455552","2217","2217","2217","24.548120498657227","24.548120498657227","24.548120498657227"
+"290979840","2221","2221","2221","24.30980110168457","24.30980110168457","24.30980110168457"
+"291504128","2225","2225","2225","24.860822677612305","24.860822677612305","24.860822677612305"
+"292028416","2229","2229","2229","24.189327239990234","24.189327239990234","24.189327239990234"
+"292552704","2233","2233","2233","26.999897003173828","26.999897003173828","26.999897003173828"
+"293076992","2237","2237","2237","24.953092575073242","24.953092575073242","24.953092575073242"
+"293601280","2241","2241","2241","25.516029357910156","25.516029357910156","25.516029357910156"
+"294125568","2245","2245","2245","25.409414291381836","25.409414291381836","25.409414291381836"
+"294649856","2249","2249","2249","26.753679275512695","26.753679275512695","26.753679275512695"
+"295174144","2253","2253","2253","26.432262420654297","26.432262420654297","26.432262420654297"
+"295698432","2257","2257","2257","24.71135711669922","24.71135711669922","24.71135711669922"
+"296222720","2261","2261","2261","25.26358413696289","25.26358413696289","25.26358413696289"
+"296747008","2265","2265","2265","25.602888107299805","25.602888107299805","25.602888107299805"
+"297271296","2269","2269","2269","25.273624420166016","25.273624420166016","25.273624420166016"
+"297795584","2273","2273","2273","26.03654670715332","26.03654670715332","26.03654670715332"
+"298319872","2277","2277","2277","25.174978256225586","25.174978256225586","25.174978256225586"
+"298844160","2281","2281","2281","26.381078720092773","26.381078720092773","26.381078720092773"
+"299368448","2285","2285","2285","25.98817253112793","25.98817253112793","25.98817253112793"
+"299892736","2289","2289","2289","25.728212356567383","25.728212356567383","25.728212356567383"
+"300417024","2293","2293","2293","25.27511215209961","25.27511215209961","25.27511215209961"
+"300941312","2297","2297","2297","26.50542449951172","26.50542449951172","26.50542449951172"
+"301465600","2301","2301","2301","26.205814361572266","26.205814361572266","26.205814361572266"
+"301989888","2305","2305","2305","25.192489624023438","25.192489624023438","25.192489624023438"
+"302514176","2309","2309","2309","26.56828498840332","26.56828498840332","26.56828498840332"
+"303038464","2313","2313","2313","26.95036506652832","26.95036506652832","26.95036506652832"
+"303562752","2317","2317","2317","26.243566513061523","26.243566513061523","26.243566513061523"
+"304087040","2321","2321","2321","26.50383186340332","26.50383186340332","26.50383186340332"
+"304611328","2325","2325","2325","25.939231872558594","25.939231872558594","25.939231872558594"
+"305135616","2329","2329","2329","26.31424903869629","26.31424903869629","26.31424903869629"
+"305659904","2333","2333","2333","26.50239372253418","26.50239372253418","26.50239372253418"
+"306184192","2337","2337","2337","25.82040023803711","25.82040023803711","25.82040023803711"
+"306708480","2341","2341","2341","26.353500366210938","26.353500366210938","26.353500366210938"
+"307232768","2345","2345","2345","25.159513473510742","25.159513473510742","25.159513473510742"
+"307757056","2349","2349","2349","25.763090133666992","25.763090133666992","25.763090133666992"
+"308281344","2353","2353","2353","25.384302139282227","25.384302139282227","25.384302139282227"
+"308805632","2357","2357","2357","26.715036392211914","26.715036392211914","26.715036392211914"
+"309329920","2361","2361","2361","25.47911834716797","25.47911834716797","25.47911834716797"
+"309854208","2365","2365","2365","24.741596221923828","24.741596221923828","24.741596221923828"
+"310378496","2369","2369","2369","26.134925842285156","26.134925842285156","26.134925842285156"
+"310902784","2373","2373","2373","25.80356216430664","25.80356216430664","25.80356216430664"
+"311427072","2377","2377","2377","26.43313980102539","26.43313980102539","26.43313980102539"
+"311951360","2381","2381","2381","26.713964462280273","26.713964462280273","26.713964462280273"
+"312475648","2385","2385","2385","26.366455078125","26.366455078125","26.366455078125"
+"312999936","2389","2389","2389","26.317584991455078","26.317584991455078","26.317584991455078"
+"313524224","2393","2393","2393","25.603734970092773","25.603734970092773","25.603734970092773"
+"314048512","2397","2397","2397","24.42814064025879","24.42814064025879","24.42814064025879"
+"314572800","2401","2401","2401","26.261913299560547","26.261913299560547","26.261913299560547"
+"315097088","2405","2405","2405","27.013273239135742","27.013273239135742","27.013273239135742"
+"315621376","2409","2409","2409","26.705270767211914","26.705270767211914","26.705270767211914"
+"316145664","2413","2413","2413","27.10221290588379","27.10221290588379","27.10221290588379"
+"316669952","2417","2417","2417","25.726451873779297","25.726451873779297","25.726451873779297"
+"317194240","2421","2421","2421","25.518346786499023","25.518346786499023","25.518346786499023"
+"317718528","2425","2425","2425","26.91303253173828","26.91303253173828","26.91303253173828"
+"318242816","2429","2429","2429","25.03980827331543","25.03980827331543","25.03980827331543"
+"318767104","2433","2433","2433","25.674335479736328","25.674335479736328","25.674335479736328"
+"319291392","2437","2437","2437","26.862714767456055","26.862714767456055","26.862714767456055"
+"319815680","2441","2441","2441","25.298030853271484","25.298030853271484","25.298030853271484"
+"320339968","2445","2445","2445","26.55095100402832","26.55095100402832","26.55095100402832"
+"320864256","2449","2449","2449","26.81487274169922","26.81487274169922","26.81487274169922"
+"321388544","2453","2453","2453","26.079296112060547","26.079296112060547","26.079296112060547"
+"321912832","2457","2457","2457","27.22984504699707","27.22984504699707","27.22984504699707"
+"322437120","2461","2461","2461","26.822450637817383","26.822450637817383","26.822450637817383"
+"322961408","2465","2465","2465","25.33271598815918","25.33271598815918","25.33271598815918"
+"323485696","2469","2469","2469","25.53559684753418","25.53559684753418","25.53559684753418"
+"324009984","2473","2473","2473","24.740779876708984","24.740779876708984","24.740779876708984"
+"324534272","2477","2477","2477","25.577985763549805","25.577985763549805","25.577985763549805"
+"325058560","2481","2481","2481","25.356801986694336","25.356801986694336","25.356801986694336"
+"325582848","2485","2485","2485","26.470792770385742","26.470792770385742","26.470792770385742"
+"326107136","2489","2489","2489","26.38029670715332","26.38029670715332","26.38029670715332"
+"326631424","2493","2493","2493","27.924100875854492","27.924100875854492","27.924100875854492"
+"327155712","2497","2497","2497","27.250905990600586","27.250905990600586","27.250905990600586"
+"327680000","2501","2501","2501","25.182235717773438","25.182235717773438","25.182235717773438"
+"328204288","2505","2505","2505","26.429115295410156","26.429115295410156","26.429115295410156"
+"328728576","2509","2509","2509","25.052648544311523","25.052648544311523","25.052648544311523"
+"329252864","2513","2513","2513","26.917098999023438","26.917098999023438","26.917098999023438"
+"329777152","2517","2517","2517","25.957763671875","25.957763671875","25.957763671875"
+"330301440","2521","2521","2521","26.80215835571289","26.80215835571289","26.80215835571289"
+"330825728","2525","2525","2525","25.99167823791504","25.99167823791504","25.99167823791504"
+"331350016","2529","2529","2529","26.46453857421875","26.46453857421875","26.46453857421875"
+"331874304","2533","2533","2533","25.530057907104492","25.530057907104492","25.530057907104492"
+"332398592","2537","2537","2537","27.1796875","27.1796875","27.1796875"
+"332922880","2541","2541","2541","26.54924774169922","26.54924774169922","26.54924774169922"
+"333447168","2545","2545","2545","26.52279281616211","26.52279281616211","26.52279281616211"
+"333971456","2549","2549","2549","26.491771697998047","26.491771697998047","26.491771697998047"
+"334495744","2553","2553","2553","25.35258674621582","25.35258674621582","25.35258674621582"
+"335020032","2557","2557","2557","27.15178871154785","27.15178871154785","27.15178871154785"
+"335544320","2561","2561","2561","26.240047454833984","26.240047454833984","26.240047454833984"
+"336068608","2565","2565","2565","25.87549591064453","25.87549591064453","25.87549591064453"
+"336592896","2569","2569","2569","26.16005516052246","26.16005516052246","26.16005516052246"
+"337117184","2573","2573","2573","25.92848777770996","25.92848777770996","25.92848777770996"
+"337641472","2577","2577","2577","25.520009994506836","25.520009994506836","25.520009994506836"
+"338165760","2581","2581","2581","26.045541763305664","26.045541763305664","26.045541763305664"
+"338690048","2585","2585","2585","26.55977439880371","26.55977439880371","26.55977439880371"
+"339214336","2589","2589","2589","25.918928146362305","25.918928146362305","25.918928146362305"
+"339738624","2593","2593","2593","27.006916046142578","27.006916046142578","27.006916046142578"
+"340262912","2597","2597","2597","25.77324676513672","25.77324676513672","25.77324676513672"
+"340787200","2601","2601","2601","25.67287826538086","25.67287826538086","25.67287826538086"
+"341311488","2605","2605","2605","27.456212997436523","27.456212997436523","27.456212997436523"
+"341835776","2609","2609","2609","25.89277458190918","25.89277458190918","25.89277458190918"
+"342360064","2613","2613","2613","26.065074920654297","26.065074920654297","26.065074920654297"
+"342884352","2617","2617","2617","27.491905212402344","27.491905212402344","27.491905212402344"
+"343408640","2621","2621","2621","27.495269775390625","27.495269775390625","27.495269775390625"
+"343932928","2625","2625","2625","27.372509002685547","27.372509002685547","27.372509002685547"
+"344457216","2629","2629","2629","27.06730079650879","27.06730079650879","27.06730079650879"
+"344981504","2633","2633","2633","26.162904739379883","26.162904739379883","26.162904739379883"
+"345505792","2637","2637","2637","25.912757873535156","25.912757873535156","25.912757873535156"
+"346030080","2641","2641","2641","26.96820831298828","26.96820831298828","26.96820831298828"
+"346554368","2645","2645","2645","26.56772804260254","26.56772804260254","26.56772804260254"
+"347078656","2649","2649","2649","25.884740829467773","25.884740829467773","25.884740829467773"
+"347602944","2653","2653","2653","26.7222900390625","26.7222900390625","26.7222900390625"
+"348127232","2657","2657","2657","27.05524444580078","27.05524444580078","27.05524444580078"
+"348651520","2661","2661","2661","25.902006149291992","25.902006149291992","25.902006149291992"
+"349175808","2665","2665","2665","27.20322036743164","27.20322036743164","27.20322036743164"
+"349700096","2669","2669","2669","26.76824951171875","26.76824951171875","26.76824951171875"
+"350224384","2673","2673","2673","29.21621322631836","29.21621322631836","29.21621322631836"
+"350748672","2677","2677","2677","26.817338943481445","26.817338943481445","26.817338943481445"
+"351272960","2681","2681","2681","27.073619842529297","27.073619842529297","27.073619842529297"
+"351797248","2685","2685","2685","25.513784408569336","25.513784408569336","25.513784408569336"
+"352321536","2689","2689","2689","27.719974517822266","27.719974517822266","27.719974517822266"
+"352845824","2693","2693","2693","25.926715850830078","25.926715850830078","25.926715850830078"
+"353370112","2697","2697","2697","26.011886596679688","26.011886596679688","26.011886596679688"
+"353894400","2701","2701","2701","27.13543128967285","27.13543128967285","27.13543128967285"
+"354418688","2705","2705","2705","27.31780242919922","27.31780242919922","27.31780242919922"
+"354942976","2709","2709","2709","27.98843765258789","27.98843765258789","27.98843765258789"
+"355467264","2713","2713","2713","26.31599235534668","26.31599235534668","26.31599235534668"
+"355991552","2717","2717","2717","27.654354095458984","27.654354095458984","27.654354095458984"
+"356515840","2721","2721","2721","26.926986694335938","26.926986694335938","26.926986694335938"
+"357040128","2725","2725","2725","26.6295166015625","26.6295166015625","26.6295166015625"
+"357564416","2729","2729","2729","26.840139389038086","26.840139389038086","26.840139389038086"
+"358088704","2733","2733","2733","26.44869613647461","26.44869613647461","26.44869613647461"
+"358612992","2737","2737","2737","26.51325225830078","26.51325225830078","26.51325225830078"
+"359137280","2741","2741","2741","26.46255111694336","26.46255111694336","26.46255111694336"
+"359661568","2745","2745","2745","26.67433738708496","26.67433738708496","26.67433738708496"
+"360185856","2749","2749","2749","26.665782928466797","26.665782928466797","26.665782928466797"
+"360710144","2753","2753","2753","26.879638671875","26.879638671875","26.879638671875"
+"361234432","2757","2757","2757","28.178489685058594","28.178489685058594","28.178489685058594"
+"361758720","2761","2761","2761","26.144699096679688","26.144699096679688","26.144699096679688"
+"362283008","2765","2765","2765","25.7310791015625","25.7310791015625","25.7310791015625"
+"362807296","2769","2769","2769","26.974374771118164","26.974374771118164","26.974374771118164"
+"363331584","2773","2773","2773","26.619848251342773","26.619848251342773","26.619848251342773"
+"363855872","2777","2777","2777","26.47810935974121","26.47810935974121","26.47810935974121"
+"364380160","2781","2781","2781","26.4289493560791","26.4289493560791","26.4289493560791"
+"364904448","2785","2785","2785","27.733505249023438","27.733505249023438","27.733505249023438"
+"365428736","2789","2789","2789","25.841535568237305","25.841535568237305","25.841535568237305"
+"365953024","2793","2793","2793","28.393468856811523","28.393468856811523","28.393468856811523"
+"366477312","2797","2797","2797","27.169775009155273","27.169775009155273","27.169775009155273"
+"367001600","2801","2801","2801","28.203020095825195","28.203020095825195","28.203020095825195"
+"367525888","2805","2805","2805","27.097293853759766","27.097293853759766","27.097293853759766"
+"368050176","2809","2809","2809","27.522340774536133","27.522340774536133","27.522340774536133"
+"368574464","2813","2813","2813","26.57172393798828","26.57172393798828","26.57172393798828"
+"369098752","2817","2817","2817","28.32975959777832","28.32975959777832","28.32975959777832"
+"369623040","2821","2821","2821","27.608768463134766","27.608768463134766","27.608768463134766"
+"370147328","2825","2825","2825","27.583208084106445","27.583208084106445","27.583208084106445"
+"370671616","2829","2829","2829","26.946189880371094","26.946189880371094","26.946189880371094"
+"371195904","2833","2833","2833","26.179079055786133","26.179079055786133","26.179079055786133"
+"371720192","2837","2837","2837","26.739946365356445","26.739946365356445","26.739946365356445"
+"372244480","2841","2841","2841","27.697362899780273","27.697362899780273","27.697362899780273"
+"372768768","2845","2845","2845","27.69890594482422","27.69890594482422","27.69890594482422"
+"373293056","2849","2849","2849","26.87679100036621","26.87679100036621","26.87679100036621"
+"373817344","2853","2853","2853","26.88290786743164","26.88290786743164","26.88290786743164"
+"374341632","2857","2857","2857","26.94320297241211","26.94320297241211","26.94320297241211"
+"374865920","2861","2861","2861","27.572250366210938","27.572250366210938","27.572250366210938"
+"375390208","2865","2865","2865","27.152896881103516","27.152896881103516","27.152896881103516"
+"375914496","2869","2869","2869","26.68562889099121","26.68562889099121","26.68562889099121"
+"376438784","2873","2873","2873","26.55105209350586","26.55105209350586","26.55105209350586"
+"376963072","2877","2877","2877","26.7618408203125","26.7618408203125","26.7618408203125"
+"377487360","2881","2881","2881","25.874156951904297","25.874156951904297","25.874156951904297"
+"378011648","2885","2885","2885","28.16281509399414","28.16281509399414","28.16281509399414"
+"378535936","2889","2889","2889","25.66960334777832","25.66960334777832","25.66960334777832"
+"379060224","2893","2893","2893","27.939815521240234","27.939815521240234","27.939815521240234"
+"379584512","2897","2897","2897","26.83873176574707","26.83873176574707","26.83873176574707"
+"380108800","2901","2901","2901","27.78097152709961","27.78097152709961","27.78097152709961"
+"380633088","2905","2905","2905","26.211498260498047","26.211498260498047","26.211498260498047"
+"381157376","2909","2909","2909","27.515897750854492","27.515897750854492","27.515897750854492"
+"381681664","2913","2913","2913","26.84584617614746","26.84584617614746","26.84584617614746"
+"382205952","2917","2917","2917","26.856142044067383","26.856142044067383","26.856142044067383"
+"382730240","2921","2921","2921","27.064306259155273","27.064306259155273","27.064306259155273"
+"383254528","2925","2925","2925","26.73470115661621","26.73470115661621","26.73470115661621"
+"383778816","2929","2929","2929","25.63197898864746","25.63197898864746","25.63197898864746"
+"384303104","2933","2933","2933","27.17756462097168","27.17756462097168","27.17756462097168"
+"384827392","2937","2937","2937","27.53101348876953","27.53101348876953","27.53101348876953"
+"385351680","2941","2941","2941","25.59623146057129","25.59623146057129","25.59623146057129"
+"385875968","2945","2945","2945","26.71928596496582","26.71928596496582","26.71928596496582"
+"386400256","2949","2949","2949","26.841581344604492","26.841581344604492","26.841581344604492"
+"386924544","2953","2953","2953","27.43053436279297","27.43053436279297","27.43053436279297"
+"387448832","2957","2957","2957","26.774267196655273","26.774267196655273","26.774267196655273"
+"387973120","2961","2961","2961","27.782670974731445","27.782670974731445","27.782670974731445"
+"388497408","2965","2965","2965","27.48992919921875","27.48992919921875","27.48992919921875"
+"389021696","2969","2969","2969","26.814334869384766","26.814334869384766","26.814334869384766"
+"389545984","2973","2973","2973","26.43631935119629","26.43631935119629","26.43631935119629"
+"390070272","2977","2977","2977","27.040191650390625","27.040191650390625","27.040191650390625"
+"390594560","2981","2981","2981","26.33087921142578","26.33087921142578","26.33087921142578"
+"391118848","2985","2985","2985","29.093448638916016","29.093448638916016","29.093448638916016"
+"391643136","2989","2989","2989","27.865951538085938","27.865951538085938","27.865951538085938"
+"392167424","2993","2993","2993","26.6235294342041","26.6235294342041","26.6235294342041"
+"392691712","2997","2997","2997","27.271652221679688","27.271652221679688","27.271652221679688"
+"393216000","3001","3001","3001","27.329557418823242","27.329557418823242","27.329557418823242"
+"393740288","3005","3005","3005","28.24724769592285","28.24724769592285","28.24724769592285"
+"394264576","3009","3009","3009","26.28367805480957","26.28367805480957","26.28367805480957"
+"394788864","3013","3013","3013","27.14924430847168","27.14924430847168","27.14924430847168"
+"395313152","3017","3017","3017","27.087446212768555","27.087446212768555","27.087446212768555"
+"395837440","3021","3021","3021","27.442489624023438","27.442489624023438","27.442489624023438"
+"396361728","3025","3025","3025","26.862133026123047","26.862133026123047","26.862133026123047"
+"396886016","3029","3029","3029","27.8426513671875","27.8426513671875","27.8426513671875"
+"397410304","3033","3033","3033","27.541696548461914","27.541696548461914","27.541696548461914"
+"397934592","3037","3037","3037","28.011728286743164","28.011728286743164","28.011728286743164"
+"398458880","3041","3041","3041","28.19783592224121","28.19783592224121","28.19783592224121"
+"398983168","3045","3045","3045","26.99626350402832","26.99626350402832","26.99626350402832"
+"399507456","3049","3049","3049","27.34903907775879","27.34903907775879","27.34903907775879"
+"400031744","3053","3053","3053","25.853160858154297","25.853160858154297","25.853160858154297"
+"400556032","3057","3057","3057","28.126388549804688","28.126388549804688","28.126388549804688"
+"401080320","3061","3061","3061","26.42511749267578","26.42511749267578","26.42511749267578"
+"401604608","3065","3065","3065","26.39518928527832","26.39518928527832","26.39518928527832"
+"402128896","3069","3069","3069","26.253414154052734","26.253414154052734","26.253414154052734"
+"402653184","3073","3073","3073","26.619829177856445","26.619829177856445","26.619829177856445"
+"403177472","3077","3077","3077","26.542133331298828","26.542133331298828","26.542133331298828"
+"403701760","3081","3081","3081","27.91919708251953","27.91919708251953","27.91919708251953"
+"404226048","3085","3085","3085","27.257553100585938","27.257553100585938","27.257553100585938"
+"404750336","3089","3089","3089","27.89405632019043","27.89405632019043","27.89405632019043"
+"405274624","3093","3093","3093","27.509159088134766","27.509159088134766","27.509159088134766"
+"405798912","3097","3097","3097","26.46883773803711","26.46883773803711","26.46883773803711"
+"406323200","3101","3101","3101","29.06717872619629","29.06717872619629","29.06717872619629"
+"406847488","3105","3105","3105","27.14169692993164","27.14169692993164","27.14169692993164"
+"407371776","3109","3109","3109","26.9875431060791","26.9875431060791","26.9875431060791"
+"407896064","3113","3113","3113","27.744638442993164","27.744638442993164","27.744638442993164"
+"408420352","3117","3117","3117","26.653438568115234","26.653438568115234","26.653438568115234"
+"408944640","3121","3121","3121","26.83182144165039","26.83182144165039","26.83182144165039"
+"409468928","3125","3125","3125","26.92641830444336","26.92641830444336","26.92641830444336"
+"409993216","3129","3129","3129","26.651166915893555","26.651166915893555","26.651166915893555"
+"410517504","3133","3133","3133","27.672069549560547","27.672069549560547","27.672069549560547"
+"411041792","3137","3137","3137","27.200727462768555","27.200727462768555","27.200727462768555"
+"411566080","3141","3141","3141","28.146102905273438","28.146102905273438","28.146102905273438"
+"412090368","3145","3145","3145","28.3391056060791","28.3391056060791","28.3391056060791"
+"412614656","3149","3149","3149","27.615333557128906","27.615333557128906","27.615333557128906"
+"413138944","3153","3153","3153","25.91826057434082","25.91826057434082","25.91826057434082"
+"413663232","3157","3157","3157","28.220306396484375","28.220306396484375","28.220306396484375"
+"414187520","3161","3161","3161","27.49390983581543","27.49390983581543","27.49390983581543"
+"414711808","3165","3165","3165","26.20903968811035","26.20903968811035","26.20903968811035"
+"415236096","3169","3169","3169","27.840717315673828","27.840717315673828","27.840717315673828"
+"415760384","3173","3173","3173","27.738359451293945","27.738359451293945","27.738359451293945"
+"416284672","3177","3177","3177","26.472816467285156","26.472816467285156","26.472816467285156"
+"416808960","3181","3181","3181","26.543676376342773","26.543676376342773","26.543676376342773"
+"417333248","3185","3185","3185","27.422231674194336","27.422231674194336","27.422231674194336"
+"417857536","3189","3189","3189","27.854055404663086","27.854055404663086","27.854055404663086"
+"418381824","3193","3193","3193","26.60036277770996","26.60036277770996","26.60036277770996"
+"418906112","3197","3197","3197","26.59032440185547","26.59032440185547","26.59032440185547"
+"419430400","3201","3201","3201","26.15861701965332","26.15861701965332","26.15861701965332"
+"419954688","3205","3205","3205","27.51805305480957","27.51805305480957","27.51805305480957"
+"420478976","3209","3209","3209","28.113359451293945","28.113359451293945","28.113359451293945"
+"421003264","3213","3213","3213","27.487239837646484","27.487239837646484","27.487239837646484"
+"421527552","3217","3217","3217","26.407777786254883","26.407777786254883","26.407777786254883"
+"422051840","3221","3221","3221","27.173709869384766","27.173709869384766","27.173709869384766"
+"422576128","3225","3225","3225","28.056488037109375","28.056488037109375","28.056488037109375"
+"423100416","3229","3229","3229","27.06106948852539","27.06106948852539","27.06106948852539"
+"423624704","3233","3233","3233","28.854703903198242","28.854703903198242","28.854703903198242"
+"424148992","3237","3237","3237","28.657508850097656","28.657508850097656","28.657508850097656"
+"424673280","3241","3241","3241","28.50126838684082","28.50126838684082","28.50126838684082"
+"425197568","3245","3245","3245","28.770347595214844","28.770347595214844","28.770347595214844"
+"425721856","3249","3249","3249","27.75554656982422","27.75554656982422","27.75554656982422"
+"426246144","3253","3253","3253","27.15214729309082","27.15214729309082","27.15214729309082"
+"426770432","3257","3257","3257","25.9041690826416","25.9041690826416","25.9041690826416"
+"427294720","3261","3261","3261","28.06163787841797","28.06163787841797","28.06163787841797"
+"427819008","3265","3265","3265","26.41777229309082","26.41777229309082","26.41777229309082"
+"428343296","3269","3269","3269","28.694040298461914","28.694040298461914","28.694040298461914"
+"428867584","3273","3273","3273","27.201595306396484","27.201595306396484","27.201595306396484"
+"429391872","3277","3277","3277","27.04092788696289","27.04092788696289","27.04092788696289"
+"429916160","3281","3281","3281","26.703161239624023","26.703161239624023","26.703161239624023"
+"430440448","3285","3285","3285","28.465118408203125","28.465118408203125","28.465118408203125"
+"430964736","3289","3289","3289","27.73710823059082","27.73710823059082","27.73710823059082"
+"431489024","3293","3293","3293","27.461631774902344","27.461631774902344","27.461631774902344"
+"432013312","3297","3297","3297","29.49570655822754","29.49570655822754","29.49570655822754"
+"432537600","3301","3301","3301","26.816951751708984","26.816951751708984","26.816951751708984"
+"433061888","3305","3305","3305","26.631872177124023","26.631872177124023","26.631872177124023"
+"433586176","3309","3309","3309","28.45409393310547","28.45409393310547","28.45409393310547"
+"434110464","3313","3313","3313","27.30992889404297","27.30992889404297","27.30992889404297"
+"434634752","3317","3317","3317","29.60027503967285","29.60027503967285","29.60027503967285"
+"435159040","3321","3321","3321","27.293949127197266","27.293949127197266","27.293949127197266"
+"435683328","3325","3325","3325","27.84956932067871","27.84956932067871","27.84956932067871"
+"436207616","3329","3329","3329","27.466230392456055","27.466230392456055","27.466230392456055"
+"436731904","3333","3333","3333","27.59624671936035","27.59624671936035","27.59624671936035"
+"437256192","3337","3337","3337","26.90784454345703","26.90784454345703","26.90784454345703"
+"437780480","3341","3341","3341","27.776779174804688","27.776779174804688","27.776779174804688"
+"438304768","3345","3345","3345","28.55907440185547","28.55907440185547","28.55907440185547"
+"438829056","3349","3349","3349","28.24482536315918","28.24482536315918","28.24482536315918"
+"439353344","3353","3353","3353","27.216827392578125","27.216827392578125","27.216827392578125"
+"439877632","3357","3357","3357","28.154891967773438","28.154891967773438","28.154891967773438"
+"440401920","3361","3361","3361","28.17463493347168","28.17463493347168","28.17463493347168"
+"440926208","3365","3365","3365","28.23911476135254","28.23911476135254","28.23911476135254"
+"441450496","3369","3369","3369","25.237071990966797","25.237071990966797","25.237071990966797"
+"441974784","3373","3373","3373","28.14385986328125","28.14385986328125","28.14385986328125"
+"442499072","3377","3377","3377","27.647279739379883","27.647279739379883","27.647279739379883"
+"443023360","3381","3381","3381","27.513925552368164","27.513925552368164","27.513925552368164"
+"443547648","3385","3385","3385","26.968536376953125","26.968536376953125","26.968536376953125"
+"444071936","3389","3389","3389","26.65829086303711","26.65829086303711","26.65829086303711"
+"444596224","3393","3393","3393","28.016300201416016","28.016300201416016","28.016300201416016"
+"445120512","3397","3397","3397","28.14321517944336","28.14321517944336","28.14321517944336"
+"445644800","3401","3401","3401","29.17499351501465","29.17499351501465","29.17499351501465"
+"446169088","3405","3405","3405","27.29165267944336","27.29165267944336","27.29165267944336"
+"446693376","3409","3409","3409","27.80463981628418","27.80463981628418","27.80463981628418"
+"447217664","3413","3413","3413","27.800519943237305","27.800519943237305","27.800519943237305"
+"447741952","3417","3417","3417","28.643085479736328","28.643085479736328","28.643085479736328"
+"448266240","3421","3421","3421","26.2353515625","26.2353515625","26.2353515625"
+"448790528","3425","3425","3425","27.705631256103516","27.705631256103516","27.705631256103516"
+"449314816","3429","3429","3429","27.50688934326172","27.50688934326172","27.50688934326172"
+"449839104","3433","3433","3433","26.905858993530273","26.905858993530273","26.905858993530273"
+"450363392","3437","3437","3437","27.79836654663086","27.79836654663086","27.79836654663086"
+"450887680","3441","3441","3441","28.56512451171875","28.56512451171875","28.56512451171875"
+"451411968","3445","3445","3445","27.744300842285156","27.744300842285156","27.744300842285156"
+"451936256","3449","3449","3449","26.675495147705078","26.675495147705078","26.675495147705078"
+"452460544","3453","3453","3453","26.089271545410156","26.089271545410156","26.089271545410156"
+"452984832","3457","3457","3457","28.981542587280273","28.981542587280273","28.981542587280273"
+"453509120","3461","3461","3461","27.09477424621582","27.09477424621582","27.09477424621582"
+"454033408","3465","3465","3465","27.31597137451172","27.31597137451172","27.31597137451172"
+"454557696","3469","3469","3469","26.81882667541504","26.81882667541504","26.81882667541504"
+"455081984","3473","3473","3473","26.226707458496094","26.226707458496094","26.226707458496094"
+"455606272","3477","3477","3477","28.245363235473633","28.245363235473633","28.245363235473633"
+"456130560","3481","3481","3481","25.91023063659668","25.91023063659668","25.91023063659668"
+"456654848","3485","3485","3485","26.899904251098633","26.899904251098633","26.899904251098633"
+"457179136","3489","3489","3489","27.483699798583984","27.483699798583984","27.483699798583984"
+"457703424","3493","3493","3493","27.460880279541016","27.460880279541016","27.460880279541016"
+"458227712","3497","3497","3497","27.2908935546875","27.2908935546875","27.2908935546875"
+"458752000","3501","3501","3501","26.64052391052246","26.64052391052246","26.64052391052246"
+"459276288","3505","3505","3505","27.00501823425293","27.00501823425293","27.00501823425293"
+"459800576","3509","3509","3509","27.238204956054688","27.238204956054688","27.238204956054688"
+"460324864","3513","3513","3513","27.38047218322754","27.38047218322754","27.38047218322754"
+"460849152","3517","3517","3517","27.320533752441406","27.320533752441406","27.320533752441406"
+"461373440","3521","3521","3521","27.40447998046875","27.40447998046875","27.40447998046875"
+"461897728","3525","3525","3525","26.868587493896484","26.868587493896484","26.868587493896484"
+"462422016","3529","3529","3529","26.57927894592285","26.57927894592285","26.57927894592285"
+"462946304","3533","3533","3533","28.55919647216797","28.55919647216797","28.55919647216797"
+"463470592","3537","3537","3537","27.55774688720703","27.55774688720703","27.55774688720703"
+"463994880","3541","3541","3541","28.089773178100586","28.089773178100586","28.089773178100586"
+"464519168","3545","3545","3545","26.823740005493164","26.823740005493164","26.823740005493164"
+"465043456","3549","3549","3549","28.23204803466797","28.23204803466797","28.23204803466797"
+"465567744","3553","3553","3553","26.55942726135254","26.55942726135254","26.55942726135254"
+"466092032","3557","3557","3557","27.345783233642578","27.345783233642578","27.345783233642578"
+"466616320","3561","3561","3561","28.272342681884766","28.272342681884766","28.272342681884766"
+"467140608","3565","3565","3565","27.48290252685547","27.48290252685547","27.48290252685547"
+"467664896","3569","3569","3569","27.7825870513916","27.7825870513916","27.7825870513916"
+"468189184","3573","3573","3573","27.64717674255371","27.64717674255371","27.64717674255371"
+"468713472","3577","3577","3577","27.920427322387695","27.920427322387695","27.920427322387695"
+"469237760","3581","3581","3581","27.372541427612305","27.372541427612305","27.372541427612305"
+"469762048","3585","3585","3585","28.38801383972168","28.38801383972168","28.38801383972168"
+"470286336","3589","3589","3589","27.999961853027344","27.999961853027344","27.999961853027344"
+"470810624","3593","3593","3593","26.99735450744629","26.99735450744629","26.99735450744629"
+"471334912","3597","3597","3597","29.13752555847168","29.13752555847168","29.13752555847168"
+"471859200","3601","3601","3601","27.727313995361328","27.727313995361328","27.727313995361328"
+"472383488","3605","3605","3605","27.175434112548828","27.175434112548828","27.175434112548828"
+"472907776","3609","3609","3609","26.955923080444336","26.955923080444336","26.955923080444336"
+"473432064","3613","3613","3613","27.318599700927734","27.318599700927734","27.318599700927734"
+"473956352","3617","3617","3617","27.588998794555664","27.588998794555664","27.588998794555664"
+"474480640","3621","3621","3621","27.80373764038086","27.80373764038086","27.80373764038086"
+"475004928","3625","3625","3625","28.887645721435547","28.887645721435547","28.887645721435547"
+"475529216","3629","3629","3629","28.03980827331543","28.03980827331543","28.03980827331543"
+"476053504","3633","3633","3633","27.16341781616211","27.16341781616211","27.16341781616211"
+"476577792","3637","3637","3637","28.202903747558594","28.202903747558594","28.202903747558594"
+"477102080","3641","3641","3641","28.088285446166992","28.088285446166992","28.088285446166992"
+"477626368","3645","3645","3645","29.062246322631836","29.062246322631836","29.062246322631836"
+"478150656","3649","3649","3649","28.38624382019043","28.38624382019043","28.38624382019043"
+"478674944","3653","3653","3653","27.916242599487305","27.916242599487305","27.916242599487305"
+"479199232","3657","3657","3657","29.27581214904785","29.27581214904785","29.27581214904785"
+"479723520","3661","3661","3661","26.979726791381836","26.979726791381836","26.979726791381836"
+"480247808","3665","3665","3665","28.175050735473633","28.175050735473633","28.175050735473633"
+"480772096","3669","3669","3669","27.225955963134766","27.225955963134766","27.225955963134766"
+"481296384","3673","3673","3673","27.109481811523438","27.109481811523438","27.109481811523438"
+"481820672","3677","3677","3677","27.34609031677246","27.34609031677246","27.34609031677246"
+"482344960","3681","3681","3681","27.54530143737793","27.54530143737793","27.54530143737793"
+"482869248","3685","3685","3685","27.507116317749023","27.507116317749023","27.507116317749023"
+"483393536","3689","3689","3689","28.117462158203125","28.117462158203125","28.117462158203125"
+"483917824","3693","3693","3693","28.440643310546875","28.440643310546875","28.440643310546875"
+"484442112","3697","3697","3697","27.31194496154785","27.31194496154785","27.31194496154785"
+"484966400","3701","3701","3701","27.421092987060547","27.421092987060547","27.421092987060547"
+"485490688","3705","3705","3705","28.181570053100586","28.181570053100586","28.181570053100586"
+"486014976","3709","3709","3709","28.08283805847168","28.08283805847168","28.08283805847168"
+"486539264","3713","3713","3713","27.14096450805664","27.14096450805664","27.14096450805664"
+"487063552","3717","3717","3717","27.49943733215332","27.49943733215332","27.49943733215332"
+"487587840","3721","3721","3721","28.484481811523438","28.484481811523438","28.484481811523438"
+"488112128","3725","3725","3725","27.32122230529785","27.32122230529785","27.32122230529785"
+"488636416","3729","3729","3729","27.03037452697754","27.03037452697754","27.03037452697754"
+"489160704","3733","3733","3733","28.566261291503906","28.566261291503906","28.566261291503906"
+"489684992","3737","3737","3737","28.613332748413086","28.613332748413086","28.613332748413086"
+"490209280","3741","3741","3741","28.072208404541016","28.072208404541016","28.072208404541016"
+"490733568","3745","3745","3745","27.672719955444336","27.672719955444336","27.672719955444336"
+"491257856","3749","3749","3749","28.548297882080078","28.548297882080078","28.548297882080078"
+"491782144","3753","3753","3753","27.81199836730957","27.81199836730957","27.81199836730957"
+"492306432","3757","3757","3757","28.644437789916992","28.644437789916992","28.644437789916992"
+"492830720","3761","3761","3761","28.528032302856445","28.528032302856445","28.528032302856445"
+"493355008","3765","3765","3765","25.882143020629883","25.882143020629883","25.882143020629883"
+"493879296","3769","3769","3769","28.418582916259766","28.418582916259766","28.418582916259766"
+"494403584","3773","3773","3773","26.54509925842285","26.54509925842285","26.54509925842285"
+"494927872","3777","3777","3777","28.285070419311523","28.285070419311523","28.285070419311523"
+"495452160","3781","3781","3781","27.096683502197266","27.096683502197266","27.096683502197266"
+"495976448","3785","3785","3785","28.149303436279297","28.149303436279297","28.149303436279297"
+"496500736","3789","3789","3789","26.17766761779785","26.17766761779785","26.17766761779785"
+"497025024","3793","3793","3793","28.05560302734375","28.05560302734375","28.05560302734375"
+"497549312","3797","3797","3797","27.80960464477539","27.80960464477539","27.80960464477539"
+"498073600","3801","3801","3801","26.880783081054688","26.880783081054688","26.880783081054688"
+"498597888","3805","3805","3805","28.76179313659668","28.76179313659668","28.76179313659668"
+"499122176","3809","3809","3809","28.815412521362305","28.815412521362305","28.815412521362305"
+"499646464","3813","3813","3813","27.769054412841797","27.769054412841797","27.769054412841797"
+"500170752","3817","3817","3817","28.63221549987793","28.63221549987793","28.63221549987793"
+"500695040","3821","3821","3821","27.781620025634766","27.781620025634766","27.781620025634766"
+"501219328","3825","3825","3825","27.424440383911133","27.424440383911133","27.424440383911133"
+"501743616","3829","3829","3829","28.07331085205078","28.07331085205078","28.07331085205078"
+"502267904","3833","3833","3833","27.262868881225586","27.262868881225586","27.262868881225586"
+"502792192","3837","3837","3837","28.25947380065918","28.25947380065918","28.25947380065918"
+"503316480","3841","3841","3841","28.49013900756836","28.49013900756836","28.49013900756836"
+"503840768","3845","3845","3845","26.480302810668945","26.480302810668945","26.480302810668945"
+"504365056","3849","3849","3849","28.299983978271484","28.299983978271484","28.299983978271484"
+"504889344","3853","3853","3853","28.034189224243164","28.034189224243164","28.034189224243164"
+"505413632","3857","3857","3857","26.9789981842041","26.9789981842041","26.9789981842041"
+"505937920","3861","3861","3861","28.42172622680664","28.42172622680664","28.42172622680664"
+"506462208","3865","3865","3865","27.73461151123047","27.73461151123047","27.73461151123047"
+"506986496","3869","3869","3869","27.24178695678711","27.24178695678711","27.24178695678711"
+"507510784","3873","3873","3873","28.022193908691406","28.022193908691406","28.022193908691406"
+"508035072","3877","3877","3877","28.126955032348633","28.126955032348633","28.126955032348633"
+"508559360","3881","3881","3881","27.35799789428711","27.35799789428711","27.35799789428711"
+"509083648","3885","3885","3885","28.927955627441406","28.927955627441406","28.927955627441406"
+"509607936","3889","3889","3889","28.946502685546875","28.946502685546875","28.946502685546875"
+"510132224","3893","3893","3893","29.789913177490234","29.789913177490234","29.789913177490234"
+"510656512","3897","3897","3897","26.47412872314453","26.47412872314453","26.47412872314453"
+"511180800","3901","3901","3901","27.714534759521484","27.714534759521484","27.714534759521484"
+"511705088","3905","3905","3905","26.794734954833984","26.794734954833984","26.794734954833984"
+"512229376","3909","3909","3909","28.90367317199707","28.90367317199707","28.90367317199707"
+"512753664","3913","3913","3913","28.786766052246094","28.786766052246094","28.786766052246094"
+"513277952","3917","3917","3917","26.765844345092773","26.765844345092773","26.765844345092773"
+"513802240","3921","3921","3921","28.836660385131836","28.836660385131836","28.836660385131836"
+"514326528","3925","3925","3925","28.45279312133789","28.45279312133789","28.45279312133789"
+"514850816","3929","3929","3929","27.50047492980957","27.50047492980957","27.50047492980957"
+"515375104","3933","3933","3933","27.71158218383789","27.71158218383789","27.71158218383789"
+"515899392","3937","3937","3937","27.877487182617188","27.877487182617188","27.877487182617188"
+"516423680","3941","3941","3941","27.57308006286621","27.57308006286621","27.57308006286621"
+"516947968","3945","3945","3945","27.52393913269043","27.52393913269043","27.52393913269043"
+"517472256","3949","3949","3949","27.206512451171875","27.206512451171875","27.206512451171875"
+"517996544","3953","3953","3953","27.681486129760742","27.681486129760742","27.681486129760742"
+"518520832","3957","3957","3957","27.33197784423828","27.33197784423828","27.33197784423828"
+"519045120","3961","3961","3961","27.701425552368164","27.701425552368164","27.701425552368164"
+"519569408","3965","3965","3965","28.758846282958984","28.758846282958984","28.758846282958984"
+"520093696","3969","3969","3969","27.793216705322266","27.793216705322266","27.793216705322266"
+"520617984","3973","3973","3973","27.622880935668945","27.622880935668945","27.622880935668945"
+"521142272","3977","3977","3977","26.831127166748047","26.831127166748047","26.831127166748047"
+"521666560","3981","3981","3981","29.305673599243164","29.305673599243164","29.305673599243164"
+"522190848","3985","3985","3985","28.887426376342773","28.887426376342773","28.887426376342773"
+"522715136","3989","3989","3989","27.565370559692383","27.565370559692383","27.565370559692383"
+"523239424","3993","3993","3993","27.18408203125","27.18408203125","27.18408203125"
+"523763712","3997","3997","3997","28.540252685546875","28.540252685546875","28.540252685546875"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew_col.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew_col.csv
new file mode 100644
index 000000000..73214824a
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew_col.csv
@@ -0,0 +1,1001 @@
+"global_step","DRRandom_04-01-36-40 - _step","DRRandom_04-01-36-40 - _step__MIN","DRRandom_04-01-36-40 - _step__MAX","DRRandom_04-01-36-40 - rewards/collision/step","DRRandom_04-01-36-40 - rewards/collision/step__MIN","DRRandom_04-01-36-40 - rewards/collision/step__MAX"
+"192","3","3","3","-9.99999713897705","-9.99999713897705","-9.99999713897705"
+"524288","7","7","7","-9.999019622802734","-9.999019622802734","-9.999019622802734"
+"1048576","11","11","11","-9.99999713897705","-9.99999713897705","-9.99999713897705"
+"1572864","15","15","15","-9.99999713897705","-9.99999713897705","-9.99999713897705"
+"2097152","19","19","19","-9.999910354614258","-9.999910354614258","-9.999910354614258"
+"2621440","23","23","23","-9.99999713897705","-9.99999713897705","-9.99999713897705"
+"3145728","27","27","27","-9.992517471313477","-9.992517471313477","-9.992517471313477"
+"3670016","31","31","31","-9.999995231628418","-9.999995231628418","-9.999995231628418"
+"4194304","35","35","35","-9.995129585266113","-9.995129585266113","-9.995129585266113"
+"4718592","39","39","39","-9.945270538330078","-9.945270538330078","-9.945270538330078"
+"5242880","43","43","43","-9.861248970031738","-9.861248970031738","-9.861248970031738"
+"5767168","47","47","47","-9.98608112335205","-9.98608112335205","-9.98608112335205"
+"6291456","51","51","51","-9.99999713897705","-9.99999713897705","-9.99999713897705"
+"6815744","55","55","55","-9.940696716308594","-9.940696716308594","-9.940696716308594"
+"7340032","59","59","59","-9.876565933227539","-9.876565933227539","-9.876565933227539"
+"7864320","63","63","63","-9.850189208984375","-9.850189208984375","-9.850189208984375"
+"8388608","67","67","67","-9.984864234924316","-9.984864234924316","-9.984864234924316"
+"8912896","71","71","71","-9.868375778198242","-9.868375778198242","-9.868375778198242"
+"9437184","75","75","75","-9.888383865356445","-9.888383865356445","-9.888383865356445"
+"9961472","79","79","79","-9.916692733764648","-9.916692733764648","-9.916692733764648"
+"10485760","83","83","83","-9.862299919128418","-9.862299919128418","-9.862299919128418"
+"11010048","87","87","87","-9.84399127960205","-9.84399127960205","-9.84399127960205"
+"11534336","91","91","91","-9.772317886352539","-9.772317886352539","-9.772317886352539"
+"12058624","95","95","95","-9.806173324584961","-9.806173324584961","-9.806173324584961"
+"12582912","99","99","99","-9.634217262268066","-9.634217262268066","-9.634217262268066"
+"13107200","103","103","103","-9.603195190429688","-9.603195190429688","-9.603195190429688"
+"13631488","107","107","107","-9.5668306350708","-9.5668306350708","-9.5668306350708"
+"14155776","111","111","111","-9.868393898010254","-9.868393898010254","-9.868393898010254"
+"14680064","115","115","115","-9.479263305664062","-9.479263305664062","-9.479263305664062"
+"15204352","119","119","119","-9.516868591308594","-9.516868591308594","-9.516868591308594"
+"15728640","123","123","123","-9.673318862915039","-9.673318862915039","-9.673318862915039"
+"16252928","127","127","127","-9.560396194458008","-9.560396194458008","-9.560396194458008"
+"16777216","131","131","131","-9.433130264282227","-9.433130264282227","-9.433130264282227"
+"17301504","135","135","135","-9.499381065368652","-9.499381065368652","-9.499381065368652"
+"17825792","139","139","139","-9.558895111083984","-9.558895111083984","-9.558895111083984"
+"18350080","143","143","143","-9.104968070983887","-9.104968070983887","-9.104968070983887"
+"18874368","147","147","147","-9.263216018676758","-9.263216018676758","-9.263216018676758"
+"19398656","151","151","151","-9.690051078796387","-9.690051078796387","-9.690051078796387"
+"19922944","155","155","155","-9.339509010314941","-9.339509010314941","-9.339509010314941"
+"20447232","159","159","159","-9.358259201049805","-9.358259201049805","-9.358259201049805"
+"20971520","163","163","163","-9.415786743164062","-9.415786743164062","-9.415786743164062"
+"21495808","167","167","167","-9.406904220581055","-9.406904220581055","-9.406904220581055"
+"22020096","171","171","171","-9.4617919921875","-9.4617919921875","-9.4617919921875"
+"22544384","175","175","175","-9.424764633178711","-9.424764633178711","-9.424764633178711"
+"23068672","179","179","179","-8.831751823425293","-8.831751823425293","-8.831751823425293"
+"23592960","183","183","183","-8.94803237915039","-8.94803237915039","-8.94803237915039"
+"24117248","187","187","187","-9.292790412902832","-9.292790412902832","-9.292790412902832"
+"24641536","191","191","191","-9.225264549255371","-9.225264549255371","-9.225264549255371"
+"25165824","195","195","195","-9.179900169372559","-9.179900169372559","-9.179900169372559"
+"25690112","199","199","199","-9.356606483459473","-9.356606483459473","-9.356606483459473"
+"26214400","203","203","203","-8.666827201843262","-8.666827201843262","-8.666827201843262"
+"26738688","207","207","207","-9.124837875366211","-9.124837875366211","-9.124837875366211"
+"27262976","211","211","211","-9.170819282531738","-9.170819282531738","-9.170819282531738"
+"27787264","215","215","215","-9.066462516784668","-9.066462516784668","-9.066462516784668"
+"28311552","219","219","219","-8.431180953979492","-8.431180953979492","-8.431180953979492"
+"28835840","223","223","223","-8.78959846496582","-8.78959846496582","-8.78959846496582"
+"29360128","227","227","227","-8.41519546508789","-8.41519546508789","-8.41519546508789"
+"29884416","231","231","231","-8.597110748291016","-8.597110748291016","-8.597110748291016"
+"30408704","235","235","235","-8.30621337890625","-8.30621337890625","-8.30621337890625"
+"30932992","239","239","239","-8.922492027282715","-8.922492027282715","-8.922492027282715"
+"31457280","243","243","243","-8.91647720336914","-8.91647720336914","-8.91647720336914"
+"31981568","247","247","247","-8.888541221618652","-8.888541221618652","-8.888541221618652"
+"32505856","251","251","251","-9.02493953704834","-9.02493953704834","-9.02493953704834"
+"33030144","255","255","255","-8.703207015991211","-8.703207015991211","-8.703207015991211"
+"33554432","259","259","259","-8.286286354064941","-8.286286354064941","-8.286286354064941"
+"34078720","263","263","263","-8.835113525390625","-8.835113525390625","-8.835113525390625"
+"34603008","267","267","267","-8.46471881866455","-8.46471881866455","-8.46471881866455"
+"35127296","271","271","271","-8.196759223937988","-8.196759223937988","-8.196759223937988"
+"35651584","275","275","275","-8.489686012268066","-8.489686012268066","-8.489686012268066"
+"36175872","279","279","279","-8.311279296875","-8.311279296875","-8.311279296875"
+"36700160","283","283","283","-8.027563095092773","-8.027563095092773","-8.027563095092773"
+"37224448","287","287","287","-7.836814880371094","-7.836814880371094","-7.836814880371094"
+"37748736","291","291","291","-7.809538841247559","-7.809538841247559","-7.809538841247559"
+"38273024","295","295","295","-7.795563697814941","-7.795563697814941","-7.795563697814941"
+"38797312","299","299","299","-8.258774757385254","-8.258774757385254","-8.258774757385254"
+"39321600","303","303","303","-8.438544273376465","-8.438544273376465","-8.438544273376465"
+"39845888","307","307","307","-7.85377311706543","-7.85377311706543","-7.85377311706543"
+"40370176","311","311","311","-8.168079376220703","-8.168079376220703","-8.168079376220703"
+"40894464","315","315","315","-8.096928596496582","-8.096928596496582","-8.096928596496582"
+"41418752","319","319","319","-7.37039041519165","-7.37039041519165","-7.37039041519165"
+"41943040","323","323","323","-8.036718368530273","-8.036718368530273","-8.036718368530273"
+"42467328","327","327","327","-7.58516788482666","-7.58516788482666","-7.58516788482666"
+"42991616","331","331","331","-7.963348388671875","-7.963348388671875","-7.963348388671875"
+"43515904","335","335","335","-7.634610652923584","-7.634610652923584","-7.634610652923584"
+"44040192","339","339","339","-7.5532355308532715","-7.5532355308532715","-7.5532355308532715"
+"44564480","343","343","343","-7.674378395080566","-7.674378395080566","-7.674378395080566"
+"45088768","347","347","347","-7.092195987701416","-7.092195987701416","-7.092195987701416"
+"45613056","351","351","351","-7.828216552734375","-7.828216552734375","-7.828216552734375"
+"46137344","355","355","355","-7.717631816864014","-7.717631816864014","-7.717631816864014"
+"46661632","359","359","359","-8.148951530456543","-8.148951530456543","-8.148951530456543"
+"47185920","363","363","363","-8.472125053405762","-8.472125053405762","-8.472125053405762"
+"47710208","367","367","367","-7.277010440826416","-7.277010440826416","-7.277010440826416"
+"48234496","371","371","371","-6.792895317077637","-6.792895317077637","-6.792895317077637"
+"48758784","375","375","375","-7.153288841247559","-7.153288841247559","-7.153288841247559"
+"49283072","379","379","379","-7.542932033538818","-7.542932033538818","-7.542932033538818"
+"49807360","383","383","383","-7.060571193695068","-7.060571193695068","-7.060571193695068"
+"50331648","387","387","387","-7.189024925231934","-7.189024925231934","-7.189024925231934"
+"50855936","391","391","391","-7.270157814025879","-7.270157814025879","-7.270157814025879"
+"51380224","395","395","395","-7.827589511871338","-7.827589511871338","-7.827589511871338"
+"51904512","399","399","399","-7.210005283355713","-7.210005283355713","-7.210005283355713"
+"52428800","403","403","403","-6.797995567321777","-6.797995567321777","-6.797995567321777"
+"52953088","407","407","407","-7.406902313232422","-7.406902313232422","-7.406902313232422"
+"53477376","411","411","411","-7.4502105712890625","-7.4502105712890625","-7.4502105712890625"
+"54001664","415","415","415","-6.259567737579346","-6.259567737579346","-6.259567737579346"
+"54525952","419","419","419","-6.861742973327637","-6.861742973327637","-6.861742973327637"
+"55050240","423","423","423","-7.007745265960693","-7.007745265960693","-7.007745265960693"
+"55574528","427","427","427","-6.969524383544922","-6.969524383544922","-6.969524383544922"
+"56098816","431","431","431","-6.635502815246582","-6.635502815246582","-6.635502815246582"
+"56623104","435","435","435","-6.214888572692871","-6.214888572692871","-6.214888572692871"
+"57147392","439","439","439","-7.1418914794921875","-7.1418914794921875","-7.1418914794921875"
+"57671680","443","443","443","-6.790219783782959","-6.790219783782959","-6.790219783782959"
+"58195968","447","447","447","-6.868386745452881","-6.868386745452881","-6.868386745452881"
+"58720256","451","451","451","-6.991228103637695","-6.991228103637695","-6.991228103637695"
+"59244544","455","455","455","-7.08590030670166","-7.08590030670166","-7.08590030670166"
+"59768832","459","459","459","-6.84920597076416","-6.84920597076416","-6.84920597076416"
+"60293120","463","463","463","-6.679563999176025","-6.679563999176025","-6.679563999176025"
+"60817408","467","467","467","-7.264965534210205","-7.264965534210205","-7.264965534210205"
+"61341696","471","471","471","-6.5172858238220215","-6.5172858238220215","-6.5172858238220215"
+"61865984","475","475","475","-7.013154029846191","-7.013154029846191","-7.013154029846191"
+"62390272","479","479","479","-6.890408039093018","-6.890408039093018","-6.890408039093018"
+"62914560","483","483","483","-6.213476657867432","-6.213476657867432","-6.213476657867432"
+"63438848","487","487","487","-6.2182817459106445","-6.2182817459106445","-6.2182817459106445"
+"63963136","491","491","491","-6.492876052856445","-6.492876052856445","-6.492876052856445"
+"64487424","495","495","495","-6.572102069854736","-6.572102069854736","-6.572102069854736"
+"65011712","499","499","499","-6.322445392608643","-6.322445392608643","-6.322445392608643"
+"65536000","503","503","503","-6.149107933044434","-6.149107933044434","-6.149107933044434"
+"66060288","507","507","507","-6.760223865509033","-6.760223865509033","-6.760223865509033"
+"66584576","511","511","511","-5.836979866027832","-5.836979866027832","-5.836979866027832"
+"67108864","515","515","515","-6.05949592590332","-6.05949592590332","-6.05949592590332"
+"67633152","519","519","519","-7.003397464752197","-7.003397464752197","-7.003397464752197"
+"68157440","523","523","523","-6.715593338012695","-6.715593338012695","-6.715593338012695"
+"68681728","527","527","527","-6.754271507263184","-6.754271507263184","-6.754271507263184"
+"69206016","531","531","531","-6.156022071838379","-6.156022071838379","-6.156022071838379"
+"69730304","535","535","535","-6.319283485412598","-6.319283485412598","-6.319283485412598"
+"70254592","539","539","539","-6.21744441986084","-6.21744441986084","-6.21744441986084"
+"70778880","543","543","543","-6.66522741317749","-6.66522741317749","-6.66522741317749"
+"71303168","547","547","547","-5.818639278411865","-5.818639278411865","-5.818639278411865"
+"71827456","551","551","551","-5.540837287902832","-5.540837287902832","-5.540837287902832"
+"72351744","555","555","555","-6.092514991760254","-6.092514991760254","-6.092514991760254"
+"72876032","559","559","559","-6.138923168182373","-6.138923168182373","-6.138923168182373"
+"73400320","563","563","563","-6.182028293609619","-6.182028293609619","-6.182028293609619"
+"73924608","567","567","567","-6.087350368499756","-6.087350368499756","-6.087350368499756"
+"74448896","571","571","571","-6.0269317626953125","-6.0269317626953125","-6.0269317626953125"
+"74973184","575","575","575","-6.801143646240234","-6.801143646240234","-6.801143646240234"
+"75497472","579","579","579","-6.239560604095459","-6.239560604095459","-6.239560604095459"
+"76021760","583","583","583","-6.053619384765625","-6.053619384765625","-6.053619384765625"
+"76546048","587","587","587","-5.630836009979248","-5.630836009979248","-5.630836009979248"
+"77070336","591","591","591","-6.1125688552856445","-6.1125688552856445","-6.1125688552856445"
+"77594624","595","595","595","-6.17673921585083","-6.17673921585083","-6.17673921585083"
+"78118912","599","599","599","-5.9643778800964355","-5.9643778800964355","-5.9643778800964355"
+"78643200","603","603","603","-5.752536296844482","-5.752536296844482","-5.752536296844482"
+"79167488","607","607","607","-6.367559909820557","-6.367559909820557","-6.367559909820557"
+"79691776","611","611","611","-6.0216288566589355","-6.0216288566589355","-6.0216288566589355"
+"80216064","615","615","615","-5.782961368560791","-5.782961368560791","-5.782961368560791"
+"80740352","619","619","619","-5.931070804595947","-5.931070804595947","-5.931070804595947"
+"81264640","623","623","623","-6.30011510848999","-6.30011510848999","-6.30011510848999"
+"81788928","627","627","627","-5.682901859283447","-5.682901859283447","-5.682901859283447"
+"82313216","631","631","631","-5.648722171783447","-5.648722171783447","-5.648722171783447"
+"82837504","635","635","635","-5.625759124755859","-5.625759124755859","-5.625759124755859"
+"83361792","639","639","639","-5.4177350997924805","-5.4177350997924805","-5.4177350997924805"
+"83886080","643","643","643","-5.47056770324707","-5.47056770324707","-5.47056770324707"
+"84410368","647","647","647","-5.17848014831543","-5.17848014831543","-5.17848014831543"
+"84934656","651","651","651","-5.861546993255615","-5.861546993255615","-5.861546993255615"
+"85458944","655","655","655","-5.137368679046631","-5.137368679046631","-5.137368679046631"
+"85983232","659","659","659","-5.809142112731934","-5.809142112731934","-5.809142112731934"
+"86507520","663","663","663","-4.949546813964844","-4.949546813964844","-4.949546813964844"
+"87031808","667","667","667","-4.972194194793701","-4.972194194793701","-4.972194194793701"
+"87556096","671","671","671","-5.395167350769043","-5.395167350769043","-5.395167350769043"
+"88080384","675","675","675","-4.6283979415893555","-4.6283979415893555","-4.6283979415893555"
+"88604672","679","679","679","-5.1927361488342285","-5.1927361488342285","-5.1927361488342285"
+"89128960","683","683","683","-5.104676246643066","-5.104676246643066","-5.104676246643066"
+"89653248","687","687","687","-5.814145565032959","-5.814145565032959","-5.814145565032959"
+"90177536","691","691","691","-5.177026271820068","-5.177026271820068","-5.177026271820068"
+"90701824","695","695","695","-5.468333721160889","-5.468333721160889","-5.468333721160889"
+"91226112","699","699","699","-5.445929527282715","-5.445929527282715","-5.445929527282715"
+"91750400","703","703","703","-4.940840721130371","-4.940840721130371","-4.940840721130371"
+"92274688","707","707","707","-5.441745281219482","-5.441745281219482","-5.441745281219482"
+"92798976","711","711","711","-5.453848838806152","-5.453848838806152","-5.453848838806152"
+"93323264","715","715","715","-5.156940937042236","-5.156940937042236","-5.156940937042236"
+"93847552","719","719","719","-5.459362506866455","-5.459362506866455","-5.459362506866455"
+"94371840","723","723","723","-5.7520623207092285","-5.7520623207092285","-5.7520623207092285"
+"94896128","727","727","727","-5.469799041748047","-5.469799041748047","-5.469799041748047"
+"95420416","731","731","731","-5.285676002502441","-5.285676002502441","-5.285676002502441"
+"95944704","735","735","735","-5.140302658081055","-5.140302658081055","-5.140302658081055"
+"96468992","739","739","739","-4.992669105529785","-4.992669105529785","-4.992669105529785"
+"96993280","743","743","743","-5.687685012817383","-5.687685012817383","-5.687685012817383"
+"97517568","747","747","747","-4.94851541519165","-4.94851541519165","-4.94851541519165"
+"98041856","751","751","751","-5.473487377166748","-5.473487377166748","-5.473487377166748"
+"98566144","755","755","755","-5.280390739440918","-5.280390739440918","-5.280390739440918"
+"99090432","759","759","759","-5.785419940948486","-5.785419940948486","-5.785419940948486"
+"99614720","763","763","763","-4.959272384643555","-4.959272384643555","-4.959272384643555"
+"100139008","767","767","767","-4.655531406402588","-4.655531406402588","-4.655531406402588"
+"100663296","771","771","771","-5.06303596496582","-5.06303596496582","-5.06303596496582"
+"101187584","775","775","775","-5.183110237121582","-5.183110237121582","-5.183110237121582"
+"101711872","779","779","779","-5.332927703857422","-5.332927703857422","-5.332927703857422"
+"102236160","783","783","783","-5.052170276641846","-5.052170276641846","-5.052170276641846"
+"102760448","787","787","787","-5.59745979309082","-5.59745979309082","-5.59745979309082"
+"103284736","791","791","791","-4.705946922302246","-4.705946922302246","-4.705946922302246"
+"103809024","795","795","795","-5.384334564208984","-5.384334564208984","-5.384334564208984"
+"104333312","799","799","799","-5.294549465179443","-5.294549465179443","-5.294549465179443"
+"104857600","803","803","803","-4.966794490814209","-4.966794490814209","-4.966794490814209"
+"105381888","807","807","807","-5.131435394287109","-5.131435394287109","-5.131435394287109"
+"105906176","811","811","811","-5.188973426818848","-5.188973426818848","-5.188973426818848"
+"106430464","815","815","815","-4.930053234100342","-4.930053234100342","-4.930053234100342"
+"106954752","819","819","819","-4.734565258026123","-4.734565258026123","-4.734565258026123"
+"107479040","823","823","823","-4.869314670562744","-4.869314670562744","-4.869314670562744"
+"108003328","827","827","827","-4.961503028869629","-4.961503028869629","-4.961503028869629"
+"108527616","831","831","831","-4.989423751831055","-4.989423751831055","-4.989423751831055"
+"109051904","835","835","835","-3.8522026538848877","-3.8522026538848877","-3.8522026538848877"
+"109576192","839","839","839","-5.099425792694092","-5.099425792694092","-5.099425792694092"
+"110100480","843","843","843","-5.269590854644775","-5.269590854644775","-5.269590854644775"
+"110624768","847","847","847","-4.967761516571045","-4.967761516571045","-4.967761516571045"
+"111149056","851","851","851","-5.08101749420166","-5.08101749420166","-5.08101749420166"
+"111673344","855","855","855","-4.829315185546875","-4.829315185546875","-4.829315185546875"
+"112197632","859","859","859","-5.200876235961914","-5.200876235961914","-5.200876235961914"
+"112721920","863","863","863","-4.25569486618042","-4.25569486618042","-4.25569486618042"
+"113246208","867","867","867","-4.796185493469238","-4.796185493469238","-4.796185493469238"
+"113770496","871","871","871","-4.774853706359863","-4.774853706359863","-4.774853706359863"
+"114294784","875","875","875","-4.641881465911865","-4.641881465911865","-4.641881465911865"
+"114819072","879","879","879","-4.623525142669678","-4.623525142669678","-4.623525142669678"
+"115343360","883","883","883","-4.902030944824219","-4.902030944824219","-4.902030944824219"
+"115867648","887","887","887","-4.730027198791504","-4.730027198791504","-4.730027198791504"
+"116391936","891","891","891","-5.16632080078125","-5.16632080078125","-5.16632080078125"
+"116916224","895","895","895","-4.812100887298584","-4.812100887298584","-4.812100887298584"
+"117440512","899","899","899","-4.428447723388672","-4.428447723388672","-4.428447723388672"
+"117964800","903","903","903","-5.141603946685791","-5.141603946685791","-5.141603946685791"
+"118489088","907","907","907","-5.474337577819824","-5.474337577819824","-5.474337577819824"
+"119013376","911","911","911","-4.889243125915527","-4.889243125915527","-4.889243125915527"
+"119537664","915","915","915","-4.8634562492370605","-4.8634562492370605","-4.8634562492370605"
+"120061952","919","919","919","-3.8433949947357178","-3.8433949947357178","-3.8433949947357178"
+"120586240","923","923","923","-4.201903820037842","-4.201903820037842","-4.201903820037842"
+"121110528","927","927","927","-4.6757636070251465","-4.6757636070251465","-4.6757636070251465"
+"121634816","931","931","931","-4.5287909507751465","-4.5287909507751465","-4.5287909507751465"
+"122159104","935","935","935","-4.666049003601074","-4.666049003601074","-4.666049003601074"
+"122683392","939","939","939","-4.337522983551025","-4.337522983551025","-4.337522983551025"
+"123207680","943","943","943","-4.388852596282959","-4.388852596282959","-4.388852596282959"
+"123731968","947","947","947","-4.725096225738525","-4.725096225738525","-4.725096225738525"
+"124256256","951","951","951","-4.587471961975098","-4.587471961975098","-4.587471961975098"
+"124780544","955","955","955","-4.741805553436279","-4.741805553436279","-4.741805553436279"
+"125304832","959","959","959","-5.0047149658203125","-5.0047149658203125","-5.0047149658203125"
+"125829120","963","963","963","-3.8311266899108887","-3.8311266899108887","-3.8311266899108887"
+"126353408","967","967","967","-4.371734142303467","-4.371734142303467","-4.371734142303467"
+"126877696","971","971","971","-4.212096214294434","-4.212096214294434","-4.212096214294434"
+"127401984","975","975","975","-4.3661346435546875","-4.3661346435546875","-4.3661346435546875"
+"127926272","979","979","979","-4.692439079284668","-4.692439079284668","-4.692439079284668"
+"128450560","983","983","983","-4.865912914276123","-4.865912914276123","-4.865912914276123"
+"128974848","987","987","987","-3.8741424083709717","-3.8741424083709717","-3.8741424083709717"
+"129499136","991","991","991","-4.518064975738525","-4.518064975738525","-4.518064975738525"
+"130023424","995","995","995","-4.307686805725098","-4.307686805725098","-4.307686805725098"
+"130547712","999","999","999","-4.368228435516357","-4.368228435516357","-4.368228435516357"
+"131072000","1003","1003","1003","-4.6626877784729","-4.6626877784729","-4.6626877784729"
+"131596288","1007","1007","1007","-4.859768390655518","-4.859768390655518","-4.859768390655518"
+"132120576","1011","1011","1011","-4.760822296142578","-4.760822296142578","-4.760822296142578"
+"132644864","1015","1015","1015","-4.416811943054199","-4.416811943054199","-4.416811943054199"
+"133169152","1019","1019","1019","-4.4574737548828125","-4.4574737548828125","-4.4574737548828125"
+"133693440","1023","1023","1023","-4.949069499969482","-4.949069499969482","-4.949069499969482"
+"134217728","1027","1027","1027","-4.662948131561279","-4.662948131561279","-4.662948131561279"
+"134742016","1031","1031","1031","-4.573500156402588","-4.573500156402588","-4.573500156402588"
+"135266304","1035","1035","1035","-5.369050025939941","-5.369050025939941","-5.369050025939941"
+"135790592","1039","1039","1039","-4.1193461418151855","-4.1193461418151855","-4.1193461418151855"
+"136314880","1043","1043","1043","-3.9631853103637695","-3.9631853103637695","-3.9631853103637695"
+"136839168","1047","1047","1047","-3.997302532196045","-3.997302532196045","-3.997302532196045"
+"137363456","1051","1051","1051","-3.912998914718628","-3.912998914718628","-3.912998914718628"
+"137887744","1055","1055","1055","-4.737585544586182","-4.737585544586182","-4.737585544586182"
+"138412032","1059","1059","1059","-3.679762840270996","-3.679762840270996","-3.679762840270996"
+"138936320","1063","1063","1063","-4.3091840744018555","-4.3091840744018555","-4.3091840744018555"
+"139460608","1067","1067","1067","-3.6116316318511963","-3.6116316318511963","-3.6116316318511963"
+"139984896","1071","1071","1071","-4.849607467651367","-4.849607467651367","-4.849607467651367"
+"140509184","1075","1075","1075","-4.503736972808838","-4.503736972808838","-4.503736972808838"
+"141033472","1079","1079","1079","-5.197135925292969","-5.197135925292969","-5.197135925292969"
+"141557760","1083","1083","1083","-4.308148384094238","-4.308148384094238","-4.308148384094238"
+"142082048","1087","1087","1087","-4.151874542236328","-4.151874542236328","-4.151874542236328"
+"142606336","1091","1091","1091","-4.839818477630615","-4.839818477630615","-4.839818477630615"
+"143130624","1095","1095","1095","-4.645565509796143","-4.645565509796143","-4.645565509796143"
+"143654912","1099","1099","1099","-3.810669183731079","-3.810669183731079","-3.810669183731079"
+"144179200","1103","1103","1103","-4.071512222290039","-4.071512222290039","-4.071512222290039"
+"144703488","1107","1107","1107","-4.071194171905518","-4.071194171905518","-4.071194171905518"
+"145227776","1111","1111","1111","-4.233304500579834","-4.233304500579834","-4.233304500579834"
+"145752064","1115","1115","1115","-4.5623626708984375","-4.5623626708984375","-4.5623626708984375"
+"146276352","1119","1119","1119","-4.085054874420166","-4.085054874420166","-4.085054874420166"
+"146800640","1123","1123","1123","-4.191879749298096","-4.191879749298096","-4.191879749298096"
+"147324928","1127","1127","1127","-3.693333625793457","-3.693333625793457","-3.693333625793457"
+"147849216","1131","1131","1131","-4.1124114990234375","-4.1124114990234375","-4.1124114990234375"
+"148373504","1135","1135","1135","-4.413700580596924","-4.413700580596924","-4.413700580596924"
+"148897792","1139","1139","1139","-3.699716806411743","-3.699716806411743","-3.699716806411743"
+"149422080","1143","1143","1143","-3.739741802215576","-3.739741802215576","-3.739741802215576"
+"149946368","1147","1147","1147","-3.3868932723999023","-3.3868932723999023","-3.3868932723999023"
+"150470656","1151","1151","1151","-3.6126012802124023","-3.6126012802124023","-3.6126012802124023"
+"150994944","1155","1155","1155","-3.460085868835449","-3.460085868835449","-3.460085868835449"
+"151519232","1159","1159","1159","-4.275721073150635","-4.275721073150635","-4.275721073150635"
+"152043520","1163","1163","1163","-3.4735476970672607","-3.4735476970672607","-3.4735476970672607"
+"152567808","1167","1167","1167","-4.07192850112915","-4.07192850112915","-4.07192850112915"
+"153092096","1171","1171","1171","-4.2152018547058105","-4.2152018547058105","-4.2152018547058105"
+"153616384","1175","1175","1175","-4.414291858673096","-4.414291858673096","-4.414291858673096"
+"154140672","1179","1179","1179","-3.94621205329895","-3.94621205329895","-3.94621205329895"
+"154664960","1183","1183","1183","-3.7558226585388184","-3.7558226585388184","-3.7558226585388184"
+"155189248","1187","1187","1187","-3.9257278442382812","-3.9257278442382812","-3.9257278442382812"
+"155713536","1191","1191","1191","-4.250458240509033","-4.250458240509033","-4.250458240509033"
+"156237824","1195","1195","1195","-3.6897246837615967","-3.6897246837615967","-3.6897246837615967"
+"156762112","1199","1199","1199","-3.3784236907958984","-3.3784236907958984","-3.3784236907958984"
+"157286400","1203","1203","1203","-3.827176332473755","-3.827176332473755","-3.827176332473755"
+"157810688","1207","1207","1207","-3.9589550495147705","-3.9589550495147705","-3.9589550495147705"
+"158334976","1211","1211","1211","-4.077770709991455","-4.077770709991455","-4.077770709991455"
+"158859264","1215","1215","1215","-3.637303352355957","-3.637303352355957","-3.637303352355957"
+"159383552","1219","1219","1219","-3.7946150302886963","-3.7946150302886963","-3.7946150302886963"
+"159907840","1223","1223","1223","-3.1853103637695312","-3.1853103637695312","-3.1853103637695312"
+"160432128","1227","1227","1227","-3.830914258956909","-3.830914258956909","-3.830914258956909"
+"160956416","1231","1231","1231","-3.2758991718292236","-3.2758991718292236","-3.2758991718292236"
+"161480704","1235","1235","1235","-3.834038257598877","-3.834038257598877","-3.834038257598877"
+"162004992","1239","1239","1239","-2.742605209350586","-2.742605209350586","-2.742605209350586"
+"162529280","1243","1243","1243","-3.7334768772125244","-3.7334768772125244","-3.7334768772125244"
+"163053568","1247","1247","1247","-3.662966251373291","-3.662966251373291","-3.662966251373291"
+"163577856","1251","1251","1251","-3.318852424621582","-3.318852424621582","-3.318852424621582"
+"164102144","1255","1255","1255","-3.4500834941864014","-3.4500834941864014","-3.4500834941864014"
+"164626432","1259","1259","1259","-3.497697353363037","-3.497697353363037","-3.497697353363037"
+"165150720","1263","1263","1263","-3.43571138381958","-3.43571138381958","-3.43571138381958"
+"165675008","1267","1267","1267","-3.4102675914764404","-3.4102675914764404","-3.4102675914764404"
+"166199296","1271","1271","1271","-3.313722848892212","-3.313722848892212","-3.313722848892212"
+"166723584","1275","1275","1275","-3.4593935012817383","-3.4593935012817383","-3.4593935012817383"
+"167247872","1279","1279","1279","-3.274519920349121","-3.274519920349121","-3.274519920349121"
+"167772160","1283","1283","1283","-3.128680944442749","-3.128680944442749","-3.128680944442749"
+"168296448","1287","1287","1287","-3.5066893100738525","-3.5066893100738525","-3.5066893100738525"
+"168820736","1291","1291","1291","-3.219996213912964","-3.219996213912964","-3.219996213912964"
+"169345024","1295","1295","1295","-4.629025936126709","-4.629025936126709","-4.629025936126709"
+"169869312","1299","1299","1299","-3.2230052947998047","-3.2230052947998047","-3.2230052947998047"
+"170393600","1303","1303","1303","-3.2781126499176025","-3.2781126499176025","-3.2781126499176025"
+"170917888","1307","1307","1307","-3.660203218460083","-3.660203218460083","-3.660203218460083"
+"171442176","1311","1311","1311","-3.096933126449585","-3.096933126449585","-3.096933126449585"
+"171966464","1315","1315","1315","-3.0776641368865967","-3.0776641368865967","-3.0776641368865967"
+"172490752","1319","1319","1319","-2.957444906234741","-2.957444906234741","-2.957444906234741"
+"173015040","1323","1323","1323","-3.030050277709961","-3.030050277709961","-3.030050277709961"
+"173539328","1327","1327","1327","-3.251584768295288","-3.251584768295288","-3.251584768295288"
+"174063616","1331","1331","1331","-3.6122243404388428","-3.6122243404388428","-3.6122243404388428"
+"174587904","1335","1335","1335","-3.3043923377990723","-3.3043923377990723","-3.3043923377990723"
+"175112192","1339","1339","1339","-2.9093518257141113","-2.9093518257141113","-2.9093518257141113"
+"175636480","1343","1343","1343","-3.2345874309539795","-3.2345874309539795","-3.2345874309539795"
+"176160768","1347","1347","1347","-3.1456313133239746","-3.1456313133239746","-3.1456313133239746"
+"176685056","1351","1351","1351","-3.03552508354187","-3.03552508354187","-3.03552508354187"
+"177209344","1355","1355","1355","-3.5365734100341797","-3.5365734100341797","-3.5365734100341797"
+"177733632","1359","1359","1359","-3.475559711456299","-3.475559711456299","-3.475559711456299"
+"178257920","1363","1363","1363","-3.0250768661499023","-3.0250768661499023","-3.0250768661499023"
+"178782208","1367","1367","1367","-2.73549485206604","-2.73549485206604","-2.73549485206604"
+"179306496","1371","1371","1371","-3.0916926860809326","-3.0916926860809326","-3.0916926860809326"
+"179830784","1375","1375","1375","-3.10208797454834","-3.10208797454834","-3.10208797454834"
+"180355072","1379","1379","1379","-3.5820388793945312","-3.5820388793945312","-3.5820388793945312"
+"180879360","1383","1383","1383","-2.864271879196167","-2.864271879196167","-2.864271879196167"
+"181403648","1387","1387","1387","-2.9180994033813477","-2.9180994033813477","-2.9180994033813477"
+"181927936","1391","1391","1391","-2.93255615234375","-2.93255615234375","-2.93255615234375"
+"182452224","1395","1395","1395","-3.5976998805999756","-3.5976998805999756","-3.5976998805999756"
+"182976512","1399","1399","1399","-3.6290600299835205","-3.6290600299835205","-3.6290600299835205"
+"183500800","1403","1403","1403","-2.6249444484710693","-2.6249444484710693","-2.6249444484710693"
+"184025088","1407","1407","1407","-2.6709322929382324","-2.6709322929382324","-2.6709322929382324"
+"184549376","1411","1411","1411","-2.7676260471343994","-2.7676260471343994","-2.7676260471343994"
+"185073664","1415","1415","1415","-2.9194090366363525","-2.9194090366363525","-2.9194090366363525"
+"185597952","1419","1419","1419","-2.863804578781128","-2.863804578781128","-2.863804578781128"
+"186122240","1423","1423","1423","-3.2217466831207275","-3.2217466831207275","-3.2217466831207275"
+"186646528","1427","1427","1427","-3.1422080993652344","-3.1422080993652344","-3.1422080993652344"
+"187170816","1431","1431","1431","-2.36582350730896","-2.36582350730896","-2.36582350730896"
+"187695104","1435","1435","1435","-3.035529136657715","-3.035529136657715","-3.035529136657715"
+"188219392","1439","1439","1439","-2.511152505874634","-2.511152505874634","-2.511152505874634"
+"188743680","1443","1443","1443","-2.690591335296631","-2.690591335296631","-2.690591335296631"
+"189267968","1447","1447","1447","-2.246840715408325","-2.246840715408325","-2.246840715408325"
+"189792256","1451","1451","1451","-2.522975444793701","-2.522975444793701","-2.522975444793701"
+"190316544","1455","1455","1455","-2.9578917026519775","-2.9578917026519775","-2.9578917026519775"
+"190840832","1459","1459","1459","-3.0048668384552","-3.0048668384552","-3.0048668384552"
+"191365120","1463","1463","1463","-3.027970552444458","-3.027970552444458","-3.027970552444458"
+"191889408","1467","1467","1467","-2.6962411403656006","-2.6962411403656006","-2.6962411403656006"
+"192413696","1471","1471","1471","-2.9335713386535645","-2.9335713386535645","-2.9335713386535645"
+"192937984","1475","1475","1475","-2.747267007827759","-2.747267007827759","-2.747267007827759"
+"193462272","1479","1479","1479","-2.837118148803711","-2.837118148803711","-2.837118148803711"
+"193986560","1483","1483","1483","-2.8812170028686523","-2.8812170028686523","-2.8812170028686523"
+"194510848","1487","1487","1487","-2.608224630355835","-2.608224630355835","-2.608224630355835"
+"195035136","1491","1491","1491","-2.9960453510284424","-2.9960453510284424","-2.9960453510284424"
+"195559424","1495","1495","1495","-2.7481448650360107","-2.7481448650360107","-2.7481448650360107"
+"196083712","1499","1499","1499","-2.608081102371216","-2.608081102371216","-2.608081102371216"
+"196608000","1503","1503","1503","-3.2662229537963867","-3.2662229537963867","-3.2662229537963867"
+"197132288","1507","1507","1507","-2.1700029373168945","-2.1700029373168945","-2.1700029373168945"
+"197656576","1511","1511","1511","-2.524550676345825","-2.524550676345825","-2.524550676345825"
+"198180864","1515","1515","1515","-2.8329570293426514","-2.8329570293426514","-2.8329570293426514"
+"198705152","1519","1519","1519","-2.625319480895996","-2.625319480895996","-2.625319480895996"
+"199229440","1523","1523","1523","-2.8155736923217773","-2.8155736923217773","-2.8155736923217773"
+"199753728","1527","1527","1527","-2.9392223358154297","-2.9392223358154297","-2.9392223358154297"
+"200278016","1531","1531","1531","-3.389347553253174","-3.389347553253174","-3.389347553253174"
+"200802304","1535","1535","1535","-2.8235232830047607","-2.8235232830047607","-2.8235232830047607"
+"201326592","1539","1539","1539","-2.505545139312744","-2.505545139312744","-2.505545139312744"
+"201850880","1543","1543","1543","-3.122750997543335","-3.122750997543335","-3.122750997543335"
+"202375168","1547","1547","1547","-2.833400249481201","-2.833400249481201","-2.833400249481201"
+"202899456","1551","1551","1551","-2.896549940109253","-2.896549940109253","-2.896549940109253"
+"203423744","1555","1555","1555","-2.6987242698669434","-2.6987242698669434","-2.6987242698669434"
+"203948032","1559","1559","1559","-2.536729574203491","-2.536729574203491","-2.536729574203491"
+"204472320","1563","1563","1563","-2.5467653274536133","-2.5467653274536133","-2.5467653274536133"
+"204996608","1567","1567","1567","-2.738234758377075","-2.738234758377075","-2.738234758377075"
+"205520896","1571","1571","1571","-2.736041784286499","-2.736041784286499","-2.736041784286499"
+"206045184","1575","1575","1575","-3.5070900917053223","-3.5070900917053223","-3.5070900917053223"
+"206569472","1579","1579","1579","-2.565253734588623","-2.565253734588623","-2.565253734588623"
+"207093760","1583","1583","1583","-2.790025472640991","-2.790025472640991","-2.790025472640991"
+"207618048","1587","1587","1587","-2.9046483039855957","-2.9046483039855957","-2.9046483039855957"
+"208142336","1591","1591","1591","-2.9266693592071533","-2.9266693592071533","-2.9266693592071533"
+"208666624","1595","1595","1595","-2.3068675994873047","-2.3068675994873047","-2.3068675994873047"
+"209190912","1599","1599","1599","-2.4411113262176514","-2.4411113262176514","-2.4411113262176514"
+"209715200","1603","1603","1603","-2.8383495807647705","-2.8383495807647705","-2.8383495807647705"
+"210239488","1607","1607","1607","-2.3070993423461914","-2.3070993423461914","-2.3070993423461914"
+"210763776","1611","1611","1611","-2.8990893363952637","-2.8990893363952637","-2.8990893363952637"
+"211288064","1615","1615","1615","-2.6015124320983887","-2.6015124320983887","-2.6015124320983887"
+"211812352","1619","1619","1619","-2.902919292449951","-2.902919292449951","-2.902919292449951"
+"212336640","1623","1623","1623","-2.513861894607544","-2.513861894607544","-2.513861894607544"
+"212860928","1627","1627","1627","-2.6078827381134033","-2.6078827381134033","-2.6078827381134033"
+"213385216","1631","1631","1631","-2.8052303791046143","-2.8052303791046143","-2.8052303791046143"
+"213909504","1635","1635","1635","-3.3120720386505127","-3.3120720386505127","-3.3120720386505127"
+"214433792","1639","1639","1639","-2.4862658977508545","-2.4862658977508545","-2.4862658977508545"
+"214958080","1643","1643","1643","-3.1477694511413574","-3.1477694511413574","-3.1477694511413574"
+"215482368","1647","1647","1647","-2.8232970237731934","-2.8232970237731934","-2.8232970237731934"
+"216006656","1651","1651","1651","-2.2529447078704834","-2.2529447078704834","-2.2529447078704834"
+"216530944","1655","1655","1655","-2.333036422729492","-2.333036422729492","-2.333036422729492"
+"217055232","1659","1659","1659","-2.3384835720062256","-2.3384835720062256","-2.3384835720062256"
+"217579520","1663","1663","1663","-2.872983694076538","-2.872983694076538","-2.872983694076538"
+"218103808","1667","1667","1667","-2.197305679321289","-2.197305679321289","-2.197305679321289"
+"218628096","1671","1671","1671","-2.2381744384765625","-2.2381744384765625","-2.2381744384765625"
+"219152384","1675","1675","1675","-2.8054535388946533","-2.8054535388946533","-2.8054535388946533"
+"219676672","1679","1679","1679","-1.8960516452789307","-1.8960516452789307","-1.8960516452789307"
+"220200960","1683","1683","1683","-3.0544116497039795","-3.0544116497039795","-3.0544116497039795"
+"220725248","1687","1687","1687","-2.399108648300171","-2.399108648300171","-2.399108648300171"
+"221249536","1691","1691","1691","-2.962157726287842","-2.962157726287842","-2.962157726287842"
+"221773824","1695","1695","1695","-2.4714291095733643","-2.4714291095733643","-2.4714291095733643"
+"222298112","1699","1699","1699","-2.3885676860809326","-2.3885676860809326","-2.3885676860809326"
+"222822400","1703","1703","1703","-2.4897890090942383","-2.4897890090942383","-2.4897890090942383"
+"223346688","1707","1707","1707","-2.682389974594116","-2.682389974594116","-2.682389974594116"
+"223870976","1711","1711","1711","-2.8346352577209473","-2.8346352577209473","-2.8346352577209473"
+"224395264","1715","1715","1715","-2.2260982990264893","-2.2260982990264893","-2.2260982990264893"
+"224919552","1719","1719","1719","-2.540605306625366","-2.540605306625366","-2.540605306625366"
+"225443840","1723","1723","1723","-2.011984348297119","-2.011984348297119","-2.011984348297119"
+"225968128","1727","1727","1727","-2.579435348510742","-2.579435348510742","-2.579435348510742"
+"226492416","1731","1731","1731","-2.5755908489227295","-2.5755908489227295","-2.5755908489227295"
+"227016704","1735","1735","1735","-1.7879178524017334","-1.7879178524017334","-1.7879178524017334"
+"227540992","1739","1739","1739","-1.9506233930587769","-1.9506233930587769","-1.9506233930587769"
+"228065280","1743","1743","1743","-2.5389201641082764","-2.5389201641082764","-2.5389201641082764"
+"228589568","1747","1747","1747","-1.961617350578308","-1.961617350578308","-1.961617350578308"
+"229113856","1751","1751","1751","-2.4634454250335693","-2.4634454250335693","-2.4634454250335693"
+"229638144","1755","1755","1755","-2.4047958850860596","-2.4047958850860596","-2.4047958850860596"
+"230162432","1759","1759","1759","-2.6637914180755615","-2.6637914180755615","-2.6637914180755615"
+"230686720","1763","1763","1763","-1.8777766227722168","-1.8777766227722168","-1.8777766227722168"
+"231211008","1767","1767","1767","-2.5853545665740967","-2.5853545665740967","-2.5853545665740967"
+"231735296","1771","1771","1771","-2.181727409362793","-2.181727409362793","-2.181727409362793"
+"232259584","1775","1775","1775","-2.696587562561035","-2.696587562561035","-2.696587562561035"
+"232783872","1779","1779","1779","-2.007917642593384","-2.007917642593384","-2.007917642593384"
+"233308160","1783","1783","1783","-2.277733325958252","-2.277733325958252","-2.277733325958252"
+"233832448","1787","1787","1787","-2.29819655418396","-2.29819655418396","-2.29819655418396"
+"234356736","1791","1791","1791","-2.969128370285034","-2.969128370285034","-2.969128370285034"
+"234881024","1795","1795","1795","-2.569277286529541","-2.569277286529541","-2.569277286529541"
+"235405312","1799","1799","1799","-2.3831446170806885","-2.3831446170806885","-2.3831446170806885"
+"235929600","1803","1803","1803","-1.739413857460022","-1.739413857460022","-1.739413857460022"
+"236453888","1807","1807","1807","-2.312481164932251","-2.312481164932251","-2.312481164932251"
+"236978176","1811","1811","1811","-1.8972141742706299","-1.8972141742706299","-1.8972141742706299"
+"237502464","1815","1815","1815","-2.880523681640625","-2.880523681640625","-2.880523681640625"
+"238026752","1819","1819","1819","-1.922176480293274","-1.922176480293274","-1.922176480293274"
+"238551040","1823","1823","1823","-2.1395108699798584","-2.1395108699798584","-2.1395108699798584"
+"239075328","1827","1827","1827","-2.31270170211792","-2.31270170211792","-2.31270170211792"
+"239599616","1831","1831","1831","-2.3543684482574463","-2.3543684482574463","-2.3543684482574463"
+"240123904","1835","1835","1835","-2.1783363819122314","-2.1783363819122314","-2.1783363819122314"
+"240648192","1839","1839","1839","-1.7098784446716309","-1.7098784446716309","-1.7098784446716309"
+"241172480","1843","1843","1843","-1.9282327890396118","-1.9282327890396118","-1.9282327890396118"
+"241696768","1847","1847","1847","-1.9707638025283813","-1.9707638025283813","-1.9707638025283813"
+"242221056","1851","1851","1851","-2.256343126296997","-2.256343126296997","-2.256343126296997"
+"242745344","1855","1855","1855","-2.229785203933716","-2.229785203933716","-2.229785203933716"
+"243269632","1859","1859","1859","-1.811026930809021","-1.811026930809021","-1.811026930809021"
+"243793920","1863","1863","1863","-1.8102340698242188","-1.8102340698242188","-1.8102340698242188"
+"244318208","1867","1867","1867","-1.806150197982788","-1.806150197982788","-1.806150197982788"
+"244842496","1871","1871","1871","-1.9887566566467285","-1.9887566566467285","-1.9887566566467285"
+"245366784","1875","1875","1875","-1.7933599948883057","-1.7933599948883057","-1.7933599948883057"
+"245891072","1879","1879","1879","-1.830987811088562","-1.830987811088562","-1.830987811088562"
+"246415360","1883","1883","1883","-1.8169021606445312","-1.8169021606445312","-1.8169021606445312"
+"246939648","1887","1887","1887","-1.9817698001861572","-1.9817698001861572","-1.9817698001861572"
+"247463936","1891","1891","1891","-1.8897666931152344","-1.8897666931152344","-1.8897666931152344"
+"247988224","1895","1895","1895","-2.211599588394165","-2.211599588394165","-2.211599588394165"
+"248512512","1899","1899","1899","-1.9018052816390991","-1.9018052816390991","-1.9018052816390991"
+"249036800","1903","1903","1903","-2.0883777141571045","-2.0883777141571045","-2.0883777141571045"
+"249561088","1907","1907","1907","-2.1936542987823486","-2.1936542987823486","-2.1936542987823486"
+"250085376","1911","1911","1911","-1.3059237003326416","-1.3059237003326416","-1.3059237003326416"
+"250609664","1915","1915","1915","-1.900916576385498","-1.900916576385498","-1.900916576385498"
+"251133952","1919","1919","1919","-2.049431324005127","-2.049431324005127","-2.049431324005127"
+"251658240","1923","1923","1923","-1.8988022804260254","-1.8988022804260254","-1.8988022804260254"
+"252182528","1927","1927","1927","-2.267333984375","-2.267333984375","-2.267333984375"
+"252706816","1931","1931","1931","-2.129584550857544","-2.129584550857544","-2.129584550857544"
+"253231104","1935","1935","1935","-2.064103126525879","-2.064103126525879","-2.064103126525879"
+"253755392","1939","1939","1939","-2.2898824214935303","-2.2898824214935303","-2.2898824214935303"
+"254279680","1943","1943","1943","-2.62958025932312","-2.62958025932312","-2.62958025932312"
+"254803968","1947","1947","1947","-1.84613835811615","-1.84613835811615","-1.84613835811615"
+"255328256","1951","1951","1951","-2.2546820640563965","-2.2546820640563965","-2.2546820640563965"
+"255852544","1955","1955","1955","-2.2018301486968994","-2.2018301486968994","-2.2018301486968994"
+"256376832","1959","1959","1959","-1.7200255393981934","-1.7200255393981934","-1.7200255393981934"
+"256901120","1963","1963","1963","-1.933887004852295","-1.933887004852295","-1.933887004852295"
+"257425408","1967","1967","1967","-1.4853700399398804","-1.4853700399398804","-1.4853700399398804"
+"257949696","1971","1971","1971","-1.4241224527359009","-1.4241224527359009","-1.4241224527359009"
+"258473984","1975","1975","1975","-2.0002853870391846","-2.0002853870391846","-2.0002853870391846"
+"258998272","1979","1979","1979","-1.8828716278076172","-1.8828716278076172","-1.8828716278076172"
+"259522560","1983","1983","1983","-2.621931314468384","-2.621931314468384","-2.621931314468384"
+"260046848","1987","1987","1987","-1.2470252513885498","-1.2470252513885498","-1.2470252513885498"
+"260571136","1991","1991","1991","-2.1243481636047363","-2.1243481636047363","-2.1243481636047363"
+"261095424","1995","1995","1995","-1.6206262111663818","-1.6206262111663818","-1.6206262111663818"
+"261619712","1999","1999","1999","-2.206028461456299","-2.206028461456299","-2.206028461456299"
+"262144000","2003","2003","2003","-2.112086534500122","-2.112086534500122","-2.112086534500122"
+"262668288","2007","2007","2007","-1.5937137603759766","-1.5937137603759766","-1.5937137603759766"
+"263192576","2011","2011","2011","-1.653401255607605","-1.653401255607605","-1.653401255607605"
+"263716864","2015","2015","2015","-1.4156571626663208","-1.4156571626663208","-1.4156571626663208"
+"264241152","2019","2019","2019","-2.2511959075927734","-2.2511959075927734","-2.2511959075927734"
+"264765440","2023","2023","2023","-1.7678157091140747","-1.7678157091140747","-1.7678157091140747"
+"265289728","2027","2027","2027","-2.3137197494506836","-2.3137197494506836","-2.3137197494506836"
+"265814016","2031","2031","2031","-1.9440674781799316","-1.9440674781799316","-1.9440674781799316"
+"266338304","2035","2035","2035","-1.6984143257141113","-1.6984143257141113","-1.6984143257141113"
+"266862592","2039","2039","2039","-1.908078908920288","-1.908078908920288","-1.908078908920288"
+"267386880","2043","2043","2043","-1.9309390783309937","-1.9309390783309937","-1.9309390783309937"
+"267911168","2047","2047","2047","-2.2280831336975098","-2.2280831336975098","-2.2280831336975098"
+"268435456","2051","2051","2051","-2.4018213748931885","-2.4018213748931885","-2.4018213748931885"
+"268959744","2055","2055","2055","-1.8025453090667725","-1.8025453090667725","-1.8025453090667725"
+"269484032","2059","2059","2059","-2.2960736751556396","-2.2960736751556396","-2.2960736751556396"
+"270008320","2063","2063","2063","-2.1044201850891113","-2.1044201850891113","-2.1044201850891113"
+"270532608","2067","2067","2067","-1.875675916671753","-1.875675916671753","-1.875675916671753"
+"271056896","2071","2071","2071","-1.8218345642089844","-1.8218345642089844","-1.8218345642089844"
+"271581184","2075","2075","2075","-2.127577066421509","-2.127577066421509","-2.127577066421509"
+"272105472","2079","2079","2079","-1.8709853887557983","-1.8709853887557983","-1.8709853887557983"
+"272629760","2083","2083","2083","-1.4572187662124634","-1.4572187662124634","-1.4572187662124634"
+"273154048","2087","2087","2087","-2.292581796646118","-2.292581796646118","-2.292581796646118"
+"273678336","2091","2091","2091","-2.269587278366089","-2.269587278366089","-2.269587278366089"
+"274202624","2095","2095","2095","-2.7251007556915283","-2.7251007556915283","-2.7251007556915283"
+"274726912","2099","2099","2099","-1.8018832206726074","-1.8018832206726074","-1.8018832206726074"
+"275251200","2103","2103","2103","-1.8979216814041138","-1.8979216814041138","-1.8979216814041138"
+"275775488","2107","2107","2107","-1.5857499837875366","-1.5857499837875366","-1.5857499837875366"
+"276299776","2111","2111","2111","-1.6718369722366333","-1.6718369722366333","-1.6718369722366333"
+"276824064","2115","2115","2115","-1.9474549293518066","-1.9474549293518066","-1.9474549293518066"
+"277348352","2119","2119","2119","-1.8192846775054932","-1.8192846775054932","-1.8192846775054932"
+"277872640","2123","2123","2123","-1.6788859367370605","-1.6788859367370605","-1.6788859367370605"
+"278396928","2127","2127","2127","-2.623866558074951","-2.623866558074951","-2.623866558074951"
+"278921216","2131","2131","2131","-1.6428301334381104","-1.6428301334381104","-1.6428301334381104"
+"279445504","2135","2135","2135","-1.9947755336761475","-1.9947755336761475","-1.9947755336761475"
+"279969792","2139","2139","2139","-2.254659414291382","-2.254659414291382","-2.254659414291382"
+"280494080","2143","2143","2143","-2.1928505897521973","-2.1928505897521973","-2.1928505897521973"
+"281018368","2147","2147","2147","-1.6465532779693604","-1.6465532779693604","-1.6465532779693604"
+"281542656","2151","2151","2151","-1.6166138648986816","-1.6166138648986816","-1.6166138648986816"
+"282066944","2155","2155","2155","-1.7017087936401367","-1.7017087936401367","-1.7017087936401367"
+"282591232","2159","2159","2159","-1.723292350769043","-1.723292350769043","-1.723292350769043"
+"283115520","2163","2163","2163","-1.4567086696624756","-1.4567086696624756","-1.4567086696624756"
+"283639808","2167","2167","2167","-1.6974730491638184","-1.6974730491638184","-1.6974730491638184"
+"284164096","2171","2171","2171","-1.805816411972046","-1.805816411972046","-1.805816411972046"
+"284688384","2175","2175","2175","-1.9102282524108887","-1.9102282524108887","-1.9102282524108887"
+"285212672","2179","2179","2179","-1.8314902782440186","-1.8314902782440186","-1.8314902782440186"
+"285736960","2183","2183","2183","-1.8615663051605225","-1.8615663051605225","-1.8615663051605225"
+"286261248","2187","2187","2187","-1.655299186706543","-1.655299186706543","-1.655299186706543"
+"286785536","2191","2191","2191","-1.3931719064712524","-1.3931719064712524","-1.3931719064712524"
+"287309824","2195","2195","2195","-1.7730190753936768","-1.7730190753936768","-1.7730190753936768"
+"287834112","2199","2199","2199","-2.4461276531219482","-2.4461276531219482","-2.4461276531219482"
+"288358400","2203","2203","2203","-2.4825289249420166","-2.4825289249420166","-2.4825289249420166"
+"288882688","2207","2207","2207","-1.5328373908996582","-1.5328373908996582","-1.5328373908996582"
+"289406976","2211","2211","2211","-2.0097596645355225","-2.0097596645355225","-2.0097596645355225"
+"289931264","2215","2215","2215","-2.1351964473724365","-2.1351964473724365","-2.1351964473724365"
+"290455552","2219","2219","2219","-1.9029595851898193","-1.9029595851898193","-1.9029595851898193"
+"290979840","2223","2223","2223","-2.0925116539001465","-2.0925116539001465","-2.0925116539001465"
+"291504128","2227","2227","2227","-1.8778700828552246","-1.8778700828552246","-1.8778700828552246"
+"292028416","2231","2231","2231","-2.2516236305236816","-2.2516236305236816","-2.2516236305236816"
+"292552704","2235","2235","2235","-1.3232342004776","-1.3232342004776","-1.3232342004776"
+"293076992","2239","2239","2239","-1.9698821306228638","-1.9698821306228638","-1.9698821306228638"
+"293601280","2243","2243","2243","-1.7353850603103638","-1.7353850603103638","-1.7353850603103638"
+"294125568","2247","2247","2247","-1.6838120222091675","-1.6838120222091675","-1.6838120222091675"
+"294649856","2251","2251","2251","-1.4314472675323486","-1.4314472675323486","-1.4314472675323486"
+"295174144","2255","2255","2255","-1.3665493726730347","-1.3665493726730347","-1.3665493726730347"
+"295698432","2259","2259","2259","-2.0312411785125732","-2.0312411785125732","-2.0312411785125732"
+"296222720","2263","2263","2263","-1.6631543636322021","-1.6631543636322021","-1.6631543636322021"
+"296747008","2267","2267","2267","-1.5683043003082275","-1.5683043003082275","-1.5683043003082275"
+"297271296","2271","2271","2271","-1.8537347316741943","-1.8537347316741943","-1.8537347316741943"
+"297795584","2275","2275","2275","-1.6683205366134644","-1.6683205366134644","-1.6683205366134644"
+"298319872","2279","2279","2279","-1.870514154434204","-1.870514154434204","-1.870514154434204"
+"298844160","2283","2283","2283","-1.6494011878967285","-1.6494011878967285","-1.6494011878967285"
+"299368448","2287","2287","2287","-1.9597285985946655","-1.9597285985946655","-1.9597285985946655"
+"299892736","2291","2291","2291","-1.9763096570968628","-1.9763096570968628","-1.9763096570968628"
+"300417024","2295","2295","2295","-1.6533976793289185","-1.6533976793289185","-1.6533976793289185"
+"300941312","2299","2299","2299","-1.3458967208862305","-1.3458967208862305","-1.3458967208862305"
+"301465600","2303","2303","2303","-1.8462469577789307","-1.8462469577789307","-1.8462469577789307"
+"301989888","2307","2307","2307","-1.918578028678894","-1.918578028678894","-1.918578028678894"
+"302514176","2311","2311","2311","-1.5269927978515625","-1.5269927978515625","-1.5269927978515625"
+"303038464","2315","2315","2315","-1.4597034454345703","-1.4597034454345703","-1.4597034454345703"
+"303562752","2319","2319","2319","-1.919063925743103","-1.919063925743103","-1.919063925743103"
+"304087040","2323","2323","2323","-1.6155897378921509","-1.6155897378921509","-1.6155897378921509"
+"304611328","2327","2327","2327","-1.8614275455474854","-1.8614275455474854","-1.8614275455474854"
+"305135616","2331","2331","2331","-1.586240530014038","-1.586240530014038","-1.586240530014038"
+"305659904","2335","2335","2335","-1.2528311014175415","-1.2528311014175415","-1.2528311014175415"
+"306184192","2339","2339","2339","-1.8528761863708496","-1.8528761863708496","-1.8528761863708496"
+"306708480","2343","2343","2343","-1.7576329708099365","-1.7576329708099365","-1.7576329708099365"
+"307232768","2347","2347","2347","-1.9346914291381836","-1.9346914291381836","-1.9346914291381836"
+"307757056","2351","2351","2351","-2.06091570854187","-2.06091570854187","-2.06091570854187"
+"308281344","2355","2355","2355","-1.8656001091003418","-1.8656001091003418","-1.8656001091003418"
+"308805632","2359","2359","2359","-1.2922592163085938","-1.2922592163085938","-1.2922592163085938"
+"309329920","2363","2363","2363","-1.8237887620925903","-1.8237887620925903","-1.8237887620925903"
+"309854208","2367","2367","2367","-2.0107715129852295","-2.0107715129852295","-2.0107715129852295"
+"310378496","2371","2371","2371","-1.8054298162460327","-1.8054298162460327","-1.8054298162460327"
+"310902784","2375","2375","2375","-1.6298246383666992","-1.6298246383666992","-1.6298246383666992"
+"311427072","2379","2379","2379","-1.4738497734069824","-1.4738497734069824","-1.4738497734069824"
+"311951360","2383","2383","2383","-1.46359384059906","-1.46359384059906","-1.46359384059906"
+"312475648","2387","2387","2387","-1.3203896284103394","-1.3203896284103394","-1.3203896284103394"
+"312999936","2391","2391","2391","-1.4139572381973267","-1.4139572381973267","-1.4139572381973267"
+"313524224","2395","2395","2395","-1.5697284936904907","-1.5697284936904907","-1.5697284936904907"
+"314048512","2399","2399","2399","-1.949922800064087","-1.949922800064087","-1.949922800064087"
+"314572800","2403","2403","2403","-1.509547233581543","-1.509547233581543","-1.509547233581543"
+"315097088","2407","2407","2407","-1.3361403942108154","-1.3361403942108154","-1.3361403942108154"
+"315621376","2411","2411","2411","-1.3232018947601318","-1.3232018947601318","-1.3232018947601318"
+"316145664","2415","2415","2415","-1.2777822017669678","-1.2777822017669678","-1.2777822017669678"
+"316669952","2419","2419","2419","-1.3824098110198975","-1.3824098110198975","-1.3824098110198975"
+"317194240","2423","2423","2423","-1.8129386901855469","-1.8129386901855469","-1.8129386901855469"
+"317718528","2427","2427","2427","-1.5646247863769531","-1.5646247863769531","-1.5646247863769531"
+"318242816","2431","2431","2431","-2.3304555416107178","-2.3304555416107178","-2.3304555416107178"
+"318767104","2435","2435","2435","-1.9148095846176147","-1.9148095846176147","-1.9148095846176147"
+"319291392","2439","2439","2439","-1.386902093887329","-1.386902093887329","-1.386902093887329"
+"319815680","2443","2443","2443","-1.6933382749557495","-1.6933382749557495","-1.6933382749557495"
+"320339968","2447","2447","2447","-1.4924602508544922","-1.4924602508544922","-1.4924602508544922"
+"320864256","2451","2451","2451","-1.484609603881836","-1.484609603881836","-1.484609603881836"
+"321388544","2455","2455","2455","-1.6670070886611938","-1.6670070886611938","-1.6670070886611938"
+"321912832","2459","2459","2459","-1.3888044357299805","-1.3888044357299805","-1.3888044357299805"
+"322437120","2463","2463","2463","-1.2109928131103516","-1.2109928131103516","-1.2109928131103516"
+"322961408","2467","2467","2467","-1.6259123086929321","-1.6259123086929321","-1.6259123086929321"
+"323485696","2471","2471","2471","-1.7330378293991089","-1.7330378293991089","-1.7330378293991089"
+"324009984","2475","2475","2475","-1.8666008710861206","-1.8666008710861206","-1.8666008710861206"
+"324534272","2479","2479","2479","-2.0096139907836914","-2.0096139907836914","-2.0096139907836914"
+"325058560","2483","2483","2483","-1.882660150527954","-1.882660150527954","-1.882660150527954"
+"325582848","2487","2487","2487","-1.6095091104507446","-1.6095091104507446","-1.6095091104507446"
+"326107136","2491","2491","2491","-1.4776328802108765","-1.4776328802108765","-1.4776328802108765"
+"326631424","2495","2495","2495","-1.3420276641845703","-1.3420276641845703","-1.3420276641845703"
+"327155712","2499","2499","2499","-1.2702358961105347","-1.2702358961105347","-1.2702358961105347"
+"327680000","2503","2503","2503","-1.736933708190918","-1.736933708190918","-1.736933708190918"
+"328204288","2507","2507","2507","-1.7417223453521729","-1.7417223453521729","-1.7417223453521729"
+"328728576","2511","2511","2511","-1.9155364036560059","-1.9155364036560059","-1.9155364036560059"
+"329252864","2515","2515","2515","-1.3555984497070312","-1.3555984497070312","-1.3555984497070312"
+"329777152","2519","2519","2519","-1.8930797576904297","-1.8930797576904297","-1.8930797576904297"
+"330301440","2523","2523","2523","-1.5114840269088745","-1.5114840269088745","-1.5114840269088745"
+"330825728","2527","2527","2527","-1.8296852111816406","-1.8296852111816406","-1.8296852111816406"
+"331350016","2531","2531","2531","-1.5204912424087524","-1.5204912424087524","-1.5204912424087524"
+"331874304","2535","2535","2535","-1.5356152057647705","-1.5356152057647705","-1.5356152057647705"
+"332398592","2539","2539","2539","-1.351586937904358","-1.351586937904358","-1.351586937904358"
+"332922880","2543","2543","2543","-1.4720369577407837","-1.4720369577407837","-1.4720369577407837"
+"333447168","2547","2547","2547","-1.5191247463226318","-1.5191247463226318","-1.5191247463226318"
+"333971456","2551","2551","2551","-1.47837233543396","-1.47837233543396","-1.47837233543396"
+"334495744","2555","2555","2555","-1.707527995109558","-1.707527995109558","-1.707527995109558"
+"335020032","2559","2559","2559","-1.388843297958374","-1.388843297958374","-1.388843297958374"
+"335544320","2563","2563","2563","-1.5142364501953125","-1.5142364501953125","-1.5142364501953125"
+"336068608","2567","2567","2567","-1.6617618799209595","-1.6617618799209595","-1.6617618799209595"
+"336592896","2571","2571","2571","-1.394510269165039","-1.394510269165039","-1.394510269165039"
+"337117184","2575","2575","2575","-1.6553105115890503","-1.6553105115890503","-1.6553105115890503"
+"337641472","2579","2579","2579","-1.8646721839904785","-1.8646721839904785","-1.8646721839904785"
+"338165760","2583","2583","2583","-1.5137449502944946","-1.5137449502944946","-1.5137449502944946"
+"338690048","2587","2587","2587","-1.544411540031433","-1.544411540031433","-1.544411540031433"
+"339214336","2591","2591","2591","-1.898559331893921","-1.898559331893921","-1.898559331893921"
+"339738624","2595","2595","2595","-1.3586146831512451","-1.3586146831512451","-1.3586146831512451"
+"340262912","2599","2599","2599","-1.6832313537597656","-1.6832313537597656","-1.6832313537597656"
+"340787200","2603","2603","2603","-1.631095051765442","-1.631095051765442","-1.631095051765442"
+"341311488","2607","2607","2607","-1.2153706550598145","-1.2153706550598145","-1.2153706550598145"
+"341835776","2611","2611","2611","-1.5522810220718384","-1.5522810220718384","-1.5522810220718384"
+"342360064","2615","2615","2615","-1.8018081188201904","-1.8018081188201904","-1.8018081188201904"
+"342884352","2619","2619","2619","-1.2820905447006226","-1.2820905447006226","-1.2820905447006226"
+"343408640","2623","2623","2623","-0.9632264971733093","-0.9632264971733093","-0.9632264971733093"
+"343932928","2627","2627","2627","-1.1878585815429688","-1.1878585815429688","-1.1878585815429688"
+"344457216","2631","2631","2631","-1.4693195819854736","-1.4693195819854736","-1.4693195819854736"
+"344981504","2635","2635","2635","-1.528245210647583","-1.528245210647583","-1.528245210647583"
+"345505792","2639","2639","2639","-1.654512882232666","-1.654512882232666","-1.654512882232666"
+"346030080","2643","2643","2643","-1.6322087049484253","-1.6322087049484253","-1.6322087049484253"
+"346554368","2647","2647","2647","-1.5704536437988281","-1.5704536437988281","-1.5704536437988281"
+"347078656","2651","2651","2651","-1.7390950918197632","-1.7390950918197632","-1.7390950918197632"
+"347602944","2655","2655","2655","-1.4509801864624023","-1.4509801864624023","-1.4509801864624023"
+"348127232","2659","2659","2659","-1.3843841552734375","-1.3843841552734375","-1.3843841552734375"
+"348651520","2663","2663","2663","-1.8233698606491089","-1.8233698606491089","-1.8233698606491089"
+"349175808","2667","2667","2667","-1.3422892093658447","-1.3422892093658447","-1.3422892093658447"
+"349700096","2671","2671","2671","-1.3048162460327148","-1.3048162460327148","-1.3048162460327148"
+"350224384","2675","2675","2675","-0.7924509048461914","-0.7924509048461914","-0.7924509048461914"
+"350748672","2679","2679","2679","-1.2940069437026978","-1.2940069437026978","-1.2940069437026978"
+"351272960","2683","2683","2683","-1.5503796339035034","-1.5503796339035034","-1.5503796339035034"
+"351797248","2687","2687","2687","-1.6732535362243652","-1.6732535362243652","-1.6732535362243652"
+"352321536","2691","2691","2691","-1.1120195388793945","-1.1120195388793945","-1.1120195388793945"
+"352845824","2695","2695","2695","-1.9403845071792603","-1.9403845071792603","-1.9403845071792603"
+"353370112","2699","2699","2699","-1.6042327880859375","-1.6042327880859375","-1.6042327880859375"
+"353894400","2703","2703","2703","-1.3650933504104614","-1.3650933504104614","-1.3650933504104614"
+"354418688","2707","2707","2707","-1.1119965314865112","-1.1119965314865112","-1.1119965314865112"
+"354942976","2711","2711","2711","-1.0513362884521484","-1.0513362884521484","-1.0513362884521484"
+"355467264","2715","2715","2715","-1.851422667503357","-1.851422667503357","-1.851422667503357"
+"355991552","2719","2719","2719","-1.115903615951538","-1.115903615951538","-1.115903615951538"
+"356515840","2723","2723","2723","-1.3876162767410278","-1.3876162767410278","-1.3876162767410278"
+"357040128","2727","2727","2727","-1.5539579391479492","-1.5539579391479492","-1.5539579391479492"
+"357564416","2731","2731","2731","-1.6146188974380493","-1.6146188974380493","-1.6146188974380493"
+"358088704","2735","2735","2735","-1.5273704528808594","-1.5273704528808594","-1.5273704528808594"
+"358612992","2739","2739","2739","-1.4326521158218384","-1.4326521158218384","-1.4326521158218384"
+"359137280","2743","2743","2743","-1.5713905096054077","-1.5713905096054077","-1.5713905096054077"
+"359661568","2747","2747","2747","-1.279274344444275","-1.279274344444275","-1.279274344444275"
+"360185856","2751","2751","2751","-1.5054481029510498","-1.5054481029510498","-1.5054481029510498"
+"360710144","2755","2755","2755","-1.5170376300811768","-1.5170376300811768","-1.5170376300811768"
+"361234432","2759","2759","2759","-0.8636203408241272","-0.8636203408241272","-0.8636203408241272"
+"361758720","2763","2763","2763","-1.5255666971206665","-1.5255666971206665","-1.5255666971206665"
+"362283008","2767","2767","2767","-1.7501578330993652","-1.7501578330993652","-1.7501578330993652"
+"362807296","2771","2771","2771","-1.4239046573638916","-1.4239046573638916","-1.4239046573638916"
+"363331584","2775","2775","2775","-1.6009281873703003","-1.6009281873703003","-1.6009281873703003"
+"363855872","2779","2779","2779","-1.4144513607025146","-1.4144513607025146","-1.4144513607025146"
+"364380160","2783","2783","2783","-1.4018096923828125","-1.4018096923828125","-1.4018096923828125"
+"364904448","2787","2787","2787","-1.25944983959198","-1.25944983959198","-1.25944983959198"
+"365428736","2791","2791","2791","-1.6235870122909546","-1.6235870122909546","-1.6235870122909546"
+"365953024","2795","2795","2795","-0.8927361369132996","-0.8927361369132996","-0.8927361369132996"
+"366477312","2799","2799","2799","-1.2539395093917847","-1.2539395093917847","-1.2539395093917847"
+"367001600","2803","2803","2803","-0.6999514102935791","-0.6999514102935791","-0.6999514102935791"
+"367525888","2807","2807","2807","-1.3668522834777832","-1.3668522834777832","-1.3668522834777832"
+"368050176","2811","2811","2811","-1.3256951570510864","-1.3256951570510864","-1.3256951570510864"
+"368574464","2815","2815","2815","-1.6594622135162354","-1.6594622135162354","-1.6594622135162354"
+"369098752","2819","2819","2819","-1.173427700996399","-1.173427700996399","-1.173427700996399"
+"369623040","2823","2823","2823","-1.0731598138809204","-1.0731598138809204","-1.0731598138809204"
+"370147328","2827","2827","2827","-1.1336982250213623","-1.1336982250213623","-1.1336982250213623"
+"370671616","2831","2831","2831","-1.2637794017791748","-1.2637794017791748","-1.2637794017791748"
+"371195904","2835","2835","2835","-1.794015645980835","-1.794015645980835","-1.794015645980835"
+"371720192","2839","2839","2839","-1.243083119392395","-1.243083119392395","-1.243083119392395"
+"372244480","2843","2843","2843","-1.1560924053192139","-1.1560924053192139","-1.1560924053192139"
+"372768768","2847","2847","2847","-1.0057778358459473","-1.0057778358459473","-1.0057778358459473"
+"373293056","2851","2851","2851","-1.244717001914978","-1.244717001914978","-1.244717001914978"
+"373817344","2855","2855","2855","-1.3856620788574219","-1.3856620788574219","-1.3856620788574219"
+"374341632","2859","2859","2859","-1.124117136001587","-1.124117136001587","-1.124117136001587"
+"374865920","2863","2863","2863","-1.2034364938735962","-1.2034364938735962","-1.2034364938735962"
+"375390208","2867","2867","2867","-1.378248929977417","-1.378248929977417","-1.378248929977417"
+"375914496","2871","2871","2871","-1.327565312385559","-1.327565312385559","-1.327565312385559"
+"376438784","2875","2875","2875","-1.7827012538909912","-1.7827012538909912","-1.7827012538909912"
+"376963072","2879","2879","2879","-1.497092366218567","-1.497092366218567","-1.497092366218567"
+"377487360","2883","2883","2883","-2.1548478603363037","-2.1548478603363037","-2.1548478603363037"
+"378011648","2887","2887","2887","-0.9948355555534363","-0.9948355555534363","-0.9948355555534363"
+"378535936","2891","2891","2891","-1.5105557441711426","-1.5105557441711426","-1.5105557441711426"
+"379060224","2895","2895","2895","-1.107365369796753","-1.107365369796753","-1.107365369796753"
+"379584512","2899","2899","2899","-1.2561185359954834","-1.2561185359954834","-1.2561185359954834"
+"380108800","2903","2903","2903","-1.094970703125","-1.094970703125","-1.094970703125"
+"380633088","2907","2907","2907","-0.9328945875167847","-0.9328945875167847","-0.9328945875167847"
+"381157376","2911","2911","2911","-0.9560290575027466","-0.9560290575027466","-0.9560290575027466"
+"381681664","2915","2915","2915","-1.537628412246704","-1.537628412246704","-1.537628412246704"
+"382205952","2919","2919","2919","-1.389289379119873","-1.389289379119873","-1.389289379119873"
+"382730240","2923","2923","2923","-1.1598458290100098","-1.1598458290100098","-1.1598458290100098"
+"383254528","2927","2927","2927","-1.4269205331802368","-1.4269205331802368","-1.4269205331802368"
+"383778816","2931","2931","2931","-1.6719523668289185","-1.6719523668289185","-1.6719523668289185"
+"384303104","2935","2935","2935","-1.6277849674224854","-1.6277849674224854","-1.6277849674224854"
+"384827392","2939","2939","2939","-1.1430473327636719","-1.1430473327636719","-1.1430473327636719"
+"385351680","2943","2943","2943","-1.699759602546692","-1.699759602546692","-1.699759602546692"
+"385875968","2947","2947","2947","-1.3614180088043213","-1.3614180088043213","-1.3614180088043213"
+"386400256","2951","2951","2951","-1.096224069595337","-1.096224069595337","-1.096224069595337"
+"386924544","2955","2955","2955","-1.1610605716705322","-1.1610605716705322","-1.1610605716705322"
+"387448832","2959","2959","2959","-1.3245452642440796","-1.3245452642440796","-1.3245452642440796"
+"387973120","2963","2963","2963","-0.9273266196250916","-0.9273266196250916","-0.9273266196250916"
+"388497408","2967","2967","2967","-1.1628336906433105","-1.1628336906433105","-1.1628336906433105"
+"389021696","2971","2971","2971","-1.1459736824035645","-1.1459736824035645","-1.1459736824035645"
+"389545984","2975","2975","2975","-1.5116147994995117","-1.5116147994995117","-1.5116147994995117"
+"390070272","2979","2979","2979","-1.3444079160690308","-1.3444079160690308","-1.3444079160690308"
+"390594560","2983","2983","2983","-1.3863282203674316","-1.3863282203674316","-1.3863282203674316"
+"391118848","2987","2987","2987","-0.8115575909614563","-0.8115575909614563","-0.8115575909614563"
+"391643136","2991","2991","2991","-1.1188585758209229","-1.1188585758209229","-1.1188585758209229"
+"392167424","2995","2995","2995","-1.2693756818771362","-1.2693756818771362","-1.2693756818771362"
+"392691712","2999","2999","2999","-1.2104142904281616","-1.2104142904281616","-1.2104142904281616"
+"393216000","3003","3003","3003","-1.3964980840682983","-1.3964980840682983","-1.3964980840682983"
+"393740288","3007","3007","3007","-0.9331510066986084","-0.9331510066986084","-0.9331510066986084"
+"394264576","3011","3011","3011","-1.4603396654129028","-1.4603396654129028","-1.4603396654129028"
+"394788864","3015","3015","3015","-1.1809929609298706","-1.1809929609298706","-1.1809929609298706"
+"395313152","3019","3019","3019","-1.2620302438735962","-1.2620302438735962","-1.2620302438735962"
+"395837440","3023","3023","3023","-1.337949514389038","-1.337949514389038","-1.337949514389038"
+"396361728","3027","3027","3027","-1.0299983024597168","-1.0299983024597168","-1.0299983024597168"
+"396886016","3031","3031","3031","-1.1843327283859253","-1.1843327283859253","-1.1843327283859253"
+"397410304","3035","3035","3035","-0.9631139039993286","-0.9631139039993286","-0.9631139039993286"
+"397934592","3039","3039","3039","-0.8271124958992004","-0.8271124958992004","-0.8271124958992004"
+"398458880","3043","3043","3043","-1.2782799005508423","-1.2782799005508423","-1.2782799005508423"
+"398983168","3047","3047","3047","-1.352593183517456","-1.352593183517456","-1.352593183517456"
+"399507456","3051","3051","3051","-1.261566400527954","-1.261566400527954","-1.261566400527954"
+"400031744","3055","3055","3055","-1.732971429824829","-1.732971429824829","-1.732971429824829"
+"400556032","3059","3059","3059","-1.1333918571472168","-1.1333918571472168","-1.1333918571472168"
+"401080320","3063","3063","3063","-1.4394570589065552","-1.4394570589065552","-1.4394570589065552"
+"401604608","3067","3067","3067","-1.3614752292633057","-1.3614752292633057","-1.3614752292633057"
+"402128896","3071","3071","3071","-1.540605902671814","-1.540605902671814","-1.540605902671814"
+"402653184","3075","3075","3075","-1.5741108655929565","-1.5741108655929565","-1.5741108655929565"
+"403177472","3079","3079","3079","-1.1640477180480957","-1.1640477180480957","-1.1640477180480957"
+"403701760","3083","3083","3083","-0.9432505369186401","-0.9432505369186401","-0.9432505369186401"
+"404226048","3087","3087","3087","-1.1698806285858154","-1.1698806285858154","-1.1698806285858154"
+"404750336","3091","3091","3091","-0.8042238354682922","-0.8042238354682922","-0.8042238354682922"
+"405274624","3095","3095","3095","-1.2405685186386108","-1.2405685186386108","-1.2405685186386108"
+"405798912","3099","3099","3099","-1.4136358499526978","-1.4136358499526978","-1.4136358499526978"
+"406323200","3103","3103","3103","-0.7595045566558838","-0.7595045566558838","-0.7595045566558838"
+"406847488","3107","3107","3107","-1.4317147731781006","-1.4317147731781006","-1.4317147731781006"
+"407371776","3111","3111","3111","-1.2141764163970947","-1.2141764163970947","-1.2141764163970947"
+"407896064","3115","3115","3115","-1.2491005659103394","-1.2491005659103394","-1.2491005659103394"
+"408420352","3119","3119","3119","-1.271041989326477","-1.271041989326477","-1.271041989326477"
+"408944640","3123","3123","3123","-1.1580402851104736","-1.1580402851104736","-1.1580402851104736"
+"409468928","3127","3127","3127","-1.3003530502319336","-1.3003530502319336","-1.3003530502319336"
+"409993216","3131","3131","3131","-1.7364797592163086","-1.7364797592163086","-1.7364797592163086"
+"410517504","3135","3135","3135","-1.2766720056533813","-1.2766720056533813","-1.2766720056533813"
+"411041792","3139","3139","3139","-1.1059026718139648","-1.1059026718139648","-1.1059026718139648"
+"411566080","3143","3143","3143","-0.9961519241333008","-0.9961519241333008","-0.9961519241333008"
+"412090368","3147","3147","3147","-0.8457922339439392","-0.8457922339439392","-0.8457922339439392"
+"412614656","3151","3151","3151","-0.972497820854187","-0.972497820854187","-0.972497820854187"
+"413138944","3155","3155","3155","-1.6386001110076904","-1.6386001110076904","-1.6386001110076904"
+"413663232","3159","3159","3159","-0.9897832870483398","-0.9897832870483398","-0.9897832870483398"
+"414187520","3163","3163","3163","-1.5183546543121338","-1.5183546543121338","-1.5183546543121338"
+"414711808","3167","3167","3167","-1.528063178062439","-1.528063178062439","-1.528063178062439"
+"415236096","3171","3171","3171","-1.180206298828125","-1.180206298828125","-1.180206298828125"
+"415760384","3175","3175","3175","-0.9491130113601685","-0.9491130113601685","-0.9491130113601685"
+"416284672","3179","3179","3179","-1.3935085535049438","-1.3935085535049438","-1.3935085535049438"
+"416808960","3183","3183","3183","-1.3898414373397827","-1.3898414373397827","-1.3898414373397827"
+"417333248","3187","3187","3187","-1.5145751237869263","-1.5145751237869263","-1.5145751237869263"
+"417857536","3191","3191","3191","-1.064734935760498","-1.064734935760498","-1.064734935760498"
+"418381824","3195","3195","3195","-1.3370225429534912","-1.3370225429534912","-1.3370225429534912"
+"418906112","3199","3199","3199","-1.312134861946106","-1.312134861946106","-1.312134861946106"
+"419430400","3203","3203","3203","-1.6103342771530151","-1.6103342771530151","-1.6103342771530151"
+"419954688","3207","3207","3207","-1.2328407764434814","-1.2328407764434814","-1.2328407764434814"
+"420478976","3211","3211","3211","-0.8237849473953247","-0.8237849473953247","-0.8237849473953247"
+"421003264","3215","3215","3215","-1.2571948766708374","-1.2571948766708374","-1.2571948766708374"
+"421527552","3219","3219","3219","-1.4329029321670532","-1.4329029321670532","-1.4329029321670532"
+"422051840","3223","3223","3223","-1.2697925567626953","-1.2697925567626953","-1.2697925567626953"
+"422576128","3227","3227","3227","-1.0877962112426758","-1.0877962112426758","-1.0877962112426758"
+"423100416","3231","3231","3231","-1.4916951656341553","-1.4916951656341553","-1.4916951656341553"
+"423624704","3235","3235","3235","-0.7312080264091492","-0.7312080264091492","-0.7312080264091492"
+"424148992","3239","3239","3239","-0.8475208282470703","-0.8475208282470703","-0.8475208282470703"
+"424673280","3243","3243","3243","-0.8149858713150024","-0.8149858713150024","-0.8149858713150024"
+"425197568","3247","3247","3247","-1.061884880065918","-1.061884880065918","-1.061884880065918"
+"425721856","3251","3251","3251","-1.1236273050308228","-1.1236273050308228","-1.1236273050308228"
+"426246144","3255","3255","3255","-1.2386642694473267","-1.2386642694473267","-1.2386642694473267"
+"426770432","3259","3259","3259","-1.7378476858139038","-1.7378476858139038","-1.7378476858139038"
+"427294720","3263","3263","3263","-1.0424801111221313","-1.0424801111221313","-1.0424801111221313"
+"427819008","3267","3267","3267","-1.934002161026001","-1.934002161026001","-1.934002161026001"
+"428343296","3271","3271","3271","-0.8699919581413269","-0.8699919581413269","-0.8699919581413269"
+"428867584","3275","3275","3275","-1.3496636152267456","-1.3496636152267456","-1.3496636152267456"
+"429391872","3279","3279","3279","-1.35832941532135","-1.35832941532135","-1.35832941532135"
+"429916160","3283","3283","3283","-1.2923823595046997","-1.2923823595046997","-1.2923823595046997"
+"430440448","3287","3287","3287","-1.2243326902389526","-1.2243326902389526","-1.2243326902389526"
+"430964736","3291","3291","3291","-1.003477931022644","-1.003477931022644","-1.003477931022644"
+"431489024","3295","3295","3295","-1.2424414157867432","-1.2424414157867432","-1.2424414157867432"
+"432013312","3299","3299","3299","-0.6339056491851807","-0.6339056491851807","-0.6339056491851807"
+"432537600","3303","3303","3303","-1.252543330192566","-1.252543330192566","-1.252543330192566"
+"433061888","3307","3307","3307","-1.59499192237854","-1.59499192237854","-1.59499192237854"
+"433586176","3311","3311","3311","-0.7590722441673279","-0.7590722441673279","-0.7590722441673279"
+"434110464","3315","3315","3315","-1.0372780561447144","-1.0372780561447144","-1.0372780561447144"
+"434634752","3319","3319","3319","-0.8080282211303711","-0.8080282211303711","-0.8080282211303711"
+"435159040","3323","3323","3323","-1.076810359954834","-1.076810359954834","-1.076810359954834"
+"435683328","3327","3327","3327","-1.001804232597351","-1.001804232597351","-1.001804232597351"
+"436207616","3331","3331","3331","-1.1294870376586914","-1.1294870376586914","-1.1294870376586914"
+"436731904","3335","3335","3335","-1.038659930229187","-1.038659930229187","-1.038659930229187"
+"437256192","3339","3339","3339","-1.5062305927276611","-1.5062305927276611","-1.5062305927276611"
+"437780480","3343","3343","3343","-1.1589205265045166","-1.1589205265045166","-1.1589205265045166"
+"438304768","3347","3347","3347","-0.8169158101081848","-0.8169158101081848","-0.8169158101081848"
+"438829056","3351","3351","3351","-0.9855811595916748","-0.9855811595916748","-0.9855811595916748"
+"439353344","3355","3355","3355","-1.1730682849884033","-1.1730682849884033","-1.1730682849884033"
+"439877632","3359","3359","3359","-1.1843719482421875","-1.1843719482421875","-1.1843719482421875"
+"440401920","3363","3363","3363","-0.7751294374465942","-0.7751294374465942","-0.7751294374465942"
+"440926208","3367","3367","3367","-1.0789707899093628","-1.0789707899093628","-1.0789707899093628"
+"441450496","3371","3371","3371","-1.7195905447006226","-1.7195905447006226","-1.7195905447006226"
+"441974784","3375","3375","3375","-0.7481943368911743","-0.7481943368911743","-0.7481943368911743"
+"442499072","3379","3379","3379","-1.1581553220748901","-1.1581553220748901","-1.1581553220748901"
+"443023360","3383","3383","3383","-1.126179814338684","-1.126179814338684","-1.126179814338684"
+"443547648","3387","3387","3387","-1.1627861261367798","-1.1627861261367798","-1.1627861261367798"
+"444071936","3391","3391","3391","-1.3298317193984985","-1.3298317193984985","-1.3298317193984985"
+"444596224","3395","3395","3395","-0.9457413554191589","-0.9457413554191589","-0.9457413554191589"
+"445120512","3399","3399","3399","-0.8885596990585327","-0.8885596990585327","-0.8885596990585327"
+"445644800","3403","3403","3403","-0.9867993593215942","-0.9867993593215942","-0.9867993593215942"
+"446169088","3407","3407","3407","-1.222602367401123","-1.222602367401123","-1.222602367401123"
+"446693376","3411","3411","3411","-1.1663795709609985","-1.1663795709609985","-1.1663795709609985"
+"447217664","3415","3415","3415","-1.3319300413131714","-1.3319300413131714","-1.3319300413131714"
+"447741952","3419","3419","3419","-0.8959222435951233","-0.8959222435951233","-0.8959222435951233"
+"448266240","3423","3423","3423","-1.3998708724975586","-1.3998708724975586","-1.3998708724975586"
+"448790528","3427","3427","3427","-1.0768914222717285","-1.0768914222717285","-1.0768914222717285"
+"449314816","3431","3431","3431","-1.0269423723220825","-1.0269423723220825","-1.0269423723220825"
+"449839104","3435","3435","3435","-1.1848738193511963","-1.1848738193511963","-1.1848738193511963"
+"450363392","3439","3439","3439","-1.0208745002746582","-1.0208745002746582","-1.0208745002746582"
+"450887680","3443","3443","3443","-0.8468765616416931","-0.8468765616416931","-0.8468765616416931"
+"451411968","3447","3447","3447","-0.9744521379470825","-0.9744521379470825","-0.9744521379470825"
+"451936256","3451","3451","3451","-1.5572000741958618","-1.5572000741958618","-1.5572000741958618"
+"452460544","3455","3455","3455","-1.2915581464767456","-1.2915581464767456","-1.2915581464767456"
+"452984832","3459","3459","3459","-0.7928277254104614","-0.7928277254104614","-0.7928277254104614"
+"453509120","3463","3463","3463","-1.293336272239685","-1.293336272239685","-1.293336272239685"
+"454033408","3467","3467","3467","-1.1860941648483276","-1.1860941648483276","-1.1860941648483276"
+"454557696","3471","3471","3471","-1.5252946615219116","-1.5252946615219116","-1.5252946615219116"
+"455081984","3475","3475","3475","-1.561705231666565","-1.561705231666565","-1.561705231666565"
+"455606272","3479","3479","3479","-0.9259875416755676","-0.9259875416755676","-0.9259875416755676"
+"456130560","3483","3483","3483","-1.6195549964904785","-1.6195549964904785","-1.6195549964904785"
+"456654848","3487","3487","3487","-1.3426324129104614","-1.3426324129104614","-1.3426324129104614"
+"457179136","3491","3491","3491","-1.2635765075683594","-1.2635765075683594","-1.2635765075683594"
+"457703424","3495","3495","3495","-1.2655667066574097","-1.2655667066574097","-1.2655667066574097"
+"458227712","3499","3499","3499","-0.9562367796897888","-0.9562367796897888","-0.9562367796897888"
+"458752000","3503","3503","3503","-1.4261046648025513","-1.4261046648025513","-1.4261046648025513"
+"459276288","3507","3507","3507","-1.3461575508117676","-1.3461575508117676","-1.3461575508117676"
+"459800576","3511","3511","3511","-1.2917753458023071","-1.2917753458023071","-1.2917753458023071"
+"460324864","3515","3515","3515","-1.3429737091064453","-1.3429737091064453","-1.3429737091064453"
+"460849152","3519","3519","3519","-1.3040683269500732","-1.3040683269500732","-1.3040683269500732"
+"461373440","3523","3523","3523","-0.9689855575561523","-0.9689855575561523","-0.9689855575561523"
+"461897728","3527","3527","3527","-1.362562894821167","-1.362562894821167","-1.362562894821167"
+"462422016","3531","3531","3531","-1.6459200382232666","-1.6459200382232666","-1.6459200382232666"
+"462946304","3535","3535","3535","-0.7507395148277283","-0.7507395148277283","-0.7507395148277283"
+"463470592","3539","3539","3539","-1.1854124069213867","-1.1854124069213867","-1.1854124069213867"
+"463994880","3543","3543","3543","-1.0097943544387817","-1.0097943544387817","-1.0097943544387817"
+"464519168","3547","3547","3547","-1.198149561882019","-1.198149561882019","-1.198149561882019"
+"465043456","3551","3551","3551","-0.9305382966995239","-0.9305382966995239","-0.9305382966995239"
+"465567744","3555","3555","3555","-1.461892008781433","-1.461892008781433","-1.461892008781433"
+"466092032","3559","3559","3559","-1.3175451755523682","-1.3175451755523682","-1.3175451755523682"
+"466616320","3563","3563","3563","-1.1407268047332764","-1.1407268047332764","-1.1407268047332764"
+"467140608","3567","3567","3567","-1.0939983129501343","-1.0939983129501343","-1.0939983129501343"
+"467664896","3571","3571","3571","-1.2648093700408936","-1.2648093700408936","-1.2648093700408936"
+"468189184","3575","3575","3575","-1.010498046875","-1.010498046875","-1.010498046875"
+"468713472","3579","3579","3579","-0.9749177098274231","-0.9749177098274231","-0.9749177098274231"
+"469237760","3583","3583","3583","-1.079253077507019","-1.079253077507019","-1.079253077507019"
+"469762048","3587","3587","3587","-1.059714674949646","-1.059714674949646","-1.059714674949646"
+"470286336","3591","3591","3591","-1.1340875625610352","-1.1340875625610352","-1.1340875625610352"
+"470810624","3595","3595","3595","-1.3569839000701904","-1.3569839000701904","-1.3569839000701904"
+"471334912","3599","3599","3599","-0.9280603528022766","-0.9280603528022766","-0.9280603528022766"
+"471859200","3603","3603","3603","-1.0091264247894287","-1.0091264247894287","-1.0091264247894287"
+"472383488","3607","3607","3607","-1.474683403968811","-1.474683403968811","-1.474683403968811"
+"472907776","3611","3611","3611","-1.4664373397827148","-1.4664373397827148","-1.4664373397827148"
+"473432064","3615","3615","3615","-1.19827401638031","-1.19827401638031","-1.19827401638031"
+"473956352","3619","3619","3619","-1.226203441619873","-1.226203441619873","-1.226203441619873"
+"474480640","3623","3623","3623","-0.925421416759491","-0.925421416759491","-0.925421416759491"
+"475004928","3627","3627","3627","-0.758013904094696","-0.758013904094696","-0.758013904094696"
+"475529216","3631","3631","3631","-1.059551477432251","-1.059551477432251","-1.059551477432251"
+"476053504","3635","3635","3635","-1.3147656917572021","-1.3147656917572021","-1.3147656917572021"
+"476577792","3639","3639","3639","-1.2032212018966675","-1.2032212018966675","-1.2032212018966675"
+"477102080","3643","3643","3643","-0.8866534233093262","-0.8866534233093262","-0.8866534233093262"
+"477626368","3647","3647","3647","-0.886469841003418","-0.886469841003418","-0.886469841003418"
+"478150656","3651","3651","3651","-0.9898519515991211","-0.9898519515991211","-0.9898519515991211"
+"478674944","3655","3655","3655","-1.1014634370803833","-1.1014634370803833","-1.1014634370803833"
+"479199232","3659","3659","3659","-0.6228141784667969","-0.6228141784667969","-0.6228141784667969"
+"479723520","3663","3663","3663","-1.3252114057540894","-1.3252114057540894","-1.3252114057540894"
+"480247808","3667","3667","3667","-1.1229885816574097","-1.1229885816574097","-1.1229885816574097"
+"480772096","3671","3671","3671","-1.2199848890304565","-1.2199848890304565","-1.2199848890304565"
+"481296384","3675","3675","3675","-1.3758108615875244","-1.3758108615875244","-1.3758108615875244"
+"481820672","3679","3679","3679","-1.24843430519104","-1.24843430519104","-1.24843430519104"
+"482344960","3683","3683","3683","-1.143788456916809","-1.143788456916809","-1.143788456916809"
+"482869248","3687","3687","3687","-1.2075055837631226","-1.2075055837631226","-1.2075055837631226"
+"483393536","3691","3691","3691","-0.9804378151893616","-0.9804378151893616","-0.9804378151893616"
+"483917824","3695","3695","3695","-1.184971809387207","-1.184971809387207","-1.184971809387207"
+"484442112","3699","3699","3699","-1.4067394733428955","-1.4067394733428955","-1.4067394733428955"
+"484966400","3703","3703","3703","-1.158395528793335","-1.158395528793335","-1.158395528793335"
+"485490688","3707","3707","3707","-1.086648941040039","-1.086648941040039","-1.086648941040039"
+"486014976","3711","3711","3711","-1.0515974760055542","-1.0515974760055542","-1.0515974760055542"
+"486539264","3715","3715","3715","-1.3611565828323364","-1.3611565828323364","-1.3611565828323364"
+"487063552","3719","3719","3719","-1.2778372764587402","-1.2778372764587402","-1.2778372764587402"
+"487587840","3723","3723","3723","-0.6531665921211243","-0.6531665921211243","-0.6531665921211243"
+"488112128","3727","3727","3727","-1.219880223274231","-1.219880223274231","-1.219880223274231"
+"488636416","3731","3731","3731","-1.4005868434906006","-1.4005868434906006","-1.4005868434906006"
+"489160704","3735","3735","3735","-0.9422643780708313","-0.9422643780708313","-0.9422643780708313"
+"489684992","3739","3739","3739","-1.0135754346847534","-1.0135754346847534","-1.0135754346847534"
+"490209280","3743","3743","3743","-1.038555383682251","-1.038555383682251","-1.038555383682251"
+"490733568","3747","3747","3747","-1.1385960578918457","-1.1385960578918457","-1.1385960578918457"
+"491257856","3751","3751","3751","-0.8686810731887817","-0.8686810731887817","-0.8686810731887817"
+"491782144","3755","3755","3755","-1.0578340291976929","-1.0578340291976929","-1.0578340291976929"
+"492306432","3759","3759","3759","-0.9259260892868042","-0.9259260892868042","-0.9259260892868042"
+"492830720","3763","3763","3763","-1.0377137660980225","-1.0377137660980225","-1.0377137660980225"
+"493355008","3767","3767","3767","-1.5398173332214355","-1.5398173332214355","-1.5398173332214355"
+"493879296","3771","3771","3771","-0.7739966511726379","-0.7739966511726379","-0.7739966511726379"
+"494403584","3775","3775","3775","-1.2997634410858154","-1.2997634410858154","-1.2997634410858154"
+"494927872","3779","3779","3779","-0.9167462587356567","-0.9167462587356567","-0.9167462587356567"
+"495452160","3783","3783","3783","-1.2713565826416016","-1.2713565826416016","-1.2713565826416016"
+"495976448","3787","3787","3787","-1.2195603847503662","-1.2195603847503662","-1.2195603847503662"
+"496500736","3791","3791","3791","-1.5167582035064697","-1.5167582035064697","-1.5167582035064697"
+"497025024","3795","3795","3795","-1.0365149974822998","-1.0365149974822998","-1.0365149974822998"
+"497549312","3799","3799","3799","-0.9294512867927551","-0.9294512867927551","-0.9294512867927551"
+"498073600","3803","3803","3803","-1.3526480197906494","-1.3526480197906494","-1.3526480197906494"
+"498597888","3807","3807","3807","-0.8890379667282104","-0.8890379667282104","-0.8890379667282104"
+"499122176","3811","3811","3811","-0.7001555562019348","-0.7001555562019348","-0.7001555562019348"
+"499646464","3815","3815","3815","-1.232736587524414","-1.232736587524414","-1.232736587524414"
+"500170752","3819","3819","3819","-0.7880033850669861","-0.7880033850669861","-0.7880033850669861"
+"500695040","3823","3823","3823","-1.108459711074829","-1.108459711074829","-1.108459711074829"
+"501219328","3827","3827","3827","-1.0066314935684204","-1.0066314935684204","-1.0066314935684204"
+"501743616","3831","3831","3831","-1.1669117212295532","-1.1669117212295532","-1.1669117212295532"
+"502267904","3835","3835","3835","-1.1448233127593994","-1.1448233127593994","-1.1448233127593994"
+"502792192","3839","3839","3839","-1.1655086278915405","-1.1655086278915405","-1.1655086278915405"
+"503316480","3843","3843","3843","-1.0271422863006592","-1.0271422863006592","-1.0271422863006592"
+"503840768","3847","3847","3847","-1.4288781881332397","-1.4288781881332397","-1.4288781881332397"
+"504365056","3851","3851","3851","-1.0183701515197754","-1.0183701515197754","-1.0183701515197754"
+"504889344","3855","3855","3855","-1.0698286294937134","-1.0698286294937134","-1.0698286294937134"
+"505413632","3859","3859","3859","-1.1115275621414185","-1.1115275621414185","-1.1115275621414185"
+"505937920","3863","3863","3863","-0.9633153080940247","-0.9633153080940247","-0.9633153080940247"
+"506462208","3867","3867","3867","-0.9376170635223389","-0.9376170635223389","-0.9376170635223389"
+"506986496","3871","3871","3871","-1.071171522140503","-1.071171522140503","-1.071171522140503"
+"507510784","3875","3875","3875","-1.0295028686523438","-1.0295028686523438","-1.0295028686523438"
+"508035072","3879","3879","3879","-0.9332554936408997","-0.9332554936408997","-0.9332554936408997"
+"508559360","3883","3883","3883","-1.0213271379470825","-1.0213271379470825","-1.0213271379470825"
+"509083648","3887","3887","3887","-0.8417913913726807","-0.8417913913726807","-0.8417913913726807"
+"509607936","3891","3891","3891","-0.9475524425506592","-0.9475524425506592","-0.9475524425506592"
+"510132224","3895","3895","3895","-0.5851805210113525","-0.5851805210113525","-0.5851805210113525"
+"510656512","3899","3899","3899","-1.4852943420410156","-1.4852943420410156","-1.4852943420410156"
+"511180800","3903","3903","3903","-1.1720657348632812","-1.1720657348632812","-1.1720657348632812"
+"511705088","3907","3907","3907","-1.3475533723831177","-1.3475533723831177","-1.3475533723831177"
+"512229376","3911","3911","3911","-0.5958589911460876","-0.5958589911460876","-0.5958589911460876"
+"512753664","3915","3915","3915","-0.8227289915084839","-0.8227289915084839","-0.8227289915084839"
+"513277952","3919","3919","3919","-1.0532991886138916","-1.0532991886138916","-1.0532991886138916"
+"513802240","3923","3923","3923","-0.9174957275390625","-0.9174957275390625","-0.9174957275390625"
+"514326528","3927","3927","3927","-0.9527783989906311","-0.9527783989906311","-0.9527783989906311"
+"514850816","3931","3931","3931","-1.3141647577285767","-1.3141647577285767","-1.3141647577285767"
+"515375104","3935","3935","3935","-1.093645453453064","-1.093645453453064","-1.093645453453064"
+"515899392","3939","3939","3939","-1.1726500988006592","-1.1726500988006592","-1.1726500988006592"
+"516423680","3943","3943","3943","-1.151789665222168","-1.151789665222168","-1.151789665222168"
+"516947968","3947","3947","3947","-0.9680102467536926","-0.9680102467536926","-0.9680102467536926"
+"517472256","3951","3951","3951","-1.1443580389022827","-1.1443580389022827","-1.1443580389022827"
+"517996544","3955","3955","3955","-1.0573538541793823","-1.0573538541793823","-1.0573538541793823"
+"518520832","3959","3959","3959","-1.3245998620986938","-1.3245998620986938","-1.3245998620986938"
+"519045120","3963","3963","3963","-1.1373748779296875","-1.1373748779296875","-1.1373748779296875"
+"519569408","3967","3967","3967","-0.6539762616157532","-0.6539762616157532","-0.6539762616157532"
+"520093696","3971","3971","3971","-1.144949197769165","-1.144949197769165","-1.144949197769165"
+"520617984","3975","3975","3975","-1.019122838973999","-1.019122838973999","-1.019122838973999"
+"521142272","3979","3979","3979","-1.4720382690429688","-1.4720382690429688","-1.4720382690429688"
+"521666560","3983","3983","3983","-0.4997776746749878","-0.4997776746749878","-0.4997776746749878"
+"522190848","3987","3987","3987","-0.7170843482017517","-0.7170843482017517","-0.7170843482017517"
+"522715136","3991","3991","3991","-1.138208270072937","-1.138208270072937","-1.138208270072937"
+"523239424","3995","3995","3995","-0.9373717904090881","-0.9373717904090881","-0.9373717904090881"
+"523763712","3999","3999","3999","-0.6533735394477844","-0.6533735394477844","-0.6533735394477844"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew_wp.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew_wp.csv
new file mode 100644
index 000000000..04b7112b4
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_dr_rew_wp.csv
@@ -0,0 +1,1001 @@
+"global_step","DRRandom_04-01-36-40 - _step","DRRandom_04-01-36-40 - _step__MIN","DRRandom_04-01-36-40 - _step__MAX","DRRandom_04-01-36-40 - rewards/waypoint/step","DRRandom_04-01-36-40 - rewards/waypoint/step__MIN","DRRandom_04-01-36-40 - rewards/waypoint/step__MAX"
+"192","3","3","3","0.000020074501662747934","0.000020074501662747934","0.000020074501662747934"
+"524288","7","7","7","0.04151899740099907","0.04151899740099907","0.04151899740099907"
+"1048576","11","11","11","0.017369695007801056","0.017369695007801056","0.017369695007801056"
+"1572864","15","15","15","0.05581508204340935","0.05581508204340935","0.05581508204340935"
+"2097152","19","19","19","0.030586840584874153","0.030586840584874153","0.030586840584874153"
+"2621440","23","23","23","0.020466629415750504","0.020466629415750504","0.020466629415750504"
+"3145728","27","27","27","0.028525250032544136","0.028525250032544136","0.028525250032544136"
+"3670016","31","31","31","0.11075156182050705","0.11075156182050705","0.11075156182050705"
+"4194304","35","35","35","0.06375456601381302","0.06375456601381302","0.06375456601381302"
+"4718592","39","39","39","0.056293785572052","0.056293785572052","0.056293785572052"
+"5242880","43","43","43","0.22916142642498016","0.22916142642498016","0.22916142642498016"
+"5767168","47","47","47","0.07403821498155594","0.07403821498155594","0.07403821498155594"
+"6291456","51","51","51","0.11978266388177872","0.11978266388177872","0.11978266388177872"
+"6815744","55","55","55","0.29194968938827515","0.29194968938827515","0.29194968938827515"
+"7340032","59","59","59","0.34601348638534546","0.34601348638534546","0.34601348638534546"
+"7864320","63","63","63","0.2053854912519455","0.2053854912519455","0.2053854912519455"
+"8388608","67","67","67","0.11213859170675278","0.11213859170675278","0.11213859170675278"
+"8912896","71","71","71","0.20787642896175385","0.20787642896175385","0.20787642896175385"
+"9437184","75","75","75","0.27746346592903137","0.27746346592903137","0.27746346592903137"
+"9961472","79","79","79","0.4028087556362152","0.4028087556362152","0.4028087556362152"
+"10485760","83","83","83","0.5009605884552002","0.5009605884552002","0.5009605884552002"
+"11010048","87","87","87","0.7111261487007141","0.7111261487007141","0.7111261487007141"
+"11534336","91","91","91","0.7728759050369263","0.7728759050369263","0.7728759050369263"
+"12058624","95","95","95","0.5505883693695068","0.5505883693695068","0.5505883693695068"
+"12582912","99","99","99","1.2002968788146973","1.2002968788146973","1.2002968788146973"
+"13107200","103","103","103","1.274168848991394","1.274168848991394","1.274168848991394"
+"13631488","107","107","107","0.8675371408462524","0.8675371408462524","0.8675371408462524"
+"14155776","111","111","111","1.1318488121032715","1.1318488121032715","1.1318488121032715"
+"14680064","115","115","115","1.658548355102539","1.658548355102539","1.658548355102539"
+"15204352","119","119","119","1.7196110486984253","1.7196110486984253","1.7196110486984253"
+"15728640","123","123","123","1.1203384399414062","1.1203384399414062","1.1203384399414062"
+"16252928","127","127","127","1.3332819938659668","1.3332819938659668","1.3332819938659668"
+"16777216","131","131","131","1.8125602006912231","1.8125602006912231","1.8125602006912231"
+"17301504","135","135","135","1.8539724349975586","1.8539724349975586","1.8539724349975586"
+"17825792","139","139","139","1.7135878801345825","1.7135878801345825","1.7135878801345825"
+"18350080","143","143","143","2.1732962131500244","2.1732962131500244","2.1732962131500244"
+"18874368","147","147","147","1.8202016353607178","1.8202016353607178","1.8202016353607178"
+"19398656","151","151","151","1.9218409061431885","1.9218409061431885","1.9218409061431885"
+"19922944","155","155","155","2.783173084259033","2.783173084259033","2.783173084259033"
+"20447232","159","159","159","2.4767215251922607","2.4767215251922607","2.4767215251922607"
+"20971520","163","163","163","2.832312822341919","2.832312822341919","2.832312822341919"
+"21495808","167","167","167","2.360682725906372","2.360682725906372","2.360682725906372"
+"22020096","171","171","171","2.515406370162964","2.515406370162964","2.515406370162964"
+"22544384","175","175","175","2.543410539627075","2.543410539627075","2.543410539627075"
+"23068672","179","179","179","3.039020299911499","3.039020299911499","3.039020299911499"
+"23592960","183","183","183","2.715291738510132","2.715291738510132","2.715291738510132"
+"24117248","187","187","187","3.1372838020324707","3.1372838020324707","3.1372838020324707"
+"24641536","191","191","191","2.8706936836242676","2.8706936836242676","2.8706936836242676"
+"25165824","195","195","195","3.0207629203796387","3.0207629203796387","3.0207629203796387"
+"25690112","199","199","199","3.1002185344696045","3.1002185344696045","3.1002185344696045"
+"26214400","203","203","203","3.4044814109802246","3.4044814109802246","3.4044814109802246"
+"26738688","207","207","207","3.188774347305298","3.188774347305298","3.188774347305298"
+"27262976","211","211","211","3.259302854537964","3.259302854537964","3.259302854537964"
+"27787264","215","215","215","3.5534183979034424","3.5534183979034424","3.5534183979034424"
+"28311552","219","219","219","4.092195510864258","4.092195510864258","4.092195510864258"
+"28835840","223","223","223","3.784086227416992","3.784086227416992","3.784086227416992"
+"29360128","227","227","227","3.743518590927124","3.743518590927124","3.743518590927124"
+"29884416","231","231","231","3.6304714679718018","3.6304714679718018","3.6304714679718018"
+"30408704","235","235","235","3.6174824237823486","3.6174824237823486","3.6174824237823486"
+"30932992","239","239","239","3.529888153076172","3.529888153076172","3.529888153076172"
+"31457280","243","243","243","3.888462543487549","3.888462543487549","3.888462543487549"
+"31981568","247","247","247","3.9070863723754883","3.9070863723754883","3.9070863723754883"
+"32505856","251","251","251","3.813788890838623","3.813788890838623","3.813788890838623"
+"33030144","255","255","255","3.758875846862793","3.758875846862793","3.758875846862793"
+"33554432","259","259","259","4.3201141357421875","4.3201141357421875","4.3201141357421875"
+"34078720","263","263","263","3.944310426712036","3.944310426712036","3.944310426712036"
+"34603008","267","267","267","3.859052896499634","3.859052896499634","3.859052896499634"
+"35127296","271","271","271","4.05268669128418","4.05268669128418","4.05268669128418"
+"35651584","275","275","275","4.086887836456299","4.086887836456299","4.086887836456299"
+"36175872","279","279","279","4.604081153869629","4.604081153869629","4.604081153869629"
+"36700160","283","283","283","4.606419086456299","4.606419086456299","4.606419086456299"
+"37224448","287","287","287","4.476820468902588","4.476820468902588","4.476820468902588"
+"37748736","291","291","291","4.413410663604736","4.413410663604736","4.413410663604736"
+"38273024","295","295","295","4.761545181274414","4.761545181274414","4.761545181274414"
+"38797312","299","299","299","4.366486072540283","4.366486072540283","4.366486072540283"
+"39321600","303","303","303","4.291324138641357","4.291324138641357","4.291324138641357"
+"39845888","307","307","307","4.394618988037109","4.394618988037109","4.394618988037109"
+"40370176","311","311","311","4.76474142074585","4.76474142074585","4.76474142074585"
+"40894464","315","315","315","4.549729347229004","4.549729347229004","4.549729347229004"
+"41418752","319","319","319","5.158535480499268","5.158535480499268","5.158535480499268"
+"41943040","323","323","323","4.71996545791626","4.71996545791626","4.71996545791626"
+"42467328","327","327","327","4.8355393409729","4.8355393409729","4.8355393409729"
+"42991616","331","331","331","4.82131290435791","4.82131290435791","4.82131290435791"
+"43515904","335","335","335","4.9088454246521","4.9088454246521","4.9088454246521"
+"44040192","339","339","339","5.134097099304199","5.134097099304199","5.134097099304199"
+"44564480","343","343","343","5.194981098175049","5.194981098175049","5.194981098175049"
+"45088768","347","347","347","5.368504047393799","5.368504047393799","5.368504047393799"
+"45613056","351","351","351","5.094362735748291","5.094362735748291","5.094362735748291"
+"46137344","355","355","355","4.886815071105957","4.886815071105957","4.886815071105957"
+"46661632","359","359","359","4.842927932739258","4.842927932739258","4.842927932739258"
+"47185920","363","363","363","4.667442321777344","4.667442321777344","4.667442321777344"
+"47710208","367","367","367","5.474367618560791","5.474367618560791","5.474367618560791"
+"48234496","371","371","371","5.596353054046631","5.596353054046631","5.596353054046631"
+"48758784","375","375","375","5.238584995269775","5.238584995269775","5.238584995269775"
+"49283072","379","379","379","5.295119285583496","5.295119285583496","5.295119285583496"
+"49807360","383","383","383","5.5794219970703125","5.5794219970703125","5.5794219970703125"
+"50331648","387","387","387","5.590973854064941","5.590973854064941","5.590973854064941"
+"50855936","391","391","391","5.206583023071289","5.206583023071289","5.206583023071289"
+"51380224","395","395","395","5.094851970672607","5.094851970672607","5.094851970672607"
+"51904512","399","399","399","5.666741847991943","5.666741847991943","5.666741847991943"
+"52428800","403","403","403","5.790902137756348","5.790902137756348","5.790902137756348"
+"52953088","407","407","407","5.612287998199463","5.612287998199463","5.612287998199463"
+"53477376","411","411","411","5.5368499755859375","5.5368499755859375","5.5368499755859375"
+"54001664","415","415","415","6.289643287658691","6.289643287658691","6.289643287658691"
+"54525952","419","419","419","5.850175857543945","5.850175857543945","5.850175857543945"
+"55050240","423","423","423","5.740437030792236","5.740437030792236","5.740437030792236"
+"55574528","427","427","427","5.81153678894043","5.81153678894043","5.81153678894043"
+"56098816","431","431","431","6.04470682144165","6.04470682144165","6.04470682144165"
+"56623104","435","435","435","6.191843509674072","6.191843509674072","6.191843509674072"
+"57147392","439","439","439","5.742146968841553","5.742146968841553","5.742146968841553"
+"57671680","443","443","443","5.770434379577637","5.770434379577637","5.770434379577637"
+"58195968","447","447","447","5.974922180175781","5.974922180175781","5.974922180175781"
+"58720256","451","451","451","5.73087739944458","5.73087739944458","5.73087739944458"
+"59244544","455","455","455","5.8258538246154785","5.8258538246154785","5.8258538246154785"
+"59768832","459","459","459","5.8942766189575195","5.8942766189575195","5.8942766189575195"
+"60293120","463","463","463","6.087010860443115","6.087010860443115","6.087010860443115"
+"60817408","467","467","467","5.92962121963501","5.92962121963501","5.92962121963501"
+"61341696","471","471","471","6.24416971206665","6.24416971206665","6.24416971206665"
+"61865984","475","475","475","6.1257853507995605","6.1257853507995605","6.1257853507995605"
+"62390272","479","479","479","6.173658847808838","6.173658847808838","6.173658847808838"
+"62914560","483","483","483","6.433759689331055","6.433759689331055","6.433759689331055"
+"63438848","487","487","487","6.478428363800049","6.478428363800049","6.478428363800049"
+"63963136","491","491","491","6.45998477935791","6.45998477935791","6.45998477935791"
+"64487424","495","495","495","6.26762056350708","6.26762056350708","6.26762056350708"
+"65011712","499","499","499","6.587706089019775","6.587706089019775","6.587706089019775"
+"65536000","503","503","503","6.391787528991699","6.391787528991699","6.391787528991699"
+"66060288","507","507","507","6.178279399871826","6.178279399871826","6.178279399871826"
+"66584576","511","511","511","6.535902500152588","6.535902500152588","6.535902500152588"
+"67108864","515","515","515","6.46156644821167","6.46156644821167","6.46156644821167"
+"67633152","519","519","519","5.928117752075195","5.928117752075195","5.928117752075195"
+"68157440","523","523","523","6.123897075653076","6.123897075653076","6.123897075653076"
+"68681728","527","527","527","6.292797088623047","6.292797088623047","6.292797088623047"
+"69206016","531","531","531","6.768470764160156","6.768470764160156","6.768470764160156"
+"69730304","535","535","535","6.492708683013916","6.492708683013916","6.492708683013916"
+"70254592","539","539","539","6.429422855377197","6.429422855377197","6.429422855377197"
+"70778880","543","543","543","6.165757179260254","6.165757179260254","6.165757179260254"
+"71303168","547","547","547","6.68631649017334","6.68631649017334","6.68631649017334"
+"71827456","551","551","551","6.765901565551758","6.765901565551758","6.765901565551758"
+"72351744","555","555","555","6.37204647064209","6.37204647064209","6.37204647064209"
+"72876032","559","559","559","6.325593948364258","6.325593948364258","6.325593948364258"
+"73400320","563","563","563","6.553654193878174","6.553654193878174","6.553654193878174"
+"73924608","567","567","567","6.66303825378418","6.66303825378418","6.66303825378418"
+"74448896","571","571","571","6.722338676452637","6.722338676452637","6.722338676452637"
+"74973184","575","575","575","6.189435958862305","6.189435958862305","6.189435958862305"
+"75497472","579","579","579","6.274866104125977","6.274866104125977","6.274866104125977"
+"76021760","583","583","583","6.697804927825928","6.697804927825928","6.697804927825928"
+"76546048","587","587","587","6.700467586517334","6.700467586517334","6.700467586517334"
+"77070336","591","591","591","6.4516167640686035","6.4516167640686035","6.4516167640686035"
+"77594624","595","595","595","6.700704097747803","6.700704097747803","6.700704097747803"
+"78118912","599","599","599","6.562259197235107","6.562259197235107","6.562259197235107"
+"78643200","603","603","603","6.746194362640381","6.746194362640381","6.746194362640381"
+"79167488","607","607","607","6.498319149017334","6.498319149017334","6.498319149017334"
+"79691776","611","611","611","6.63088321685791","6.63088321685791","6.63088321685791"
+"80216064","615","615","615","6.806621074676514","6.806621074676514","6.806621074676514"
+"80740352","619","619","619","6.742242813110352","6.742242813110352","6.742242813110352"
+"81264640","623","623","623","6.240842342376709","6.240842342376709","6.240842342376709"
+"81788928","627","627","627","6.807999610900879","6.807999610900879","6.807999610900879"
+"82313216","631","631","631","6.738201141357422","6.738201141357422","6.738201141357422"
+"82837504","635","635","635","6.774979591369629","6.774979591369629","6.774979591369629"
+"83361792","639","639","639","6.952574729919434","6.952574729919434","6.952574729919434"
+"83886080","643","643","643","6.985705375671387","6.985705375671387","6.985705375671387"
+"84410368","647","647","647","7.086968898773193","7.086968898773193","7.086968898773193"
+"84934656","651","651","651","6.4792938232421875","6.4792938232421875","6.4792938232421875"
+"85458944","655","655","655","7.151116371154785","7.151116371154785","7.151116371154785"
+"85983232","659","659","659","6.819220542907715","6.819220542907715","6.819220542907715"
+"86507520","663","663","663","7.228780269622803","7.228780269622803","7.228780269622803"
+"87031808","667","667","667","7.0691728591918945","7.0691728591918945","7.0691728591918945"
+"87556096","671","671","671","6.9077582359313965","6.9077582359313965","6.9077582359313965"
+"88080384","675","675","675","7.419715881347656","7.419715881347656","7.419715881347656"
+"88604672","679","679","679","7.130266189575195","7.130266189575195","7.130266189575195"
+"89128960","683","683","683","7.30126953125","7.30126953125","7.30126953125"
+"89653248","687","687","687","6.878610134124756","6.878610134124756","6.878610134124756"
+"90177536","691","691","691","7.1785430908203125","7.1785430908203125","7.1785430908203125"
+"90701824","695","695","695","6.850508689880371","6.850508689880371","6.850508689880371"
+"91226112","699","699","699","7.003842830657959","7.003842830657959","7.003842830657959"
+"91750400","703","703","703","7.233475685119629","7.233475685119629","7.233475685119629"
+"92274688","707","707","707","6.846996784210205","6.846996784210205","6.846996784210205"
+"92798976","711","711","711","6.924523830413818","6.924523830413818","6.924523830413818"
+"93323264","715","715","715","6.946443557739258","6.946443557739258","6.946443557739258"
+"93847552","719","719","719","7.14295768737793","7.14295768737793","7.14295768737793"
+"94371840","723","723","723","6.512504577636719","6.512504577636719","6.512504577636719"
+"94896128","727","727","727","7.004338264465332","7.004338264465332","7.004338264465332"
+"95420416","731","731","731","6.903214454650879","6.903214454650879","6.903214454650879"
+"95944704","735","735","735","7.041469573974609","7.041469573974609","7.041469573974609"
+"96468992","739","739","739","7.216410160064697","7.216410160064697","7.216410160064697"
+"96993280","743","743","743","6.630960941314697","6.630960941314697","6.630960941314697"
+"97517568","747","747","747","7.188987731933594","7.188987731933594","7.188987731933594"
+"98041856","751","751","751","6.736874103546143","6.736874103546143","6.736874103546143"
+"98566144","755","755","755","6.901115417480469","6.901115417480469","6.901115417480469"
+"99090432","759","759","759","6.75602388381958","6.75602388381958","6.75602388381958"
+"99614720","763","763","763","7.198111534118652","7.198111534118652","7.198111534118652"
+"100139008","767","767","767","7.523478984832764","7.523478984832764","7.523478984832764"
+"100663296","771","771","771","7.129534721374512","7.129534721374512","7.129534721374512"
+"101187584","775","775","775","7.111288070678711","7.111288070678711","7.111288070678711"
+"101711872","779","779","779","6.88132381439209","6.88132381439209","6.88132381439209"
+"102236160","783","783","783","7.262330532073975","7.262330532073975","7.262330532073975"
+"102760448","787","787","787","6.881655693054199","6.881655693054199","6.881655693054199"
+"103284736","791","791","791","7.353057861328125","7.353057861328125","7.353057861328125"
+"103809024","795","795","795","6.84916877746582","6.84916877746582","6.84916877746582"
+"104333312","799","799","799","7.093222618103027","7.093222618103027","7.093222618103027"
+"104857600","803","803","803","7.301916122436523","7.301916122436523","7.301916122436523"
+"105381888","807","807","807","7.092842102050781","7.092842102050781","7.092842102050781"
+"105906176","811","811","811","7.062440872192383","7.062440872192383","7.062440872192383"
+"106430464","815","815","815","7.167042255401611","7.167042255401611","7.167042255401611"
+"106954752","819","819","819","7.39916467666626","7.39916467666626","7.39916467666626"
+"107479040","823","823","823","7.27938985824585","7.27938985824585","7.27938985824585"
+"108003328","827","827","827","6.991603851318359","6.991603851318359","6.991603851318359"
+"108527616","831","831","831","7.206880569458008","7.206880569458008","7.206880569458008"
+"109051904","835","835","835","7.619587421417236","7.619587421417236","7.619587421417236"
+"109576192","839","839","839","7.242472171783447","7.242472171783447","7.242472171783447"
+"110100480","843","843","843","6.992647171020508","6.992647171020508","6.992647171020508"
+"110624768","847","847","847","7.162746429443359","7.162746429443359","7.162746429443359"
+"111149056","851","851","851","7.0666022300720215","7.0666022300720215","7.0666022300720215"
+"111673344","855","855","855","7.212789535522461","7.212789535522461","7.212789535522461"
+"112197632","859","859","859","6.812145233154297","6.812145233154297","6.812145233154297"
+"112721920","863","863","863","7.695314884185791","7.695314884185791","7.695314884185791"
+"113246208","867","867","867","7.1747660636901855","7.1747660636901855","7.1747660636901855"
+"113770496","871","871","871","7.334959030151367","7.334959030151367","7.334959030151367"
+"114294784","875","875","875","7.330878257751465","7.330878257751465","7.330878257751465"
+"114819072","879","879","879","7.39572286605835","7.39572286605835","7.39572286605835"
+"115343360","883","883","883","7.312912464141846","7.312912464141846","7.312912464141846"
+"115867648","887","887","887","7.106296062469482","7.106296062469482","7.106296062469482"
+"116391936","891","891","891","6.97661828994751","6.97661828994751","6.97661828994751"
+"116916224","895","895","895","7.264525413513184","7.264525413513184","7.264525413513184"
+"117440512","899","899","899","7.595158100128174","7.595158100128174","7.595158100128174"
+"117964800","903","903","903","7.20539665222168","7.20539665222168","7.20539665222168"
+"118489088","907","907","907","7.043442249298096","7.043442249298096","7.043442249298096"
+"119013376","911","911","911","7.306443691253662","7.306443691253662","7.306443691253662"
+"119537664","915","915","915","7.22641658782959","7.22641658782959","7.22641658782959"
+"120061952","919","919","919","7.739482402801514","7.739482402801514","7.739482402801514"
+"120586240","923","923","923","7.59670877456665","7.59670877456665","7.59670877456665"
+"121110528","927","927","927","7.28670597076416","7.28670597076416","7.28670597076416"
+"121634816","931","931","931","7.536615371704102","7.536615371704102","7.536615371704102"
+"122159104","935","935","935","7.3500657081604","7.3500657081604","7.3500657081604"
+"122683392","939","939","939","7.762429714202881","7.762429714202881","7.762429714202881"
+"123207680","943","943","943","7.346175193786621","7.346175193786621","7.346175193786621"
+"123731968","947","947","947","7.305591106414795","7.305591106414795","7.305591106414795"
+"124256256","951","951","951","7.313337326049805","7.313337326049805","7.313337326049805"
+"124780544","955","955","955","7.2899169921875","7.2899169921875","7.2899169921875"
+"125304832","959","959","959","7.166719436645508","7.166719436645508","7.166719436645508"
+"125829120","963","963","963","7.839059829711914","7.839059829711914","7.839059829711914"
+"126353408","967","967","967","7.5298285484313965","7.5298285484313965","7.5298285484313965"
+"126877696","971","971","971","7.62220573425293","7.62220573425293","7.62220573425293"
+"127401984","975","975","975","7.639407634735107","7.639407634735107","7.639407634735107"
+"127926272","979","979","979","7.36777925491333","7.36777925491333","7.36777925491333"
+"128450560","983","983","983","6.964623928070068","6.964623928070068","6.964623928070068"
+"128974848","987","987","987","7.913332939147949","7.913332939147949","7.913332939147949"
+"129499136","991","991","991","7.535989284515381","7.535989284515381","7.535989284515381"
+"130023424","995","995","995","7.576379299163818","7.576379299163818","7.576379299163818"
+"130547712","999","999","999","7.6734747886657715","7.6734747886657715","7.6734747886657715"
+"131072000","1003","1003","1003","7.469437599182129","7.469437599182129","7.469437599182129"
+"131596288","1007","1007","1007","7.081441402435303","7.081441402435303","7.081441402435303"
+"132120576","1011","1011","1011","7.249288558959961","7.249288558959961","7.249288558959961"
+"132644864","1015","1015","1015","7.48455286026001","7.48455286026001","7.48455286026001"
+"133169152","1019","1019","1019","7.430430889129639","7.430430889129639","7.430430889129639"
+"133693440","1023","1023","1023","7.086582660675049","7.086582660675049","7.086582660675049"
+"134217728","1027","1027","1027","7.360050678253174","7.360050678253174","7.360050678253174"
+"134742016","1031","1031","1031","7.550405502319336","7.550405502319336","7.550405502319336"
+"135266304","1035","1035","1035","6.995088577270508","6.995088577270508","6.995088577270508"
+"135790592","1039","1039","1039","7.732560634613037","7.732560634613037","7.732560634613037"
+"136314880","1043","1043","1043","7.704076290130615","7.704076290130615","7.704076290130615"
+"136839168","1047","1047","1047","7.6212286949157715","7.6212286949157715","7.6212286949157715"
+"137363456","1051","1051","1051","7.739424705505371","7.739424705505371","7.739424705505371"
+"137887744","1055","1055","1055","7.4434027671813965","7.4434027671813965","7.4434027671813965"
+"138412032","1059","1059","1059","8.022194862365723","8.022194862365723","8.022194862365723"
+"138936320","1063","1063","1063","7.558815002441406","7.558815002441406","7.558815002441406"
+"139460608","1067","1067","1067","8.035919189453125","8.035919189453125","8.035919189453125"
+"139984896","1071","1071","1071","7.000513076782227","7.000513076782227","7.000513076782227"
+"140509184","1075","1075","1075","7.412755489349365","7.412755489349365","7.412755489349365"
+"141033472","1079","1079","1079","7.21217155456543","7.21217155456543","7.21217155456543"
+"141557760","1083","1083","1083","7.495734691619873","7.495734691619873","7.495734691619873"
+"142082048","1087","1087","1087","7.764025688171387","7.764025688171387","7.764025688171387"
+"142606336","1091","1091","1091","7.325047492980957","7.325047492980957","7.325047492980957"
+"143130624","1095","1095","1095","7.5794267654418945","7.5794267654418945","7.5794267654418945"
+"143654912","1099","1099","1099","7.946115016937256","7.946115016937256","7.946115016937256"
+"144179200","1103","1103","1103","7.588508605957031","7.588508605957031","7.588508605957031"
+"144703488","1107","1107","1107","7.724510192871094","7.724510192871094","7.724510192871094"
+"145227776","1111","1111","1111","7.604356288909912","7.604356288909912","7.604356288909912"
+"145752064","1115","1115","1115","7.39158296585083","7.39158296585083","7.39158296585083"
+"146276352","1119","1119","1119","7.880880355834961","7.880880355834961","7.880880355834961"
+"146800640","1123","1123","1123","7.6746745109558105","7.6746745109558105","7.6746745109558105"
+"147324928","1127","1127","1127","7.788193702697754","7.788193702697754","7.788193702697754"
+"147849216","1131","1131","1131","7.677944183349609","7.677944183349609","7.677944183349609"
+"148373504","1135","1135","1135","7.50929069519043","7.50929069519043","7.50929069519043"
+"148897792","1139","1139","1139","7.938419818878174","7.938419818878174","7.938419818878174"
+"149422080","1143","1143","1143","8.022515296936035","8.022515296936035","8.022515296936035"
+"149946368","1147","1147","1147","8.046234130859375","8.046234130859375","8.046234130859375"
+"150470656","1151","1151","1151","7.980175495147705","7.980175495147705","7.980175495147705"
+"150994944","1155","1155","1155","8.147417068481445","8.147417068481445","8.147417068481445"
+"151519232","1159","1159","1159","7.655097484588623","7.655097484588623","7.655097484588623"
+"152043520","1163","1163","1163","8.248178482055664","8.248178482055664","8.248178482055664"
+"152567808","1167","1167","1167","7.6828484535217285","7.6828484535217285","7.6828484535217285"
+"153092096","1171","1171","1171","7.76570987701416","7.76570987701416","7.76570987701416"
+"153616384","1175","1175","1175","7.525728702545166","7.525728702545166","7.525728702545166"
+"154140672","1179","1179","1179","7.932643890380859","7.932643890380859","7.932643890380859"
+"154664960","1183","1183","1183","7.911144733428955","7.911144733428955","7.911144733428955"
+"155189248","1187","1187","1187","7.754637241363525","7.754637241363525","7.754637241363525"
+"155713536","1191","1191","1191","7.574274063110352","7.574274063110352","7.574274063110352"
+"156237824","1195","1195","1195","7.779487609863281","7.779487609863281","7.779487609863281"
+"156762112","1199","1199","1199","8.112700462341309","8.112700462341309","8.112700462341309"
+"157286400","1203","1203","1203","7.838272571563721","7.838272571563721","7.838272571563721"
+"157810688","1207","1207","1207","7.802767276763916","7.802767276763916","7.802767276763916"
+"158334976","1211","1211","1211","7.6661858558654785","7.6661858558654785","7.6661858558654785"
+"158859264","1215","1215","1215","7.827589511871338","7.827589511871338","7.827589511871338"
+"159383552","1219","1219","1219","7.947350978851318","7.947350978851318","7.947350978851318"
+"159907840","1223","1223","1223","8.124067306518555","8.124067306518555","8.124067306518555"
+"160432128","1227","1227","1227","7.785157680511475","7.785157680511475","7.785157680511475"
+"160956416","1231","1231","1231","8.209303855895996","8.209303855895996","8.209303855895996"
+"161480704","1235","1235","1235","7.830549716949463","7.830549716949463","7.830549716949463"
+"162004992","1239","1239","1239","8.542902946472168","8.542902946472168","8.542902946472168"
+"162529280","1243","1243","1243","7.9089860916137695","7.9089860916137695","7.9089860916137695"
+"163053568","1247","1247","1247","7.939515590667725","7.939515590667725","7.939515590667725"
+"163577856","1251","1251","1251","8.161150932312012","8.161150932312012","8.161150932312012"
+"164102144","1255","1255","1255","8.026602745056152","8.026602745056152","8.026602745056152"
+"164626432","1259","1259","1259","8.134658813476562","8.134658813476562","8.134658813476562"
+"165150720","1263","1263","1263","8.056543350219727","8.056543350219727","8.056543350219727"
+"165675008","1267","1267","1267","8.032219886779785","8.032219886779785","8.032219886779785"
+"166199296","1271","1271","1271","7.928641319274902","7.928641319274902","7.928641319274902"
+"166723584","1275","1275","1275","8.032750129699707","8.032750129699707","8.032750129699707"
+"167247872","1279","1279","1279","8.116740226745605","8.116740226745605","8.116740226745605"
+"167772160","1283","1283","1283","8.385311126708984","8.385311126708984","8.385311126708984"
+"168296448","1287","1287","1287","8.009857177734375","8.009857177734375","8.009857177734375"
+"168820736","1291","1291","1291","8.440157890319824","8.440157890319824","8.440157890319824"
+"169345024","1295","1295","1295","7.35880184173584","7.35880184173584","7.35880184173584"
+"169869312","1299","1299","1299","8.245138168334961","8.245138168334961","8.245138168334961"
+"170393600","1303","1303","1303","8.08566951751709","8.08566951751709","8.08566951751709"
+"170917888","1307","1307","1307","7.938951015472412","7.938951015472412","7.938951015472412"
+"171442176","1311","1311","1311","8.19949722290039","8.19949722290039","8.19949722290039"
+"171966464","1315","1315","1315","8.252984046936035","8.252984046936035","8.252984046936035"
+"172490752","1319","1319","1319","8.381861686706543","8.381861686706543","8.381861686706543"
+"173015040","1323","1323","1323","8.225072860717773","8.225072860717773","8.225072860717773"
+"173539328","1327","1327","1327","8.08989429473877","8.08989429473877","8.08989429473877"
+"174063616","1331","1331","1331","8.02407169342041","8.02407169342041","8.02407169342041"
+"174587904","1335","1335","1335","8.02691650390625","8.02691650390625","8.02691650390625"
+"175112192","1339","1339","1339","8.37936782836914","8.37936782836914","8.37936782836914"
+"175636480","1343","1343","1343","8.215612411499023","8.215612411499023","8.215612411499023"
+"176160768","1347","1347","1347","8.289047241210938","8.289047241210938","8.289047241210938"
+"176685056","1351","1351","1351","8.291799545288086","8.291799545288086","8.291799545288086"
+"177209344","1355","1355","1355","8.093093872070312","8.093093872070312","8.093093872070312"
+"177733632","1359","1359","1359","8.042535781860352","8.042535781860352","8.042535781860352"
+"178257920","1363","1363","1363","8.466920852661133","8.466920852661133","8.466920852661133"
+"178782208","1367","1367","1367","8.526824951171875","8.526824951171875","8.526824951171875"
+"179306496","1371","1371","1371","8.344218254089355","8.344218254089355","8.344218254089355"
+"179830784","1375","1375","1375","8.316176414489746","8.316176414489746","8.316176414489746"
+"180355072","1379","1379","1379","8.090601921081543","8.090601921081543","8.090601921081543"
+"180879360","1383","1383","1383","8.195404052734375","8.195404052734375","8.195404052734375"
+"181403648","1387","1387","1387","8.343189239501953","8.343189239501953","8.343189239501953"
+"181927936","1391","1391","1391","8.326967239379883","8.326967239379883","8.326967239379883"
+"182452224","1395","1395","1395","8.003341674804688","8.003341674804688","8.003341674804688"
+"182976512","1399","1399","1399","8.03046989440918","8.03046989440918","8.03046989440918"
+"183500800","1403","1403","1403","8.644977569580078","8.644977569580078","8.644977569580078"
+"184025088","1407","1407","1407","8.47867202758789","8.47867202758789","8.47867202758789"
+"184549376","1411","1411","1411","8.49068546295166","8.49068546295166","8.49068546295166"
+"185073664","1415","1415","1415","8.331771850585938","8.331771850585938","8.331771850585938"
+"185597952","1419","1419","1419","8.386968612670898","8.386968612670898","8.386968612670898"
+"186122240","1423","1423","1423","8.105223655700684","8.105223655700684","8.105223655700684"
+"186646528","1427","1427","1427","8.137970924377441","8.137970924377441","8.137970924377441"
+"187170816","1431","1431","1431","8.637053489685059","8.637053489685059","8.637053489685059"
+"187695104","1435","1435","1435","8.30716323852539","8.30716323852539","8.30716323852539"
+"188219392","1439","1439","1439","8.47636604309082","8.47636604309082","8.47636604309082"
+"188743680","1443","1443","1443","8.458828926086426","8.458828926086426","8.458828926086426"
+"189267968","1447","1447","1447","8.72260856628418","8.72260856628418","8.72260856628418"
+"189792256","1451","1451","1451","8.57436466217041","8.57436466217041","8.57436466217041"
+"190316544","1455","1455","1455","8.383190155029297","8.383190155029297","8.383190155029297"
+"190840832","1459","1459","1459","8.351125717163086","8.351125717163086","8.351125717163086"
+"191365120","1463","1463","1463","8.315446853637695","8.315446853637695","8.315446853637695"
+"191889408","1467","1467","1467","8.464568138122559","8.464568138122559","8.464568138122559"
+"192413696","1471","1471","1471","8.147205352783203","8.147205352783203","8.147205352783203"
+"192937984","1475","1475","1475","8.370162963867188","8.370162963867188","8.370162963867188"
+"193462272","1479","1479","1479","8.484475135803223","8.484475135803223","8.484475135803223"
+"193986560","1483","1483","1483","8.30548095703125","8.30548095703125","8.30548095703125"
+"194510848","1487","1487","1487","8.527796745300293","8.527796745300293","8.527796745300293"
+"195035136","1491","1491","1491","8.317770957946777","8.317770957946777","8.317770957946777"
+"195559424","1495","1495","1495","8.444404602050781","8.444404602050781","8.444404602050781"
+"196083712","1499","1499","1499","8.697830200195312","8.697830200195312","8.697830200195312"
+"196608000","1503","1503","1503","8.006590843200684","8.006590843200684","8.006590843200684"
+"197132288","1507","1507","1507","8.770896911621094","8.770896911621094","8.770896911621094"
+"197656576","1511","1511","1511","8.44399356842041","8.44399356842041","8.44399356842041"
+"198180864","1515","1515","1515","8.264984130859375","8.264984130859375","8.264984130859375"
+"198705152","1519","1519","1519","8.625385284423828","8.625385284423828","8.625385284423828"
+"199229440","1523","1523","1523","8.439629554748535","8.439629554748535","8.439629554748535"
+"199753728","1527","1527","1527","8.229920387268066","8.229920387268066","8.229920387268066"
+"200278016","1531","1531","1531","8.143092155456543","8.143092155456543","8.143092155456543"
+"200802304","1535","1535","1535","8.527430534362793","8.527430534362793","8.527430534362793"
+"201326592","1539","1539","1539","8.586444854736328","8.586444854736328","8.586444854736328"
+"201850880","1543","1543","1543","8.21415901184082","8.21415901184082","8.21415901184082"
+"202375168","1547","1547","1547","8.414718627929688","8.414718627929688","8.414718627929688"
+"202899456","1551","1551","1551","8.510476112365723","8.510476112365723","8.510476112365723"
+"203423744","1555","1555","1555","8.415166854858398","8.415166854858398","8.415166854858398"
+"203948032","1559","1559","1559","8.51258373260498","8.51258373260498","8.51258373260498"
+"204472320","1563","1563","1563","8.6683931350708","8.6683931350708","8.6683931350708"
+"204996608","1567","1567","1567","8.446453094482422","8.446453094482422","8.446453094482422"
+"205520896","1571","1571","1571","8.455885887145996","8.455885887145996","8.455885887145996"
+"206045184","1575","1575","1575","7.8939127922058105","7.8939127922058105","7.8939127922058105"
+"206569472","1579","1579","1579","8.585334777832031","8.585334777832031","8.585334777832031"
+"207093760","1583","1583","1583","8.421920776367188","8.421920776367188","8.421920776367188"
+"207618048","1587","1587","1587","8.395537376403809","8.395537376403809","8.395537376403809"
+"208142336","1591","1591","1591","8.268210411071777","8.268210411071777","8.268210411071777"
+"208666624","1595","1595","1595","8.77332592010498","8.77332592010498","8.77332592010498"
+"209190912","1599","1599","1599","8.6847562789917","8.6847562789917","8.6847562789917"
+"209715200","1603","1603","1603","8.423195838928223","8.423195838928223","8.423195838928223"
+"210239488","1607","1607","1607","8.674223899841309","8.674223899841309","8.674223899841309"
+"210763776","1611","1611","1611","8.237383842468262","8.237383842468262","8.237383842468262"
+"211288064","1615","1615","1615","8.491533279418945","8.491533279418945","8.491533279418945"
+"211812352","1619","1619","1619","8.19082260131836","8.19082260131836","8.19082260131836"
+"212336640","1623","1623","1623","8.654240608215332","8.654240608215332","8.654240608215332"
+"212860928","1627","1627","1627","8.60938549041748","8.60938549041748","8.60938549041748"
+"213385216","1631","1631","1631","8.435194969177246","8.435194969177246","8.435194969177246"
+"213909504","1635","1635","1635","8.068465232849121","8.068465232849121","8.068465232849121"
+"214433792","1639","1639","1639","8.537322998046875","8.537322998046875","8.537322998046875"
+"214958080","1643","1643","1643","8.365373611450195","8.365373611450195","8.365373611450195"
+"215482368","1647","1647","1647","8.364350318908691","8.364350318908691","8.364350318908691"
+"216006656","1651","1651","1651","8.510568618774414","8.510568618774414","8.510568618774414"
+"216530944","1655","1655","1655","8.683573722839355","8.683573722839355","8.683573722839355"
+"217055232","1659","1659","1659","8.670475959777832","8.670475959777832","8.670475959777832"
+"217579520","1663","1663","1663","8.273421287536621","8.273421287536621","8.273421287536621"
+"218103808","1667","1667","1667","8.74933910369873","8.74933910369873","8.74933910369873"
+"218628096","1671","1671","1671","8.734169960021973","8.734169960021973","8.734169960021973"
+"219152384","1675","1675","1675","8.309171676635742","8.309171676635742","8.309171676635742"
+"219676672","1679","1679","1679","8.798022270202637","8.798022270202637","8.798022270202637"
+"220200960","1683","1683","1683","8.154993057250977","8.154993057250977","8.154993057250977"
+"220725248","1687","1687","1687","8.539740562438965","8.539740562438965","8.539740562438965"
+"221249536","1691","1691","1691","8.283404350280762","8.283404350280762","8.283404350280762"
+"221773824","1695","1695","1695","8.540487289428711","8.540487289428711","8.540487289428711"
+"222298112","1699","1699","1699","8.592506408691406","8.592506408691406","8.592506408691406"
+"222822400","1703","1703","1703","8.59492015838623","8.59492015838623","8.59492015838623"
+"223346688","1707","1707","1707","8.464484214782715","8.464484214782715","8.464484214782715"
+"223870976","1711","1711","1711","8.356132507324219","8.356132507324219","8.356132507324219"
+"224395264","1715","1715","1715","8.762986183166504","8.762986183166504","8.762986183166504"
+"224919552","1719","1719","1719","8.571590423583984","8.571590423583984","8.571590423583984"
+"225443840","1723","1723","1723","8.812585830688477","8.812585830688477","8.812585830688477"
+"225968128","1727","1727","1727","8.525285720825195","8.525285720825195","8.525285720825195"
+"226492416","1731","1731","1731","8.496599197387695","8.496599197387695","8.496599197387695"
+"227016704","1735","1735","1735","8.959718704223633","8.959718704223633","8.959718704223633"
+"227540992","1739","1739","1739","8.93731689453125","8.93731689453125","8.93731689453125"
+"228065280","1743","1743","1743","8.408684730529785","8.408684730529785","8.408684730529785"
+"228589568","1747","1747","1747","8.875415802001953","8.875415802001953","8.875415802001953"
+"229113856","1751","1751","1751","8.34462833404541","8.34462833404541","8.34462833404541"
+"229638144","1755","1755","1755","8.624590873718262","8.624590873718262","8.624590873718262"
+"230162432","1759","1759","1759","8.414774894714355","8.414774894714355","8.414774894714355"
+"230686720","1763","1763","1763","8.920612335205078","8.920612335205078","8.920612335205078"
+"231211008","1767","1767","1767","8.619665145874023","8.619665145874023","8.619665145874023"
+"231735296","1771","1771","1771","8.736774444580078","8.736774444580078","8.736774444580078"
+"232259584","1775","1775","1775","8.391738891601562","8.391738891601562","8.391738891601562"
+"232783872","1779","1779","1779","8.895082473754883","8.895082473754883","8.895082473754883"
+"233308160","1783","1783","1783","8.647162437438965","8.647162437438965","8.647162437438965"
+"233832448","1787","1787","1787","8.402253150939941","8.402253150939941","8.402253150939941"
+"234356736","1791","1791","1791","8.321064949035645","8.321064949035645","8.321064949035645"
+"234881024","1795","1795","1795","8.500831604003906","8.500831604003906","8.500831604003906"
+"235405312","1799","1799","1799","8.560553550720215","8.560553550720215","8.560553550720215"
+"235929600","1803","1803","1803","8.932573318481445","8.932573318481445","8.932573318481445"
+"236453888","1807","1807","1807","8.659475326538086","8.659475326538086","8.659475326538086"
+"236978176","1811","1811","1811","8.83029556274414","8.83029556274414","8.83029556274414"
+"237502464","1815","1815","1815","8.540802955627441","8.540802955627441","8.540802955627441"
+"238026752","1819","1819","1819","9.002336502075195","9.002336502075195","9.002336502075195"
+"238551040","1823","1823","1823","8.851418495178223","8.851418495178223","8.851418495178223"
+"239075328","1827","1827","1827","8.555367469787598","8.555367469787598","8.555367469787598"
+"239599616","1831","1831","1831","8.534913063049316","8.534913063049316","8.534913063049316"
+"240123904","1835","1835","1835","8.798429489135742","8.798429489135742","8.798429489135742"
+"240648192","1839","1839","1839","9.052865028381348","9.052865028381348","9.052865028381348"
+"241172480","1843","1843","1843","8.778095245361328","8.778095245361328","8.778095245361328"
+"241696768","1847","1847","1847","8.989165306091309","8.989165306091309","8.989165306091309"
+"242221056","1851","1851","1851","8.538098335266113","8.538098335266113","8.538098335266113"
+"242745344","1855","1855","1855","8.64529800415039","8.64529800415039","8.64529800415039"
+"243269632","1859","1859","1859","8.934669494628906","8.934669494628906","8.934669494628906"
+"243793920","1863","1863","1863","8.962170600891113","8.962170600891113","8.962170600891113"
+"244318208","1867","1867","1867","8.992483139038086","8.992483139038086","8.992483139038086"
+"244842496","1871","1871","1871","8.707270622253418","8.707270622253418","8.707270622253418"
+"245366784","1875","1875","1875","8.887429237365723","8.887429237365723","8.887429237365723"
+"245891072","1879","1879","1879","8.997856140136719","8.997856140136719","8.997856140136719"
+"246415360","1883","1883","1883","9.070857048034668","9.070857048034668","9.070857048034668"
+"246939648","1887","1887","1887","8.845149993896484","8.845149993896484","8.845149993896484"
+"247463936","1891","1891","1891","8.85562801361084","8.85562801361084","8.85562801361084"
+"247988224","1895","1895","1895","8.807220458984375","8.807220458984375","8.807220458984375"
+"248512512","1899","1899","1899","8.897327423095703","8.897327423095703","8.897327423095703"
+"249036800","1903","1903","1903","8.719823837280273","8.719823837280273","8.719823837280273"
+"249561088","1907","1907","1907","8.64521312713623","8.64521312713623","8.64521312713623"
+"250085376","1911","1911","1911","9.243528366088867","9.243528366088867","9.243528366088867"
+"250609664","1915","1915","1915","8.932913780212402","8.932913780212402","8.932913780212402"
+"251133952","1919","1919","1919","8.614039421081543","8.614039421081543","8.614039421081543"
+"251658240","1923","1923","1923","8.834698677062988","8.834698677062988","8.834698677062988"
+"252182528","1927","1927","1927","8.721967697143555","8.721967697143555","8.721967697143555"
+"252706816","1931","1931","1931","8.714397430419922","8.714397430419922","8.714397430419922"
+"253231104","1935","1935","1935","8.757590293884277","8.757590293884277","8.757590293884277"
+"253755392","1939","1939","1939","8.667490005493164","8.667490005493164","8.667490005493164"
+"254279680","1943","1943","1943","8.675578117370605","8.675578117370605","8.675578117370605"
+"254803968","1947","1947","1947","8.98307991027832","8.98307991027832","8.98307991027832"
+"255328256","1951","1951","1951","8.6895751953125","8.6895751953125","8.6895751953125"
+"255852544","1955","1955","1955","8.644065856933594","8.644065856933594","8.644065856933594"
+"256376832","1959","1959","1959","8.958749771118164","8.958749771118164","8.958749771118164"
+"256901120","1963","1963","1963","8.75345516204834","8.75345516204834","8.75345516204834"
+"257425408","1967","1967","1967","9.14931869506836","9.14931869506836","9.14931869506836"
+"257949696","1971","1971","1971","9.168798446655273","9.168798446655273","9.168798446655273"
+"258473984","1975","1975","1975","8.72822380065918","8.72822380065918","8.72822380065918"
+"258998272","1979","1979","1979","8.829817771911621","8.829817771911621","8.829817771911621"
+"259522560","1983","1983","1983","8.387601852416992","8.387601852416992","8.387601852416992"
+"260046848","1987","1987","1987","9.160616874694824","9.160616874694824","9.160616874694824"
+"260571136","1991","1991","1991","8.806652069091797","8.806652069091797","8.806652069091797"
+"261095424","1995","1995","1995","9.103474617004395","9.103474617004395","9.103474617004395"
+"261619712","1999","1999","1999","8.748946189880371","8.748946189880371","8.748946189880371"
+"262144000","2003","2003","2003","8.851431846618652","8.851431846618652","8.851431846618652"
+"262668288","2007","2007","2007","9.02574634552002","9.02574634552002","9.02574634552002"
+"263192576","2011","2011","2011","9.010848999023438","9.010848999023438","9.010848999023438"
+"263716864","2015","2015","2015","9.138853073120117","9.138853073120117","9.138853073120117"
+"264241152","2019","2019","2019","8.730827331542969","8.730827331542969","8.730827331542969"
+"264765440","2023","2023","2023","8.932936668395996","8.932936668395996","8.932936668395996"
+"265289728","2027","2027","2027","8.724555015563965","8.724555015563965","8.724555015563965"
+"265814016","2031","2031","2031","8.78262710571289","8.78262710571289","8.78262710571289"
+"266338304","2035","2035","2035","9.00738525390625","9.00738525390625","9.00738525390625"
+"266862592","2039","2039","2039","8.90565013885498","8.90565013885498","8.90565013885498"
+"267386880","2043","2043","2043","8.773096084594727","8.773096084594727","8.773096084594727"
+"267911168","2047","2047","2047","8.547727584838867","8.547727584838867","8.547727584838867"
+"268435456","2051","2051","2051","8.401101112365723","8.401101112365723","8.401101112365723"
+"268959744","2055","2055","2055","8.727683067321777","8.727683067321777","8.727683067321777"
+"269484032","2059","2059","2059","8.64171028137207","8.64171028137207","8.64171028137207"
+"270008320","2063","2063","2063","8.679746627807617","8.679746627807617","8.679746627807617"
+"270532608","2067","2067","2067","8.875750541687012","8.875750541687012","8.875750541687012"
+"271056896","2071","2071","2071","8.949234008789062","8.949234008789062","8.949234008789062"
+"271581184","2075","2075","2075","8.63276195526123","8.63276195526123","8.63276195526123"
+"272105472","2079","2079","2079","8.838725090026855","8.838725090026855","8.838725090026855"
+"272629760","2083","2083","2083","9.164312362670898","9.164312362670898","9.164312362670898"
+"273154048","2087","2087","2087","8.78933048248291","8.78933048248291","8.78933048248291"
+"273678336","2091","2091","2091","8.605473518371582","8.605473518371582","8.605473518371582"
+"274202624","2095","2095","2095","8.419598579406738","8.419598579406738","8.419598579406738"
+"274726912","2099","2099","2099","8.860044479370117","8.860044479370117","8.860044479370117"
+"275251200","2103","2103","2103","8.97768497467041","8.97768497467041","8.97768497467041"
+"275775488","2107","2107","2107","8.99283218383789","8.99283218383789","8.99283218383789"
+"276299776","2111","2111","2111","8.983771324157715","8.983771324157715","8.983771324157715"
+"276824064","2115","2115","2115","8.748557090759277","8.748557090759277","8.748557090759277"
+"277348352","2119","2119","2119","8.790337562561035","8.790337562561035","8.790337562561035"
+"277872640","2123","2123","2123","8.991979598999023","8.991979598999023","8.991979598999023"
+"278396928","2127","2127","2127","8.405508995056152","8.405508995056152","8.405508995056152"
+"278921216","2131","2131","2131","9.022316932678223","9.022316932678223","9.022316932678223"
+"279445504","2135","2135","2135","8.751274108886719","8.751274108886719","8.751274108886719"
+"279969792","2139","2139","2139","8.80833911895752","8.80833911895752","8.80833911895752"
+"280494080","2143","2143","2143","8.71396255493164","8.71396255493164","8.71396255493164"
+"281018368","2147","2147","2147","8.965469360351562","8.965469360351562","8.965469360351562"
+"281542656","2151","2151","2151","9.024931907653809","9.024931907653809","9.024931907653809"
+"282066944","2155","2155","2155","9.044703483581543","9.044703483581543","9.044703483581543"
+"282591232","2159","2159","2159","8.944025039672852","8.944025039672852","8.944025039672852"
+"283115520","2163","2163","2163","9.049551010131836","9.049551010131836","9.049551010131836"
+"283639808","2167","2167","2167","9.04974365234375","9.04974365234375","9.04974365234375"
+"284164096","2171","2171","2171","9.04881477355957","9.04881477355957","9.04881477355957"
+"284688384","2175","2175","2175","8.892144203186035","8.892144203186035","8.892144203186035"
+"285212672","2179","2179","2179","9.038848876953125","9.038848876953125","9.038848876953125"
+"285736960","2183","2183","2183","8.750244140625","8.750244140625","8.750244140625"
+"286261248","2187","2187","2187","9.076427459716797","9.076427459716797","9.076427459716797"
+"286785536","2191","2191","2191","9.229509353637695","9.229509353637695","9.229509353637695"
+"287309824","2195","2195","2195","8.96351432800293","8.96351432800293","8.96351432800293"
+"287834112","2199","2199","2199","8.40308666229248","8.40308666229248","8.40308666229248"
+"288358400","2203","2203","2203","8.514018058776855","8.514018058776855","8.514018058776855"
+"288882688","2207","2207","2207","9.138160705566406","9.138160705566406","9.138160705566406"
+"289406976","2211","2211","2211","8.662093162536621","8.662093162536621","8.662093162536621"
+"289931264","2215","2215","2215","8.899847984313965","8.899847984313965","8.899847984313965"
+"290455552","2219","2219","2219","8.839113235473633","8.839113235473633","8.839113235473633"
+"290979840","2223","2223","2223","8.79090690612793","8.79090690612793","8.79090690612793"
+"291504128","2227","2227","2227","8.779346466064453","8.779346466064453","8.779346466064453"
+"292028416","2231","2231","2231","8.712230682373047","8.712230682373047","8.712230682373047"
+"292552704","2235","2235","2235","9.164563179016113","9.164563179016113","9.164563179016113"
+"293076992","2239","2239","2239","8.807472229003906","8.807472229003906","8.807472229003906"
+"293601280","2243","2243","2243","9.06608772277832","9.06608772277832","9.06608772277832"
+"294125568","2247","2247","2247","8.960268020629883","8.960268020629883","8.960268020629883"
+"294649856","2251","2251","2251","9.149697303771973","9.149697303771973","9.149697303771973"
+"295174144","2255","2255","2255","9.130081176757812","9.130081176757812","9.130081176757812"
+"295698432","2259","2259","2259","8.844292640686035","8.844292640686035","8.844292640686035"
+"296222720","2263","2263","2263","8.823970794677734","8.823970794677734","8.823970794677734"
+"296747008","2267","2267","2267","9.069037437438965","9.069037437438965","9.069037437438965"
+"297271296","2271","2271","2271","8.936476707458496","8.936476707458496","8.936476707458496"
+"297795584","2275","2275","2275","9.049830436706543","9.049830436706543","9.049830436706543"
+"298319872","2279","2279","2279","8.808760643005371","8.808760643005371","8.808760643005371"
+"298844160","2283","2283","2283","9.023564338684082","9.023564338684082","9.023564338684082"
+"299368448","2287","2287","2287","8.821764945983887","8.821764945983887","8.821764945983887"
+"299892736","2291","2291","2291","8.859896659851074","8.859896659851074","8.859896659851074"
+"300417024","2295","2295","2295","9.090896606445312","9.090896606445312","9.090896606445312"
+"300941312","2299","2299","2299","9.219904899597168","9.219904899597168","9.219904899597168"
+"301465600","2303","2303","2303","8.878231048583984","8.878231048583984","8.878231048583984"
+"301989888","2307","2307","2307","8.826926231384277","8.826926231384277","8.826926231384277"
+"302514176","2311","2311","2311","9.168572425842285","9.168572425842285","9.168572425842285"
+"303038464","2315","2315","2315","9.179803848266602","9.179803848266602","9.179803848266602"
+"303562752","2319","2319","2319","8.92923641204834","8.92923641204834","8.92923641204834"
+"304087040","2323","2323","2323","9.212246894836426","9.212246894836426","9.212246894836426"
+"304611328","2327","2327","2327","8.989822387695312","8.989822387695312","8.989822387695312"
+"305135616","2331","2331","2331","9.104360580444336","9.104360580444336","9.104360580444336"
+"305659904","2335","2335","2335","9.198083877563477","9.198083877563477","9.198083877563477"
+"306184192","2339","2339","2339","8.946911811828613","8.946911811828613","8.946911811828613"
+"306708480","2343","2343","2343","8.972898483276367","8.972898483276367","8.972898483276367"
+"307232768","2347","2347","2347","8.894308090209961","8.894308090209961","8.894308090209961"
+"307757056","2351","2351","2351","8.890226364135742","8.890226364135742","8.890226364135742"
+"308281344","2355","2355","2355","8.904067039489746","8.904067039489746","8.904067039489746"
+"308805632","2359","2359","2359","9.296585083007812","9.296585083007812","9.296585083007812"
+"309329920","2363","2363","2363","8.77762222290039","8.77762222290039","8.77762222290039"
+"309854208","2367","2367","2367","8.740535736083984","8.740535736083984","8.740535736083984"
+"310378496","2371","2371","2371","8.977279663085938","8.977279663085938","8.977279663085938"
+"310902784","2375","2375","2375","8.945862770080566","8.945862770080566","8.945862770080566"
+"311427072","2379","2379","2379","9.11939811706543","9.11939811706543","9.11939811706543"
+"311951360","2383","2383","2383","9.1245698928833","9.1245698928833","9.1245698928833"
+"312475648","2387","2387","2387","9.117781639099121","9.117781639099121","9.117781639099121"
+"312999936","2391","2391","2391","9.146018981933594","9.146018981933594","9.146018981933594"
+"313524224","2395","2395","2395","9.076337814331055","9.076337814331055","9.076337814331055"
+"314048512","2399","2399","2399","8.70168399810791","8.70168399810791","8.70168399810791"
+"314572800","2403","2403","2403","9.054915428161621","9.054915428161621","9.054915428161621"
+"315097088","2407","2407","2407","9.26833438873291","9.26833438873291","9.26833438873291"
+"315621376","2411","2411","2411","9.188345909118652","9.188345909118652","9.188345909118652"
+"316145664","2415","2415","2415","9.32247257232666","9.32247257232666","9.32247257232666"
+"316669952","2419","2419","2419","9.07752513885498","9.07752513885498","9.07752513885498"
+"317194240","2423","2423","2423","8.912997245788574","8.912997245788574","8.912997245788574"
+"317718528","2427","2427","2427","9.03773307800293","9.03773307800293","9.03773307800293"
+"318242816","2431","2431","2431","8.63060474395752","8.63060474395752","8.63060474395752"
+"318767104","2435","2435","2435","8.957215309143066","8.957215309143066","8.957215309143066"
+"319291392","2439","2439","2439","9.209489822387695","9.209489822387695","9.209489822387695"
+"319815680","2443","2443","2443","8.964225769042969","8.964225769042969","8.964225769042969"
+"320339968","2447","2447","2447","9.169089317321777","9.169089317321777","9.169089317321777"
+"320864256","2451","2451","2451","9.193458557128906","9.193458557128906","9.193458557128906"
+"321388544","2455","2455","2455","9.039697647094727","9.039697647094727","9.039697647094727"
+"321912832","2459","2459","2459","9.090550422668457","9.090550422668457","9.090550422668457"
+"322437120","2463","2463","2463","9.249098777770996","9.249098777770996","9.249098777770996"
+"322961408","2467","2467","2467","8.958226203918457","8.958226203918457","8.958226203918457"
+"323485696","2471","2471","2471","8.946199417114258","8.946199417114258","8.946199417114258"
+"324009984","2475","2475","2475","8.854289054870605","8.854289054870605","8.854289054870605"
+"324534272","2479","2479","2479","8.887396812438965","8.887396812438965","8.887396812438965"
+"325058560","2483","2483","2483","9.02319049835205","9.02319049835205","9.02319049835205"
+"325582848","2487","2487","2487","9.009795188903809","9.009795188903809","9.009795188903809"
+"326107136","2491","2491","2491","9.093616485595703","9.093616485595703","9.093616485595703"
+"326631424","2495","2495","2495","9.196060180664062","9.196060180664062","9.196060180664062"
+"327155712","2499","2499","2499","9.253827095031738","9.253827095031738","9.253827095031738"
+"327680000","2503","2503","2503","8.924580574035645","8.924580574035645","8.924580574035645"
+"328204288","2507","2507","2507","9.087443351745605","9.087443351745605","9.087443351745605"
+"328728576","2511","2511","2511","8.832974433898926","8.832974433898926","8.832974433898926"
+"329252864","2515","2515","2515","9.278822898864746","9.278822898864746","9.278822898864746"
+"329777152","2519","2519","2519","8.960373878479004","8.960373878479004","8.960373878479004"
+"330301440","2523","2523","2523","9.145363807678223","9.145363807678223","9.145363807678223"
+"330825728","2527","2527","2527","8.942113876342773","8.942113876342773","8.942113876342773"
+"331350016","2531","2531","2531","9.178567886352539","9.178567886352539","9.178567886352539"
+"331874304","2535","2535","2535","8.969266891479492","8.969266891479492","8.969266891479492"
+"332398592","2539","2539","2539","9.251665115356445","9.251665115356445","9.251665115356445"
+"332922880","2543","2543","2543","9.096817970275879","9.096817970275879","9.096817970275879"
+"333447168","2547","2547","2547","9.080641746520996","9.080641746520996","9.080641746520996"
+"333971456","2551","2551","2551","9.095097541809082","9.095097541809082","9.095097541809082"
+"334495744","2555","2555","2555","8.971198081970215","8.971198081970215","8.971198081970215"
+"335020032","2559","2559","2559","9.169442176818848","9.169442176818848","9.169442176818848"
+"335544320","2563","2563","2563","8.9874849319458","8.9874849319458","8.9874849319458"
+"336068608","2567","2567","2567","8.859960556030273","8.859960556030273","8.859960556030273"
+"336592896","2571","2571","2571","9.036728858947754","9.036728858947754","9.036728858947754"
+"337117184","2575","2575","2575","9.099166870117188","9.099166870117188","9.099166870117188"
+"337641472","2579","2579","2579","8.838260650634766","8.838260650634766","8.838260650634766"
+"338165760","2583","2583","2583","8.956584930419922","8.956584930419922","8.956584930419922"
+"338690048","2587","2587","2587","9.008081436157227","9.008081436157227","9.008081436157227"
+"339214336","2591","2591","2591","8.906499862670898","8.906499862670898","8.906499862670898"
+"339738624","2595","2595","2595","9.216617584228516","9.216617584228516","9.216617584228516"
+"340262912","2599","2599","2599","8.958976745605469","8.958976745605469","8.958976745605469"
+"340787200","2603","2603","2603","8.979302406311035","8.979302406311035","8.979302406311035"
+"341311488","2607","2607","2607","9.309233665466309","9.309233665466309","9.309233665466309"
+"341835776","2611","2611","2611","8.940740585327148","8.940740585327148","8.940740585327148"
+"342360064","2615","2615","2615","8.892938613891602","8.892938613891602","8.892938613891602"
+"342884352","2619","2619","2619","9.304838180541992","9.304838180541992","9.304838180541992"
+"343408640","2623","2623","2623","9.352987289428711","9.352987289428711","9.352987289428711"
+"343932928","2627","2627","2627","9.261303901672363","9.261303901672363","9.261303901672363"
+"344457216","2631","2631","2631","9.095276832580566","9.095276832580566","9.095276832580566"
+"344981504","2635","2635","2635","9.116477012634277","9.116477012634277","9.116477012634277"
+"345505792","2639","2639","2639","8.921157836914062","8.921157836914062","8.921157836914062"
+"346030080","2643","2643","2643","9.04650592803955","9.04650592803955","9.04650592803955"
+"346554368","2647","2647","2647","9.0235595703125","9.0235595703125","9.0235595703125"
+"347078656","2651","2651","2651","8.845080375671387","8.845080375671387","8.845080375671387"
+"347602944","2655","2655","2655","9.20824909210205","9.20824909210205","9.20824909210205"
+"348127232","2659","2659","2659","9.195837020874023","9.195837020874023","9.195837020874023"
+"348651520","2663","2663","2663","8.936582565307617","8.936582565307617","8.936582565307617"
+"349175808","2667","2667","2667","9.224352836608887","9.224352836608887","9.224352836608887"
+"349700096","2671","2671","2671","9.301715850830078","9.301715850830078","9.301715850830078"
+"350224384","2675","2675","2675","9.491003036499023","9.491003036499023","9.491003036499023"
+"350748672","2679","2679","2679","9.19706916809082","9.19706916809082","9.19706916809082"
+"351272960","2683","2683","2683","9.14610481262207","9.14610481262207","9.14610481262207"
+"351797248","2687","2687","2687","8.8736572265625","8.8736572265625","8.8736572265625"
+"352321536","2691","2691","2691","9.345108985900879","9.345108985900879","9.345108985900879"
+"352845824","2695","2695","2695","8.88541030883789","8.88541030883789","8.88541030883789"
+"353370112","2699","2699","2699","9.006522178649902","9.006522178649902","9.006522178649902"
+"353894400","2703","2703","2703","9.150788307189941","9.150788307189941","9.150788307189941"
+"354418688","2707","2707","2707","9.314587593078613","9.314587593078613","9.314587593078613"
+"354942976","2711","2711","2711","9.370266914367676","9.370266914367676","9.370266914367676"
+"355467264","2715","2715","2715","8.842535018920898","8.842535018920898","8.842535018920898"
+"355991552","2719","2719","2719","9.40207576751709","9.40207576751709","9.40207576751709"
+"356515840","2723","2723","2723","9.4003324508667","9.4003324508667","9.4003324508667"
+"357040128","2727","2727","2727","9.030604362487793","9.030604362487793","9.030604362487793"
+"357564416","2731","2731","2731","9.160575866699219","9.160575866699219","9.160575866699219"
+"358088704","2735","2735","2735","8.965463638305664","8.965463638305664","8.965463638305664"
+"358612992","2739","2739","2739","9.126675605773926","9.126675605773926","9.126675605773926"
+"359137280","2743","2743","2743","9.041937828063965","9.041937828063965","9.041937828063965"
+"359661568","2747","2747","2747","9.24373722076416","9.24373722076416","9.24373722076416"
+"360185856","2751","2751","2751","9.234206199645996","9.234206199645996","9.234206199645996"
+"360710144","2755","2755","2755","9.049647331237793","9.049647331237793","9.049647331237793"
+"361234432","2759","2759","2759","9.559507369995117","9.559507369995117","9.559507369995117"
+"361758720","2763","2763","2763","9.157123565673828","9.157123565673828","9.157123565673828"
+"362283008","2767","2767","2767","8.879568099975586","8.879568099975586","8.879568099975586"
+"362807296","2771","2771","2771","9.24372673034668","9.24372673034668","9.24372673034668"
+"363331584","2775","2775","2775","9.032673835754395","9.032673835754395","9.032673835754395"
+"363855872","2779","2779","2779","9.18370246887207","9.18370246887207","9.18370246887207"
+"364380160","2783","2783","2783","9.087952613830566","9.087952613830566","9.087952613830566"
+"364904448","2787","2787","2787","9.210758209228516","9.210758209228516","9.210758209228516"
+"365428736","2791","2791","2791","8.954496383666992","8.954496383666992","8.954496383666992"
+"365953024","2795","2795","2795","9.508502006530762","9.508502006530762","9.508502006530762"
+"366477312","2799","2799","2799","9.235496520996094","9.235496520996094","9.235496520996094"
+"367001600","2803","2803","2803","9.588506698608398","9.588506698608398","9.588506698608398"
+"367525888","2807","2807","2807","9.174452781677246","9.174452781677246","9.174452781677246"
+"368050176","2811","2811","2811","9.244355201721191","9.244355201721191","9.244355201721191"
+"368574464","2815","2815","2815","8.94876766204834","8.94876766204834","8.94876766204834"
+"369098752","2819","2819","2819","9.289024353027344","9.289024353027344","9.289024353027344"
+"369623040","2823","2823","2823","9.343794822692871","9.343794822692871","9.343794822692871"
+"370147328","2827","2827","2827","9.256508827209473","9.256508827209473","9.256508827209473"
+"370671616","2831","2831","2831","9.134054183959961","9.134054183959961","9.134054183959961"
+"371195904","2835","2835","2835","9.02328872680664","9.02328872680664","9.02328872680664"
+"371720192","2839","2839","2839","9.205462455749512","9.205462455749512","9.205462455749512"
+"372244480","2843","2843","2843","9.324348449707031","9.324348449707031","9.324348449707031"
+"372768768","2847","2847","2847","9.366362571716309","9.366362571716309","9.366362571716309"
+"373293056","2851","2851","2851","9.179678916931152","9.179678916931152","9.179678916931152"
+"373817344","2855","2855","2855","9.190567970275879","9.190567970275879","9.190567970275879"
+"374341632","2859","2859","2859","9.335193634033203","9.335193634033203","9.335193634033203"
+"374865920","2863","2863","2863","9.31345272064209","9.31345272064209","9.31345272064209"
+"375390208","2867","2867","2867","9.20544147491455","9.20544147491455","9.20544147491455"
+"375914496","2871","2871","2871","9.041049003601074","9.041049003601074","9.041049003601074"
+"376438784","2875","2875","2875","9.054017066955566","9.054017066955566","9.054017066955566"
+"376963072","2879","2879","2879","9.126070976257324","9.126070976257324","9.126070976257324"
+"377487360","2883","2883","2883","8.876952171325684","8.876952171325684","8.876952171325684"
+"378011648","2887","2887","2887","9.460274696350098","9.460274696350098","9.460274696350098"
+"378535936","2891","2891","2891","9.06075382232666","9.06075382232666","9.06075382232666"
+"379060224","2895","2895","2895","9.316102027893066","9.316102027893066","9.316102027893066"
+"379584512","2899","2899","2899","9.172006607055664","9.172006607055664","9.172006607055664"
+"380108800","2903","2903","2903","9.362411499023438","9.362411499023438","9.362411499023438"
+"380633088","2907","2907","2907","9.32859992980957","9.32859992980957","9.32859992980957"
+"381157376","2911","2911","2911","9.408387184143066","9.408387184143066","9.408387184143066"
+"381681664","2915","2915","2915","9.273536682128906","9.273536682128906","9.273536682128906"
+"382205952","2919","2919","2919","9.248327255249023","9.248327255249023","9.248327255249023"
+"382730240","2923","2923","2923","9.393256187438965","9.393256187438965","9.393256187438965"
+"383254528","2927","2927","2927","9.128240585327148","9.128240585327148","9.128240585327148"
+"383778816","2931","2931","2931","9.001033782958984","9.001033782958984","9.001033782958984"
+"384303104","2935","2935","2935","9.043665885925293","9.043665885925293","9.043665885925293"
+"384827392","2939","2939","2939","9.324769973754883","9.324769973754883","9.324769973754883"
+"385351680","2943","2943","2943","8.943511009216309","8.943511009216309","8.943511009216309"
+"385875968","2947","2947","2947","9.179971694946289","9.179971694946289","9.179971694946289"
+"386400256","2951","2951","2951","9.234777450561523","9.234777450561523","9.234777450561523"
+"386924544","2955","2955","2955","9.329157829284668","9.329157829284668","9.329157829284668"
+"387448832","2959","2959","2959","9.219292640686035","9.219292640686035","9.219292640686035"
+"387973120","2963","2963","2963","9.323090553283691","9.323090553283691","9.323090553283691"
+"388497408","2967","2967","2967","9.32108211517334","9.32108211517334","9.32108211517334"
+"389021696","2971","2971","2971","9.313253402709961","9.313253402709961","9.313253402709961"
+"389545984","2975","2975","2975","9.02721881866455","9.02721881866455","9.02721881866455"
+"390070272","2979","2979","2979","9.262237548828125","9.262237548828125","9.262237548828125"
+"390594560","2983","2983","2983","9.090727806091309","9.090727806091309","9.090727806091309"
+"391118848","2987","2987","2987","9.503425598144531","9.503425598144531","9.503425598144531"
+"391643136","2991","2991","2991","9.368765830993652","9.368765830993652","9.368765830993652"
+"392167424","2995","2995","2995","9.226033210754395","9.226033210754395","9.226033210754395"
+"392691712","2999","2999","2999","9.182291030883789","9.182291030883789","9.182291030883789"
+"393216000","3003","3003","3003","9.157920837402344","9.157920837402344","9.157920837402344"
+"393740288","3007","3007","3007","9.426156044006348","9.426156044006348","9.426156044006348"
+"394264576","3011","3011","3011","9.190093994140625","9.190093994140625","9.190093994140625"
+"394788864","3015","3015","3015","9.206888198852539","9.206888198852539","9.206888198852539"
+"395313152","3019","3019","3019","9.235243797302246","9.235243797302246","9.235243797302246"
+"395837440","3023","3023","3023","9.214956283569336","9.214956283569336","9.214956283569336"
+"396361728","3027","3027","3027","9.384309768676758","9.384309768676758","9.384309768676758"
+"396886016","3031","3031","3031","9.250812530517578","9.250812530517578","9.250812530517578"
+"397410304","3035","3035","3035","9.342812538146973","9.342812538146973","9.342812538146973"
+"397934592","3039","3039","3039","9.39427661895752","9.39427661895752","9.39427661895752"
+"398458880","3043","3043","3043","9.350890159606934","9.350890159606934","9.350890159606934"
+"398983168","3047","3047","3047","9.289216995239258","9.289216995239258","9.289216995239258"
+"399507456","3051","3051","3051","9.182892799377441","9.182892799377441","9.182892799377441"
+"400031744","3055","3055","3055","8.905096054077148","8.905096054077148","8.905096054077148"
+"400556032","3059","3059","3059","9.38297176361084","9.38297176361084","9.38297176361084"
+"401080320","3063","3063","3063","9.084840774536133","9.084840774536133","9.084840774536133"
+"401604608","3067","3067","3067","9.172090530395508","9.172090530395508","9.172090530395508"
+"402128896","3071","3071","3071","9.161079406738281","9.161079406738281","9.161079406738281"
+"402653184","3075","3075","3075","8.958829879760742","8.958829879760742","8.958829879760742"
+"403177472","3079","3079","3079","9.280121803283691","9.280121803283691","9.280121803283691"
+"403701760","3083","3083","3083","9.44886302947998","9.44886302947998","9.44886302947998"
+"404226048","3087","3087","3087","9.197381019592285","9.197381019592285","9.197381019592285"
+"404750336","3091","3091","3091","9.516891479492188","9.516891479492188","9.516891479492188"
+"405274624","3095","3095","3095","9.318999290466309","9.318999290466309","9.318999290466309"
+"405798912","3099","3099","3099","8.93913745880127","8.93913745880127","8.93913745880127"
+"406323200","3103","3103","3103","9.588942527770996","9.588942527770996","9.588942527770996"
+"406847488","3107","3107","3107","9.29694652557373","9.29694652557373","9.29694652557373"
+"407371776","3111","3111","3111","9.314275741577148","9.314275741577148","9.314275741577148"
+"407896064","3115","3115","3115","9.282323837280273","9.282323837280273","9.282323837280273"
+"408420352","3119","3119","3119","9.19389820098877","9.19389820098877","9.19389820098877"
+"408944640","3123","3123","3123","9.175281524658203","9.175281524658203","9.175281524658203"
+"409468928","3127","3127","3127","9.195965766906738","9.195965766906738","9.195965766906738"
+"409993216","3131","3131","3131","9.001907348632812","9.001907348632812","9.001907348632812"
+"410517504","3135","3135","3135","9.22225284576416","9.22225284576416","9.22225284576416"
+"411041792","3139","3139","3139","9.2852144241333","9.2852144241333","9.2852144241333"
+"411566080","3143","3143","3143","9.330471992492676","9.330471992492676","9.330471992492676"
+"412090368","3147","3147","3147","9.439184188842773","9.439184188842773","9.439184188842773"
+"412614656","3151","3151","3151","9.391225814819336","9.391225814819336","9.391225814819336"
+"413138944","3155","3155","3155","8.970218658447266","8.970218658447266","8.970218658447266"
+"413663232","3159","3159","3159","9.3351411819458","9.3351411819458","9.3351411819458"
+"414187520","3163","3163","3163","9.043503761291504","9.043503761291504","9.043503761291504"
+"414711808","3167","3167","3167","9.032645225524902","9.032645225524902","9.032645225524902"
+"415236096","3171","3171","3171","9.329307556152344","9.329307556152344","9.329307556152344"
+"415760384","3175","3175","3175","9.397128105163574","9.397128105163574","9.397128105163574"
+"416284672","3179","3179","3179","9.14667797088623","9.14667797088623","9.14667797088623"
+"416808960","3183","3183","3183","9.065032005310059","9.065032005310059","9.065032005310059"
+"417333248","3187","3187","3187","9.105179786682129","9.105179786682129","9.105179786682129"
+"417857536","3191","3191","3191","9.411609649658203","9.411609649658203","9.411609649658203"
+"418381824","3195","3195","3195","9.205428123474121","9.205428123474121","9.205428123474121"
+"418906112","3199","3199","3199","9.221160888671875","9.221160888671875","9.221160888671875"
+"419430400","3203","3203","3203","8.963289260864258","8.963289260864258","8.963289260864258"
+"419954688","3207","3207","3207","9.242879867553711","9.242879867553711","9.242879867553711"
+"420478976","3211","3211","3211","9.43168830871582","9.43168830871582","9.43168830871582"
+"421003264","3215","3215","3215","9.332289695739746","9.332289695739746","9.332289695739746"
+"421527552","3219","3219","3219","9.136493682861328","9.136493682861328","9.136493682861328"
+"422051840","3223","3223","3223","9.134683609008789","9.134683609008789","9.134683609008789"
+"422576128","3227","3227","3227","9.382786750793457","9.382786750793457","9.382786750793457"
+"423100416","3231","3231","3231","9.170095443725586","9.170095443725586","9.170095443725586"
+"423624704","3235","3235","3235","9.631953239440918","9.631953239440918","9.631953239440918"
+"424148992","3239","3239","3239","9.432544708251953","9.432544708251953","9.432544708251953"
+"424673280","3243","3243","3243","9.540389060974121","9.540389060974121","9.540389060974121"
+"425197568","3247","3247","3247","9.458906173706055","9.458906173706055","9.458906173706055"
+"425721856","3251","3251","3251","9.305014610290527","9.305014610290527","9.305014610290527"
+"426246144","3255","3255","3255","9.204147338867188","9.204147338867188","9.204147338867188"
+"426770432","3259","3259","3259","9.009442329406738","9.009442329406738","9.009442329406738"
+"427294720","3263","3263","3263","9.352191925048828","9.352191925048828","9.352191925048828"
+"427819008","3267","3267","3267","8.915205955505371","8.915205955505371","8.915205955505371"
+"428343296","3271","3271","3271","9.440874099731445","9.440874099731445","9.440874099731445"
+"428867584","3275","3275","3275","9.24692153930664","9.24692153930664","9.24692153930664"
+"429391872","3279","3279","3279","9.150289535522461","9.150289535522461","9.150289535522461"
+"429916160","3283","3283","3283","9.226444244384766","9.226444244384766","9.226444244384766"
+"430440448","3287","3287","3287","9.253327369689941","9.253327369689941","9.253327369689941"
+"430964736","3291","3291","3291","9.376832962036133","9.376832962036133","9.376832962036133"
+"431489024","3295","3295","3295","9.356219291687012","9.356219291687012","9.356219291687012"
+"432013312","3299","3299","3299","9.651755332946777","9.651755332946777","9.651755332946777"
+"432537600","3303","3303","3303","9.150593757629395","9.150593757629395","9.150593757629395"
+"433061888","3307","3307","3307","9.064197540283203","9.064197540283203","9.064197540283203"
+"433586176","3311","3311","3311","9.551351547241211","9.551351547241211","9.551351547241211"
+"434110464","3315","3315","3315","9.343184471130371","9.343184471130371","9.343184471130371"
+"434634752","3319","3319","3319","9.58554744720459","9.58554744720459","9.58554744720459"
+"435159040","3323","3323","3323","9.315423965454102","9.315423965454102","9.315423965454102"
+"435683328","3327","3327","3327","9.351025581359863","9.351025581359863","9.351025581359863"
+"436207616","3331","3331","3331","9.291979789733887","9.291979789733887","9.291979789733887"
+"436731904","3335","3335","3335","9.37076187133789","9.37076187133789","9.37076187133789"
+"437256192","3339","3339","3339","9.11796760559082","9.11796760559082","9.11796760559082"
+"437780480","3343","3343","3343","9.338715553283691","9.338715553283691","9.338715553283691"
+"438304768","3347","3347","3347","9.50802230834961","9.50802230834961","9.50802230834961"
+"438829056","3351","3351","3351","9.419231414794922","9.419231414794922","9.419231414794922"
+"439353344","3355","3355","3355","9.171850204467773","9.171850204467773","9.171850204467773"
+"439877632","3359","3359","3359","9.3157958984375","9.3157958984375","9.3157958984375"
+"440401920","3363","3363","3363","9.524181365966797","9.524181365966797","9.524181365966797"
+"440926208","3367","3367","3367","9.391175270080566","9.391175270080566","9.391175270080566"
+"441450496","3371","3371","3371","8.82343864440918","8.82343864440918","8.82343864440918"
+"441974784","3375","3375","3375","9.50165843963623","9.50165843963623","9.50165843963623"
+"442499072","3379","3379","3379","9.278989791870117","9.278989791870117","9.278989791870117"
+"443023360","3383","3383","3383","9.226808547973633","9.226808547973633","9.226808547973633"
+"443547648","3387","3387","3387","9.213056564331055","9.213056564331055","9.213056564331055"
+"444071936","3391","3391","3391","9.070013999938965","9.070013999938965","9.070013999938965"
+"444596224","3395","3395","3395","9.337774276733398","9.337774276733398","9.337774276733398"
+"445120512","3399","3399","3399","9.451620101928711","9.451620101928711","9.451620101928711"
+"445644800","3403","3403","3403","9.45910930633545","9.45910930633545","9.45910930633545"
+"446169088","3407","3407","3407","9.36987590789795","9.36987590789795","9.36987590789795"
+"446693376","3411","3411","3411","9.370281219482422","9.370281219482422","9.370281219482422"
+"447217664","3415","3415","3415","9.293584823608398","9.293584823608398","9.293584823608398"
+"447741952","3419","3419","3419","9.369904518127441","9.369904518127441","9.369904518127441"
+"448266240","3423","3423","3423","8.966924667358398","8.966924667358398","8.966924667358398"
+"448790528","3427","3427","3427","9.430665969848633","9.430665969848633","9.430665969848633"
+"449314816","3431","3431","3431","9.402471542358398","9.402471542358398","9.402471542358398"
+"449839104","3435","3435","3435","9.26331615447998","9.26331615447998","9.26331615447998"
+"450363392","3439","3439","3439","9.346036911010742","9.346036911010742","9.346036911010742"
+"450887680","3443","3443","3443","9.51987361907959","9.51987361907959","9.51987361907959"
+"451411968","3447","3447","3447","9.456409454345703","9.456409454345703","9.456409454345703"
+"451936256","3451","3451","3451","9.104767799377441","9.104767799377441","9.104767799377441"
+"452460544","3455","3455","3455","9.128091812133789","9.128091812133789","9.128091812133789"
+"452984832","3459","3459","3459","9.581616401672363","9.581616401672363","9.581616401672363"
+"453509120","3463","3463","3463","9.222943305969238","9.222943305969238","9.222943305969238"
+"454033408","3467","3467","3467","9.287898063659668","9.287898063659668","9.287898063659668"
+"454557696","3471","3471","3471","9.096412658691406","9.096412658691406","9.096412658691406"
+"455081984","3475","3475","3475","9.090007781982422","9.090007781982422","9.090007781982422"
+"455606272","3479","3479","3479","9.423996925354004","9.423996925354004","9.423996925354004"
+"456130560","3483","3483","3483","8.848224639892578","8.848224639892578","8.848224639892578"
+"456654848","3487","3487","3487","9.075959205627441","9.075959205627441","9.075959205627441"
+"457179136","3491","3491","3491","9.208756446838379","9.208756446838379","9.208756446838379"
+"457703424","3495","3495","3495","9.216540336608887","9.216540336608887","9.216540336608887"
+"458227712","3499","3499","3499","9.365835189819336","9.365835189819336","9.365835189819336"
+"458752000","3503","3503","3503","9.194707870483398","9.194707870483398","9.194707870483398"
+"459276288","3507","3507","3507","9.241138458251953","9.241138458251953","9.241138458251953"
+"459800576","3511","3511","3511","9.21322250366211","9.21322250366211","9.21322250366211"
+"460324864","3515","3515","3515","9.17597484588623","9.17597484588623","9.17597484588623"
+"460849152","3519","3519","3519","9.183836936950684","9.183836936950684","9.183836936950684"
+"461373440","3523","3523","3523","9.30542278289795","9.30542278289795","9.30542278289795"
+"461897728","3527","3527","3527","9.160015106201172","9.160015106201172","9.160015106201172"
+"462422016","3531","3531","3531","8.996058464050293","8.996058464050293","8.996058464050293"
+"462946304","3535","3535","3535","9.555971145629883","9.555971145629883","9.555971145629883"
+"463470592","3539","3539","3539","9.309124946594238","9.309124946594238","9.309124946594238"
+"463994880","3543","3543","3543","9.326796531677246","9.326796531677246","9.326796531677246"
+"464519168","3547","3547","3547","9.251713752746582","9.251713752746582","9.251713752746582"
+"465043456","3551","3551","3551","9.406816482543945","9.406816482543945","9.406816482543945"
+"465567744","3555","3555","3555","9.09354019165039","9.09354019165039","9.09354019165039"
+"466092032","3559","3559","3559","9.090614318847656","9.090614318847656","9.090614318847656"
+"466616320","3563","3563","3563","9.307323455810547","9.307323455810547","9.307323455810547"
+"467140608","3567","3567","3567","9.332450866699219","9.332450866699219","9.332450866699219"
+"467664896","3571","3571","3571","9.288686752319336","9.288686752319336","9.288686752319336"
+"468189184","3575","3575","3575","9.380495071411133","9.380495071411133","9.380495071411133"
+"468713472","3579","3579","3579","9.3650484085083","9.3650484085083","9.3650484085083"
+"469237760","3583","3583","3583","9.15886116027832","9.15886116027832","9.15886116027832"
+"469762048","3587","3587","3587","9.413251876831055","9.413251876831055","9.413251876831055"
+"470286336","3591","3591","3591","9.41928482055664","9.41928482055664","9.41928482055664"
+"470810624","3595","3595","3595","9.0986328125","9.0986328125","9.0986328125"
+"471334912","3599","3599","3599","9.454471588134766","9.454471588134766","9.454471588134766"
+"471859200","3603","3603","3603","9.369656562805176","9.369656562805176","9.369656562805176"
+"472383488","3607","3607","3607","9.09064769744873","9.09064769744873","9.09064769744873"
+"472907776","3611","3611","3611","9.057395935058594","9.057395935058594","9.057395935058594"
+"473432064","3615","3615","3615","9.256183624267578","9.256183624267578","9.256183624267578"
+"473956352","3619","3619","3619","9.198481559753418","9.198481559753418","9.198481559753418"
+"474480640","3623","3623","3623","9.40489673614502","9.40489673614502","9.40489673614502"
+"475004928","3627","3627","3627","9.520930290222168","9.520930290222168","9.520930290222168"
+"475529216","3631","3631","3631","9.3554048538208","9.3554048538208","9.3554048538208"
+"476053504","3635","3635","3635","9.270761489868164","9.270761489868164","9.270761489868164"
+"476577792","3639","3639","3639","9.309897422790527","9.309897422790527","9.309897422790527"
+"477102080","3643","3643","3643","9.504267692565918","9.504267692565918","9.504267692565918"
+"477626368","3647","3647","3647","9.538111686706543","9.538111686706543","9.538111686706543"
+"478150656","3651","3651","3651","9.449332237243652","9.449332237243652","9.449332237243652"
+"478674944","3655","3655","3655","9.401060104370117","9.401060104370117","9.401060104370117"
+"479199232","3659","3659","3659","9.56156063079834","9.56156063079834","9.56156063079834"
+"479723520","3663","3663","3663","9.044886589050293","9.044886589050293","9.044886589050293"
+"480247808","3667","3667","3667","9.333256721496582","9.333256721496582","9.333256721496582"
+"480772096","3671","3671","3671","9.143364906311035","9.143364906311035","9.143364906311035"
+"481296384","3675","3675","3675","9.100516319274902","9.100516319274902","9.100516319274902"
+"481820672","3679","3679","3679","9.174936294555664","9.174936294555664","9.174936294555664"
+"482344960","3683","3683","3683","9.258557319641113","9.258557319641113","9.258557319641113"
+"482869248","3687","3687","3687","9.309771537780762","9.309771537780762","9.309771537780762"
+"483393536","3691","3691","3691","9.306300163269043","9.306300163269043","9.306300163269043"
+"483917824","3695","3695","3695","9.345621109008789","9.345621109008789","9.345621109008789"
+"484442112","3699","3699","3699","9.217913627624512","9.217913627624512","9.217913627624512"
+"484966400","3703","3703","3703","9.256179809570312","9.256179809570312","9.256179809570312"
+"485490688","3707","3707","3707","9.420549392700195","9.420549392700195","9.420549392700195"
+"486014976","3711","3711","3711","9.312179565429688","9.312179565429688","9.312179565429688"
+"486539264","3715","3715","3715","9.064715385437012","9.064715385437012","9.064715385437012"
+"487063552","3719","3719","3719","9.235607147216797","9.235607147216797","9.235607147216797"
+"487587840","3723","3723","3723","9.631634712219238","9.631634712219238","9.631634712219238"
+"488112128","3727","3727","3727","9.27396297454834","9.27396297454834","9.27396297454834"
+"488636416","3731","3731","3731","9.164905548095703","9.164905548095703","9.164905548095703"
+"489160704","3735","3735","3735","9.40616226196289","9.40616226196289","9.40616226196289"
+"489684992","3739","3739","3739","9.462262153625488","9.462262153625488","9.462262153625488"
+"490209280","3743","3743","3743","9.433531761169434","9.433531761169434","9.433531761169434"
+"490733568","3747","3747","3747","9.264098167419434","9.264098167419434","9.264098167419434"
+"491257856","3751","3751","3751","9.458986282348633","9.458986282348633","9.458986282348633"
+"491782144","3755","3755","3755","9.416116714477539","9.416116714477539","9.416116714477539"
+"492306432","3759","3759","3759","9.407411575317383","9.407411575317383","9.407411575317383"
+"492830720","3763","3763","3763","9.435766220092773","9.435766220092773","9.435766220092773"
+"493355008","3767","3767","3767","8.851125717163086","8.851125717163086","8.851125717163086"
+"493879296","3771","3771","3771","9.491168975830078","9.491168975830078","9.491168975830078"
+"494403584","3775","3775","3775","9.121381759643555","9.121381759643555","9.121381759643555"
+"494927872","3779","3779","3779","9.424686431884766","9.424686431884766","9.424686431884766"
+"495452160","3783","3783","3783","9.189868927001953","9.189868927001953","9.189868927001953"
+"495976448","3787","3787","3787","9.218143463134766","9.218143463134766","9.218143463134766"
+"496500736","3791","3791","3791","8.937994956970215","8.937994956970215","8.937994956970215"
+"497025024","3795","3795","3795","9.252063751220703","9.252063751220703","9.252063751220703"
+"497549312","3799","3799","3799","9.496816635131836","9.496816635131836","9.496816635131836"
+"498073600","3803","3803","3803","9.035619735717773","9.035619735717773","9.035619735717773"
+"498597888","3807","3807","3807","9.400757789611816","9.400757789611816","9.400757789611816"
+"499122176","3811","3811","3811","9.47928237915039","9.47928237915039","9.47928237915039"
+"499646464","3815","3815","3815","9.210360527038574","9.210360527038574","9.210360527038574"
+"500170752","3819","3819","3819","9.555347442626953","9.555347442626953","9.555347442626953"
+"500695040","3823","3823","3823","9.411117553710938","9.411117553710938","9.411117553710938"
+"501219328","3827","3827","3827","9.287684440612793","9.287684440612793","9.287684440612793"
+"501743616","3831","3831","3831","9.205471992492676","9.205471992492676","9.205471992492676"
+"502267904","3835","3835","3835","9.217281341552734","9.217281341552734","9.217281341552734"
+"502792192","3839","3839","3839","9.368227005004883","9.368227005004883","9.368227005004883"
+"503316480","3843","3843","3843","9.373292922973633","9.373292922973633","9.373292922973633"
+"503840768","3847","3847","3847","9.11732292175293","9.11732292175293","9.11732292175293"
+"504365056","3851","3851","3851","9.421467781066895","9.421467781066895","9.421467781066895"
+"504889344","3855","3855","3855","9.4423828125","9.4423828125","9.4423828125"
+"505413632","3859","3859","3859","9.190903663635254","9.190903663635254","9.190903663635254"
+"505937920","3863","3863","3863","9.501843452453613","9.501843452453613","9.501843452453613"
+"506462208","3867","3867","3867","9.350699424743652","9.350699424743652","9.350699424743652"
+"506986496","3871","3871","3871","9.388336181640625","9.388336181640625","9.388336181640625"
+"507510784","3875","3875","3875","9.289436340332031","9.289436340332031","9.289436340332031"
+"508035072","3879","3879","3879","9.510381698608398","9.510381698608398","9.510381698608398"
+"508559360","3883","3883","3883","9.349577903747559","9.349577903747559","9.349577903747559"
+"509083648","3887","3887","3887","9.533156394958496","9.533156394958496","9.533156394958496"
+"509607936","3891","3891","3891","9.38808536529541","9.38808536529541","9.38808536529541"
+"510132224","3895","3895","3895","9.645160675048828","9.645160675048828","9.645160675048828"
+"510656512","3899","3899","3899","9.020174026489258","9.020174026489258","9.020174026489258"
+"511180800","3903","3903","3903","9.327804565429688","9.327804565429688","9.327804565429688"
+"511705088","3907","3907","3907","9.11660099029541","9.11660099029541","9.11660099029541"
+"512229376","3911","3911","3911","9.679944038391113","9.679944038391113","9.679944038391113"
+"512753664","3915","3915","3915","9.433900833129883","9.433900833129883","9.433900833129883"
+"513277952","3919","3919","3919","9.236374855041504","9.236374855041504","9.236374855041504"
+"513802240","3923","3923","3923","9.52741813659668","9.52741813659668","9.52741813659668"
+"514326528","3927","3927","3927","9.436004638671875","9.436004638671875","9.436004638671875"
+"514850816","3931","3931","3931","9.061700820922852","9.061700820922852","9.061700820922852"
+"515375104","3935","3935","3935","9.314432144165039","9.314432144165039","9.314432144165039"
+"515899392","3939","3939","3939","9.271389961242676","9.271389961242676","9.271389961242676"
+"516423680","3943","3943","3943","9.282325744628906","9.282325744628906","9.282325744628906"
+"516947968","3947","3947","3947","9.334095001220703","9.334095001220703","9.334095001220703"
+"517472256","3951","3951","3951","9.171257019042969","9.171257019042969","9.171257019042969"
+"517996544","3955","3955","3955","9.314071655273438","9.314071655273438","9.314071655273438"
+"518520832","3959","3959","3959","9.271900177001953","9.271900177001953","9.271900177001953"
+"519045120","3963","3963","3963","9.240345001220703","9.240345001220703","9.240345001220703"
+"519569408","3967","3967","3967","9.626763343811035","9.626763343811035","9.626763343811035"
+"520093696","3971","3971","3971","9.234000205993652","9.234000205993652","9.234000205993652"
+"520617984","3975","3975","3975","9.322667121887207","9.322667121887207","9.322667121887207"
+"521142272","3979","3979","3979","9.006135940551758","9.006135940551758","9.006135940551758"
+"521666560","3983","3983","3983","9.709856986999512","9.709856986999512","9.709856986999512"
+"522190848","3987","3987","3987","9.466510772705078","9.466510772705078","9.466510772705078"
+"522715136","3991","3991","3991","9.236577987670898","9.236577987670898","9.236577987670898"
+"523239424","3995","3995","3995","9.3031005859375","9.3031005859375","9.3031005859375"
+"523763712","3999","3999","3999","9.575467109680176","9.575467109680176","9.575467109680176"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_no_obst_ep_len.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_no_obst_ep_len.csv
new file mode 100644
index 000000000..fcf7ab169
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_no_obst_ep_len.csv
@@ -0,0 +1,151 @@
+"global_step","DRRandom_30-14-12-24 - _step","DRRandom_30-14-12-24 - _step__MIN","DRRandom_30-14-12-24 - _step__MAX","DRRandom_30-14-12-24 - episode_lengths/step","DRRandom_30-14-12-24 - episode_lengths/step__MIN","DRRandom_30-14-12-24 - episode_lengths/step__MAX"
+"5","3","3","3","73.2259521484375","73.2259521484375","73.2259521484375"
+"1638400","7","7","7","55.26566696166992","55.26566696166992","55.26566696166992"
+"3276800","11","11","11","60.16613006591797","60.16613006591797","60.16613006591797"
+"4915200","15","15","15","70.03802490234375","70.03802490234375","70.03802490234375"
+"6553600","19","19","19","79.03462982177734","79.03462982177734","79.03462982177734"
+"8192000","23","23","23","86.03240966796875","86.03240966796875","86.03240966796875"
+"9830400","27","27","27","90.65802764892578","90.65802764892578","90.65802764892578"
+"11468800","31","31","31","92.09781646728516","92.09781646728516","92.09781646728516"
+"13107200","35","35","35","94.39663696289062","94.39663696289062","94.39663696289062"
+"14745600","39","39","39","93.7631607055664","93.7631607055664","93.7631607055664"
+"16384000","43","43","43","90.40886688232422","90.40886688232422","90.40886688232422"
+"18022400","47","47","47","88.91542053222656","88.91542053222656","88.91542053222656"
+"19660800","51","51","51","86.2608642578125","86.2608642578125","86.2608642578125"
+"21299200","55","55","55","86.75355529785156","86.75355529785156","86.75355529785156"
+"22937600","59","59","59","86.3201904296875","86.3201904296875","86.3201904296875"
+"24576000","63","63","63","87.08451080322266","87.08451080322266","87.08451080322266"
+"26214400","67","67","67","88.92105102539062","88.92105102539062","88.92105102539062"
+"27852800","71","71","71","86.10293579101562","86.10293579101562","86.10293579101562"
+"29491200","75","75","75","87.78324890136719","87.78324890136719","87.78324890136719"
+"31129600","79","79","79","89.0646743774414","89.0646743774414","89.0646743774414"
+"32768000","83","83","83","89.42161560058594","89.42161560058594","89.42161560058594"
+"34406400","87","87","87","88.65217590332031","88.65217590332031","88.65217590332031"
+"36044800","91","91","91","83.40361022949219","83.40361022949219","83.40361022949219"
+"37683200","95","95","95","83.15818786621094","83.15818786621094","83.15818786621094"
+"39321600","99","99","99","83.69490814208984","83.69490814208984","83.69490814208984"
+"40960000","103","103","103","82.32984161376953","82.32984161376953","82.32984161376953"
+"42598400","107","107","107","79.75845336914062","79.75845336914062","79.75845336914062"
+"44236800","111","111","111","79.94886779785156","79.94886779785156","79.94886779785156"
+"45875200","115","115","115","78.79473114013672","78.79473114013672","78.79473114013672"
+"47513600","119","119","119","79.12765502929688","79.12765502929688","79.12765502929688"
+"49152000","123","123","123","77.3465347290039","77.3465347290039","77.3465347290039"
+"50790400","127","127","127","77.17098236083984","77.17098236083984","77.17098236083984"
+"52428800","131","131","131","75.84834289550781","75.84834289550781","75.84834289550781"
+"54067200","135","135","135","76.52153015136719","76.52153015136719","76.52153015136719"
+"55705600","139","139","139","76.37281036376953","76.37281036376953","76.37281036376953"
+"57344000","143","143","143","74.5140151977539","74.5140151977539","74.5140151977539"
+"58982400","147","147","147","76.48661041259766","76.48661041259766","76.48661041259766"
+"60620800","151","151","151","73.1066665649414","73.1066665649414","73.1066665649414"
+"62259200","155","155","155","72.65865325927734","72.65865325927734","72.65865325927734"
+"63897600","159","159","159","70.23477935791016","70.23477935791016","70.23477935791016"
+"65536000","163","163","163","72.10047912597656","72.10047912597656","72.10047912597656"
+"67174400","167","167","167","69.37345123291016","69.37345123291016","69.37345123291016"
+"68812800","171","171","171","69.71244812011719","69.71244812011719","69.71244812011719"
+"70451200","175","175","175","69.90234375","69.90234375","69.90234375"
+"72089600","179","179","179","69.5703125","69.5703125","69.5703125"
+"73728000","183","183","183","69.75330352783203","69.75330352783203","69.75330352783203"
+"75366400","187","187","187","69.69709777832031","69.69709777832031","69.69709777832031"
+"77004800","191","191","191","68.37712097167969","68.37712097167969","68.37712097167969"
+"78643200","195","195","195","68.75113677978516","68.75113677978516","68.75113677978516"
+"80281600","199","199","199","67.35775756835938","67.35775756835938","67.35775756835938"
+"81920000","203","203","203","68.62692260742188","68.62692260742188","68.62692260742188"
+"83558400","207","207","207","67.27125549316406","67.27125549316406","67.27125549316406"
+"85196800","211","211","211","65.46414947509766","65.46414947509766","65.46414947509766"
+"86835200","215","215","215","65.37890625","65.37890625","65.37890625"
+"88473600","219","219","219","67.10256958007812","67.10256958007812","67.10256958007812"
+"90112000","223","223","223","64.84716033935547","64.84716033935547","64.84716033935547"
+"91750400","227","227","227","66.06121826171875","66.06121826171875","66.06121826171875"
+"93388800","231","231","231","63.67059326171875","63.67059326171875","63.67059326171875"
+"95027200","235","235","235","64.23773956298828","64.23773956298828","64.23773956298828"
+"96665600","239","239","239","64.86776733398438","64.86776733398438","64.86776733398438"
+"98304000","243","243","243","64.69403076171875","64.69403076171875","64.69403076171875"
+"99942400","247","247","247","62.67354965209961","62.67354965209961","62.67354965209961"
+"101580800","251","251","251","62.622074127197266","62.622074127197266","62.622074127197266"
+"103219200","255","255","255","62.8876838684082","62.8876838684082","62.8876838684082"
+"104857600","259","259","259","64.2298812866211","64.2298812866211","64.2298812866211"
+"106496000","263","263","263","63.542015075683594","63.542015075683594","63.542015075683594"
+"108134400","267","267","267","61.66898727416992","61.66898727416992","61.66898727416992"
+"109772800","271","271","271","61.10646438598633","61.10646438598633","61.10646438598633"
+"111411200","275","275","275","61.18292236328125","61.18292236328125","61.18292236328125"
+"113049600","279","279","279","60.793357849121094","60.793357849121094","60.793357849121094"
+"114688000","283","283","283","59.69083786010742","59.69083786010742","59.69083786010742"
+"116326400","287","287","287","59.935482025146484","59.935482025146484","59.935482025146484"
+"117964800","291","291","291","59.53633117675781","59.53633117675781","59.53633117675781"
+"119603200","295","295","295","59.59921646118164","59.59921646118164","59.59921646118164"
+"121241600","299","299","299","59.29372787475586","59.29372787475586","59.29372787475586"
+"122880000","303","303","303","58.3277587890625","58.3277587890625","58.3277587890625"
+"124518400","307","307","307","58.45614242553711","58.45614242553711","58.45614242553711"
+"126156800","311","311","311","58.25267028808594","58.25267028808594","58.25267028808594"
+"127795200","315","315","315","58.18411636352539","58.18411636352539","58.18411636352539"
+"129433600","319","319","319","57.2491340637207","57.2491340637207","57.2491340637207"
+"131072000","323","323","323","57.33669662475586","57.33669662475586","57.33669662475586"
+"132710400","327","327","327","57.33012390136719","57.33012390136719","57.33012390136719"
+"134348800","331","331","331","57.62908935546875","57.62908935546875","57.62908935546875"
+"135987200","335","335","335","56.94055938720703","56.94055938720703","56.94055938720703"
+"137625600","339","339","339","57.03666305541992","57.03666305541992","57.03666305541992"
+"139264000","343","343","343","58.40892028808594","58.40892028808594","58.40892028808594"
+"140902400","347","347","347","57.251747131347656","57.251747131347656","57.251747131347656"
+"142540800","351","351","351","57.56794357299805","57.56794357299805","57.56794357299805"
+"144179200","355","355","355","56.36754608154297","56.36754608154297","56.36754608154297"
+"145817600","359","359","359","56.89902114868164","56.89902114868164","56.89902114868164"
+"147456000","363","363","363","55.528236389160156","55.528236389160156","55.528236389160156"
+"149094400","367","367","367","55.97965621948242","55.97965621948242","55.97965621948242"
+"150732800","371","371","371","56.02173614501953","56.02173614501953","56.02173614501953"
+"152371200","375","375","375","55.98999786376953","55.98999786376953","55.98999786376953"
+"154009600","379","379","379","55.87947463989258","55.87947463989258","55.87947463989258"
+"155648000","383","383","383","56.03873062133789","56.03873062133789","56.03873062133789"
+"157286400","387","387","387","55.887718200683594","55.887718200683594","55.887718200683594"
+"158924800","391","391","391","54.544822692871094","54.544822692871094","54.544822692871094"
+"160563200","395","395","395","55.37275695800781","55.37275695800781","55.37275695800781"
+"162201600","399","399","399","54.9360237121582","54.9360237121582","54.9360237121582"
+"163840000","403","403","403","54.241790771484375","54.241790771484375","54.241790771484375"
+"165478400","407","407","407","53.8125","53.8125","53.8125"
+"167116800","411","411","411","53.64307403564453","53.64307403564453","53.64307403564453"
+"168755200","415","415","415","54.05413818359375","54.05413818359375","54.05413818359375"
+"170393600","419","419","419","53.06666564941406","53.06666564941406","53.06666564941406"
+"172032000","423","423","423","54.12933349609375","54.12933349609375","54.12933349609375"
+"173670400","427","427","427","53.363914489746094","53.363914489746094","53.363914489746094"
+"175308800","431","431","431","53.88349533081055","53.88349533081055","53.88349533081055"
+"176947200","435","435","435","53.616127014160156","53.616127014160156","53.616127014160156"
+"178585600","439","439","439","53.4781379699707","53.4781379699707","53.4781379699707"
+"180224000","443","443","443","52.83061218261719","52.83061218261719","52.83061218261719"
+"181862400","447","447","447","52.9905891418457","52.9905891418457","52.9905891418457"
+"183500800","451","451","451","53.34294891357422","53.34294891357422","53.34294891357422"
+"185139200","455","455","455","52.91695785522461","52.91695785522461","52.91695785522461"
+"186777600","459","459","459","51.53973388671875","51.53973388671875","51.53973388671875"
+"188416000","463","463","463","52.86435317993164","52.86435317993164","52.86435317993164"
+"190054400","467","467","467","52.14714813232422","52.14714813232422","52.14714813232422"
+"191692800","471","471","471","52.54629135131836","52.54629135131836","52.54629135131836"
+"193331200","475","475","475","52.140625","52.140625","52.140625"
+"194969600","479","479","479","52.1446533203125","52.1446533203125","52.1446533203125"
+"196608000","483","483","483","52.090633392333984","52.090633392333984","52.090633392333984"
+"198246400","487","487","487","52.179813385009766","52.179813385009766","52.179813385009766"
+"199884800","491","491","491","51.175437927246094","51.175437927246094","51.175437927246094"
+"201523200","495","495","495","51.74534225463867","51.74534225463867","51.74534225463867"
+"203161600","499","499","499","51.06148910522461","51.06148910522461","51.06148910522461"
+"204800000","503","503","503","51.99074172973633","51.99074172973633","51.99074172973633"
+"206438400","507","507","507","51.89329147338867","51.89329147338867","51.89329147338867"
+"208076800","511","511","511","50.51334762573242","50.51334762573242","50.51334762573242"
+"209715200","515","515","515","50.297122955322266","50.297122955322266","50.297122955322266"
+"211353600","519","519","519","50.17133712768555","50.17133712768555","50.17133712768555"
+"212992000","523","523","523","50.80644989013672","50.80644989013672","50.80644989013672"
+"214630400","527","527","527","51.15658950805664","51.15658950805664","51.15658950805664"
+"216268800","531","531","531","50.83713150024414","50.83713150024414","50.83713150024414"
+"217907200","535","535","535","50.18012619018555","50.18012619018555","50.18012619018555"
+"219545600","539","539","539","49.24534225463867","49.24534225463867","49.24534225463867"
+"221184000","543","543","543","49.288230895996094","49.288230895996094","49.288230895996094"
+"222822400","547","547","547","49.34590530395508","49.34590530395508","49.34590530395508"
+"224460800","551","551","551","50.47230529785156","50.47230529785156","50.47230529785156"
+"226099200","555","555","555","49.4588623046875","49.4588623046875","49.4588623046875"
+"227737600","559","559","559","50.04985427856445","50.04985427856445","50.04985427856445"
+"229376000","563","563","563","50.64847946166992","50.64847946166992","50.64847946166992"
+"231014400","567","567","567","49.56626510620117","49.56626510620117","49.56626510620117"
+"232652800","571","571","571","49.307186126708984","49.307186126708984","49.307186126708984"
+"234291200","575","575","575","48.80516052246094","48.80516052246094","48.80516052246094"
+"235929600","579","579","579","49.97522735595703","49.97522735595703","49.97522735595703"
+"237568000","583","583","583","47.92452621459961","47.92452621459961","47.92452621459961"
+"239206400","587","587","587","48.69781494140625","48.69781494140625","48.69781494140625"
+"240844800","591","591","591","49.050559997558594","49.050559997558594","49.050559997558594"
+"242483200","595","595","595","48.47431945800781","48.47431945800781","48.47431945800781"
+"244121600","599","599","599","49.24793243408203","49.24793243408203","49.24793243408203"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_no_obst_rew.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_no_obst_rew.csv
new file mode 100644
index 000000000..bb08ec267
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/rand_no_obst_rew.csv
@@ -0,0 +1,151 @@
+"global_step","DRRandom_30-14-12-24 - _step","DRRandom_30-14-12-24 - _step__MIN","DRRandom_30-14-12-24 - _step__MAX","DRRandom_30-14-12-24 - rewards/step","DRRandom_30-14-12-24 - rewards/step__MIN","DRRandom_30-14-12-24 - rewards/step__MAX"
+"0","0","0","0","-34.648582458496094","-34.648582458496094","-34.648582458496094"
+"1638400","5","5","5","-30.1212100982666","-30.1212100982666","-30.1212100982666"
+"3276800","9","9","9","-29.351076126098633","-29.351076126098633","-29.351076126098633"
+"4915200","13","13","13","-27.606740951538086","-27.606740951538086","-27.606740951538086"
+"6553600","17","17","17","-27.50156021118164","-27.50156021118164","-27.50156021118164"
+"8192000","21","21","21","-22.063472747802734","-22.063472747802734","-22.063472747802734"
+"9830400","25","25","25","-19.44154930114746","-19.44154930114746","-19.44154930114746"
+"11468800","29","29","29","-17.980981826782227","-17.980981826782227","-17.980981826782227"
+"13107200","33","33","33","-14.263289451599121","-14.263289451599121","-14.263289451599121"
+"14745600","37","37","37","-12.626252174377441","-12.626252174377441","-12.626252174377441"
+"16384000","41","41","41","-11.838337898254395","-11.838337898254395","-11.838337898254395"
+"18022400","45","45","45","-9.172247886657715","-9.172247886657715","-9.172247886657715"
+"19660800","49","49","49","-7.004283428192139","-7.004283428192139","-7.004283428192139"
+"21299200","53","53","53","-5.599557876586914","-5.599557876586914","-5.599557876586914"
+"22937600","57","57","57","-4.175849914550781","-4.175849914550781","-4.175849914550781"
+"24576000","61","61","61","-2.819767475128174","-2.819767475128174","-2.819767475128174"
+"26214400","65","65","65","-0.46467480063438416","-0.46467480063438416","-0.46467480063438416"
+"27852800","69","69","69","1.973110318183899","1.973110318183899","1.973110318183899"
+"29491200","73","73","73","2.933623790740967","2.933623790740967","2.933623790740967"
+"31129600","77","77","77","4.996857166290283","4.996857166290283","4.996857166290283"
+"32768000","81","81","81","6.343785285949707","6.343785285949707","6.343785285949707"
+"34406400","85","85","85","7.074692726135254","7.074692726135254","7.074692726135254"
+"36044800","89","89","89","9.940253257751465","9.940253257751465","9.940253257751465"
+"37683200","93","93","93","10.35645580291748","10.35645580291748","10.35645580291748"
+"39321600","97","97","97","14.083338737487793","14.083338737487793","14.083338737487793"
+"40960000","101","101","101","13.900152206420898","13.900152206420898","13.900152206420898"
+"42598400","105","105","105","16.587736129760742","16.587736129760742","16.587736129760742"
+"44236800","109","109","109","17.186399459838867","17.186399459838867","17.186399459838867"
+"45875200","113","113","113","17.607789993286133","17.607789993286133","17.607789993286133"
+"47513600","117","117","117","19.194597244262695","19.194597244262695","19.194597244262695"
+"49152000","121","121","121","18.622400283813477","18.622400283813477","18.622400283813477"
+"50790400","125","125","125","21.004230499267578","21.004230499267578","21.004230499267578"
+"52428800","129","129","129","19.95351219177246","19.95351219177246","19.95351219177246"
+"54067200","133","133","133","19.91973114013672","19.91973114013672","19.91973114013672"
+"55705600","137","137","137","20.529125213623047","20.529125213623047","20.529125213623047"
+"57344000","141","141","141","21.85142707824707","21.85142707824707","21.85142707824707"
+"58982400","145","145","145","23.162181854248047","23.162181854248047","23.162181854248047"
+"60620800","149","149","149","22.31105613708496","22.31105613708496","22.31105613708496"
+"62259200","153","153","153","23.38030242919922","23.38030242919922","23.38030242919922"
+"63897600","157","157","157","23.340429306030273","23.340429306030273","23.340429306030273"
+"65536000","161","161","161","24.196866989135742","24.196866989135742","24.196866989135742"
+"67174400","165","165","165","23.787353515625","23.787353515625","23.787353515625"
+"68812800","169","169","169","24.587369918823242","24.587369918823242","24.587369918823242"
+"70451200","173","173","173","24.90770721435547","24.90770721435547","24.90770721435547"
+"72089600","177","177","177","26.06830596923828","26.06830596923828","26.06830596923828"
+"73728000","181","181","181","26.13243293762207","26.13243293762207","26.13243293762207"
+"75366400","185","185","185","25.86963653564453","25.86963653564453","25.86963653564453"
+"77004800","189","189","189","25.801361083984375","25.801361083984375","25.801361083984375"
+"78643200","193","193","193","26.39741325378418","26.39741325378418","26.39741325378418"
+"80281600","197","197","197","26.633975982666016","26.633975982666016","26.633975982666016"
+"81920000","201","201","201","27.07381248474121","27.07381248474121","27.07381248474121"
+"83558400","205","205","205","26.40694808959961","26.40694808959961","26.40694808959961"
+"85196800","209","209","209","26.69600486755371","26.69600486755371","26.69600486755371"
+"86835200","213","213","213","27.100812911987305","27.100812911987305","27.100812911987305"
+"88473600","217","217","217","27.635257720947266","27.635257720947266","27.635257720947266"
+"90112000","221","221","221","27.089914321899414","27.089914321899414","27.089914321899414"
+"91750400","225","225","225","27.91743278503418","27.91743278503418","27.91743278503418"
+"93388800","229","229","229","27.509849548339844","27.509849548339844","27.509849548339844"
+"95027200","233","233","233","27.108116149902344","27.108116149902344","27.108116149902344"
+"96665600","237","237","237","27.830595016479492","27.830595016479492","27.830595016479492"
+"98304000","241","241","241","27.763813018798828","27.763813018798828","27.763813018798828"
+"99942400","245","245","245","26.902423858642578","26.902423858642578","26.902423858642578"
+"101580800","249","249","249","27.199140548706055","27.199140548706055","27.199140548706055"
+"103219200","253","253","253","27.198486328125","27.198486328125","27.198486328125"
+"104857600","257","257","257","28.29524803161621","28.29524803161621","28.29524803161621"
+"106496000","261","261","261","28.282026290893555","28.282026290893555","28.282026290893555"
+"108134400","265","265","265","27.14423942565918","27.14423942565918","27.14423942565918"
+"109772800","269","269","269","27.4540958404541","27.4540958404541","27.4540958404541"
+"111411200","273","273","273","27.53458023071289","27.53458023071289","27.53458023071289"
+"113049600","277","277","277","27.8919620513916","27.8919620513916","27.8919620513916"
+"114688000","281","281","281","27.69491195678711","27.69491195678711","27.69491195678711"
+"116326400","285","285","285","27.895893096923828","27.895893096923828","27.895893096923828"
+"117964800","289","289","289","28.162538528442383","28.162538528442383","28.162538528442383"
+"119603200","293","293","293","27.87415313720703","27.87415313720703","27.87415313720703"
+"121241600","297","297","297","28.01224136352539","28.01224136352539","28.01224136352539"
+"122880000","301","301","301","27.588327407836914","27.588327407836914","27.588327407836914"
+"124518400","305","305","305","27.479372024536133","27.479372024536133","27.479372024536133"
+"126156800","309","309","309","27.465789794921875","27.465789794921875","27.465789794921875"
+"127795200","313","313","313","28.05790138244629","28.05790138244629","28.05790138244629"
+"129433600","317","317","317","27.813934326171875","27.813934326171875","27.813934326171875"
+"131072000","321","321","321","27.593000411987305","27.593000411987305","27.593000411987305"
+"132710400","325","325","325","27.95254898071289","27.95254898071289","27.95254898071289"
+"134348800","329","329","329","27.95635223388672","27.95635223388672","27.95635223388672"
+"135987200","333","333","333","27.830169677734375","27.830169677734375","27.830169677734375"
+"137625600","337","337","337","27.494770050048828","27.494770050048828","27.494770050048828"
+"139264000","341","341","341","28.606481552124023","28.606481552124023","28.606481552124023"
+"140902400","345","345","345","27.70370101928711","27.70370101928711","27.70370101928711"
+"142540800","349","349","349","28.194841384887695","28.194841384887695","28.194841384887695"
+"144179200","353","353","353","27.624059677124023","27.624059677124023","27.624059677124023"
+"145817600","357","357","357","27.892240524291992","27.892240524291992","27.892240524291992"
+"147456000","361","361","361","27.25101661682129","27.25101661682129","27.25101661682129"
+"149094400","365","365","365","27.511213302612305","27.511213302612305","27.511213302612305"
+"150732800","369","369","369","28.17357063293457","28.17357063293457","28.17357063293457"
+"152371200","373","373","373","27.986167907714844","27.986167907714844","27.986167907714844"
+"154009600","377","377","377","28.033226013183594","28.033226013183594","28.033226013183594"
+"155648000","381","381","381","28.549930572509766","28.549930572509766","28.549930572509766"
+"157286400","385","385","385","28.52841567993164","28.52841567993164","28.52841567993164"
+"158924800","389","389","389","27.96725845336914","27.96725845336914","27.96725845336914"
+"160563200","393","393","393","28.32246971130371","28.32246971130371","28.32246971130371"
+"162201600","397","397","397","28.96460723876953","28.96460723876953","28.96460723876953"
+"163840000","401","401","401","28.68648338317871","28.68648338317871","28.68648338317871"
+"165478400","405","405","405","28.266681671142578","28.266681671142578","28.266681671142578"
+"167116800","409","409","409","27.84853172302246","27.84853172302246","27.84853172302246"
+"168755200","413","413","413","28.689348220825195","28.689348220825195","28.689348220825195"
+"170393600","417","417","417","27.80359649658203","27.80359649658203","27.80359649658203"
+"172032000","421","421","421","28.734819412231445","28.734819412231445","28.734819412231445"
+"173670400","425","425","425","28.05352210998535","28.05352210998535","28.05352210998535"
+"175308800","429","429","429","28.353010177612305","28.353010177612305","28.353010177612305"
+"176947200","433","433","433","28.57078742980957","28.57078742980957","28.57078742980957"
+"178585600","437","437","437","28.016647338867188","28.016647338867188","28.016647338867188"
+"180224000","441","441","441","28.05998420715332","28.05998420715332","28.05998420715332"
+"181862400","445","445","445","28.435001373291016","28.435001373291016","28.435001373291016"
+"183500800","449","449","449","28.812469482421875","28.812469482421875","28.812469482421875"
+"185139200","453","453","453","28.464033126831055","28.464033126831055","28.464033126831055"
+"186777600","457","457","457","27.7030029296875","27.7030029296875","27.7030029296875"
+"188416000","461","461","461","28.52825355529785","28.52825355529785","28.52825355529785"
+"190054400","465","465","465","28.270030975341797","28.270030975341797","28.270030975341797"
+"191692800","469","469","469","28.522451400756836","28.522451400756836","28.522451400756836"
+"193331200","473","473","473","28.222618103027344","28.222618103027344","28.222618103027344"
+"194969600","477","477","477","28.3193302154541","28.3193302154541","28.3193302154541"
+"196608000","481","481","481","28.36888313293457","28.36888313293457","28.36888313293457"
+"198246400","485","485","485","28.480438232421875","28.480438232421875","28.480438232421875"
+"199884800","489","489","489","28.000661849975586","28.000661849975586","28.000661849975586"
+"201523200","493","493","493","28.23415184020996","28.23415184020996","28.23415184020996"
+"203161600","497","497","497","28.129283905029297","28.129283905029297","28.129283905029297"
+"204800000","501","501","501","28.86583709716797","28.86583709716797","28.86583709716797"
+"206438400","505","505","505","28.449851989746094","28.449851989746094","28.449851989746094"
+"208076800","509","509","509","27.624889373779297","27.624889373779297","27.624889373779297"
+"209715200","513","513","513","28.097293853759766","28.097293853759766","28.097293853759766"
+"211353600","517","517","517","28.15232276916504","28.15232276916504","28.15232276916504"
+"212992000","521","521","521","28.32122802734375","28.32122802734375","28.32122802734375"
+"214630400","525","525","525","28.64997673034668","28.64997673034668","28.64997673034668"
+"216268800","529","529","529","28.659990310668945","28.659990310668945","28.659990310668945"
+"217907200","533","533","533","28.073368072509766","28.073368072509766","28.073368072509766"
+"219545600","537","537","537","27.88176155090332","27.88176155090332","27.88176155090332"
+"221184000","541","541","541","27.94617462158203","27.94617462158203","27.94617462158203"
+"222822400","545","545","545","28.305850982666016","28.305850982666016","28.305850982666016"
+"224460800","549","549","549","28.913768768310547","28.913768768310547","28.913768768310547"
+"226099200","553","553","553","28.090038299560547","28.090038299560547","28.090038299560547"
+"227737600","557","557","557","28.590070724487305","28.590070724487305","28.590070724487305"
+"229376000","561","561","561","29.329328536987305","29.329328536987305","29.329328536987305"
+"231014400","565","565","565","28.48430061340332","28.48430061340332","28.48430061340332"
+"232652800","569","569","569","27.878942489624023","27.878942489624023","27.878942489624023"
+"234291200","573","573","573","28.04010772705078","28.04010772705078","28.04010772705078"
+"235929600","577","577","577","29.1005916595459","29.1005916595459","29.1005916595459"
+"237568000","581","581","581","27.41579246520996","27.41579246520996","27.41579246520996"
+"239206400","585","585","585","28.32807159423828","28.32807159423828","28.32807159423828"
+"240844800","589","589","589","28.05425453186035","28.05425453186035","28.05425453186035"
+"242483200","593","593","593","28.070119857788086","28.070119857788086","28.070119857788086"
+"244121600","597","597","597","28.770153045654297","28.770153045654297","28.770153045654297"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/splits_direct_ep_len.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/splits_direct_ep_len.csv
new file mode 100644
index 000000000..71a7cb6be
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/splits_direct_ep_len.csv
@@ -0,0 +1,301 @@
+"global_step","DRAsset_30-15-26-50 - _step","DRAsset_30-15-26-50 - _step__MIN","DRAsset_30-15-26-50 - _step__MAX","DRAsset_30-15-26-50 - episode_lengths/step","DRAsset_30-15-26-50 - episode_lengths/step__MIN","DRAsset_30-15-26-50 - episode_lengths/step__MAX"
+"4","3","3","3","49.640193939208984","49.640193939208984","49.640193939208984"
+"819200","7","7","7","57.4327278137207","57.4327278137207","57.4327278137207"
+"1638400","11","11","11","65.80400085449219","65.80400085449219","65.80400085449219"
+"2457600","15","15","15","71.01786041259766","71.01786041259766","71.01786041259766"
+"3276800","19","19","19","79.56571197509766","79.56571197509766","79.56571197509766"
+"4096000","23","23","23","94.1500015258789","94.1500015258789","94.1500015258789"
+"4915200","27","27","27","97.86861419677734","97.86861419677734","97.86861419677734"
+"5734400","31","31","31","108.20689392089844","108.20689392089844","108.20689392089844"
+"6553600","35","35","35","106.5384521484375","106.5384521484375","106.5384521484375"
+"7372800","39","39","39","106.78616333007812","106.78616333007812","106.78616333007812"
+"8192000","43","43","43","107.45945739746094","107.45945739746094","107.45945739746094"
+"9011200","47","47","47","90.7453384399414","90.7453384399414","90.7453384399414"
+"9830400","51","51","51","90.4733657836914","90.4733657836914","90.4733657836914"
+"10649600","55","55","55","117.49689483642578","117.49689483642578","117.49689483642578"
+"11468800","59","59","59","104.74481964111328","104.74481964111328","104.74481964111328"
+"12288000","63","63","63","118.28984832763672","118.28984832763672","118.28984832763672"
+"13107200","67","67","67","121.82925415039062","121.82925415039062","121.82925415039062"
+"13926400","71","71","71","127.21551513671875","127.21551513671875","127.21551513671875"
+"14745600","75","75","75","145.2936553955078","145.2936553955078","145.2936553955078"
+"15564800","79","79","79","142.21905517578125","142.21905517578125","142.21905517578125"
+"16384000","83","83","83","148.60345458984375","148.60345458984375","148.60345458984375"
+"17203200","87","87","87","152.10577392578125","152.10577392578125","152.10577392578125"
+"18022400","91","91","91","148.2568817138672","148.2568817138672","148.2568817138672"
+"18841600","95","95","95","149.01754760742188","149.01754760742188","149.01754760742188"
+"19660800","99","99","99","153.98117065429688","153.98117065429688","153.98117065429688"
+"20480000","103","103","103","164.80918884277344","164.80918884277344","164.80918884277344"
+"21299200","107","107","107","166.99029541015625","166.99029541015625","166.99029541015625"
+"22118400","111","111","111","166.50706481933594","166.50706481933594","166.50706481933594"
+"22937600","115","115","115","165.03636169433594","165.03636169433594","165.03636169433594"
+"23756800","119","119","119","165.81552124023438","165.81552124023438","165.81552124023438"
+"24576000","123","123","123","166.38925170898438","166.38925170898438","166.38925170898438"
+"25395200","127","127","127","165.27984619140625","165.27984619140625","165.27984619140625"
+"26214400","131","131","131","164.53553771972656","164.53553771972656","164.53553771972656"
+"27033600","135","135","135","167.7924346923828","167.7924346923828","167.7924346923828"
+"27852800","139","139","139","168.94276428222656","168.94276428222656","168.94276428222656"
+"28672000","143","143","143","171.31817626953125","171.31817626953125","171.31817626953125"
+"29491200","147","147","147","168.8461456298828","168.8461456298828","168.8461456298828"
+"30310400","151","151","151","173.14013671875","173.14013671875","173.14013671875"
+"31129600","155","155","155","171.0329132080078","171.0329132080078","171.0329132080078"
+"31948800","159","159","159","172.2074737548828","172.2074737548828","172.2074737548828"
+"32768000","163","163","163","174.9711456298828","174.9711456298828","174.9711456298828"
+"33587200","167","167","167","174.97789001464844","174.97789001464844","174.97789001464844"
+"34406400","171","171","171","174.49549865722656","174.49549865722656","174.49549865722656"
+"35225600","175","175","175","174.4860076904297","174.4860076904297","174.4860076904297"
+"36044800","179","179","179","173.61984252929688","173.61984252929688","173.61984252929688"
+"36864000","183","183","183","173.1695098876953","173.1695098876953","173.1695098876953"
+"37683200","187","187","187","172.62905883789062","172.62905883789062","172.62905883789062"
+"38502400","191","191","191","173.22523498535156","173.22523498535156","173.22523498535156"
+"39321600","195","195","195","173.11656188964844","173.11656188964844","173.11656188964844"
+"40140800","199","199","199","172.95614624023438","172.95614624023438","172.95614624023438"
+"40960000","203","203","203","173.06898498535156","173.06898498535156","173.06898498535156"
+"41779200","207","207","207","173.09999084472656","173.09999084472656","173.09999084472656"
+"42598400","211","211","211","174.0741424560547","174.0741424560547","174.0741424560547"
+"43417600","215","215","215","174.38526916503906","174.38526916503906","174.38526916503906"
+"44236800","219","219","219","174.81906127929688","174.81906127929688","174.81906127929688"
+"45056000","223","223","223","174.64857482910156","174.64857482910156","174.64857482910156"
+"45875200","227","227","227","175","175","175"
+"46694400","231","231","231","174.80450439453125","174.80450439453125","174.80450439453125"
+"47513600","235","235","235","174.8148193359375","174.8148193359375","174.8148193359375"
+"48332800","239","239","239","175","175","175"
+"49152000","243","243","243","174.6799774169922","174.6799774169922","174.6799774169922"
+"49971200","247","247","247","174.8504638671875","174.8504638671875","174.8504638671875"
+"50790400","251","251","251","175","175","175"
+"51609600","255","255","255","175","175","175"
+"52428800","259","259","259","173.489990234375","173.489990234375","173.489990234375"
+"53248000","263","263","263","174.97247314453125","174.97247314453125","174.97247314453125"
+"54067200","267","267","267","173.80999755859375","173.80999755859375","173.80999755859375"
+"54886400","271","271","271","174.8558349609375","174.8558349609375","174.8558349609375"
+"55705600","275","275","275","174.97169494628906","174.97169494628906","174.97169494628906"
+"56524800","279","279","279","174.944091796875","174.944091796875","174.944091796875"
+"57344000","283","283","283","174.74073791503906","174.74073791503906","174.74073791503906"
+"58163200","287","287","287","174.03822326660156","174.03822326660156","174.03822326660156"
+"58982400","291","291","291","174.40365600585938","174.40365600585938","174.40365600585938"
+"59801600","295","295","295","173.59536743164062","173.59536743164062","173.59536743164062"
+"60620800","299","299","299","173.44554138183594","173.44554138183594","173.44554138183594"
+"61440000","303","303","303","173.28099060058594","173.28099060058594","173.28099060058594"
+"62259200","307","307","307","172.95326232910156","172.95326232910156","172.95326232910156"
+"63078400","311","311","311","173.91526794433594","173.91526794433594","173.91526794433594"
+"63897600","315","315","315","173.75613403320312","173.75613403320312","173.75613403320312"
+"64716800","319","319","319","174.03475952148438","174.03475952148438","174.03475952148438"
+"65536000","323","323","323","174.42250061035156","174.42250061035156","174.42250061035156"
+"66355200","327","327","327","174.3095703125","174.3095703125","174.3095703125"
+"67174400","331","331","331","174.5194091796875","174.5194091796875","174.5194091796875"
+"67993600","335","335","335","174.4851531982422","174.4851531982422","174.4851531982422"
+"68812800","339","339","339","174.05130004882812","174.05130004882812","174.05130004882812"
+"69632000","343","343","343","174.3531951904297","174.3531951904297","174.3531951904297"
+"70451200","347","347","347","174.8632354736328","174.8632354736328","174.8632354736328"
+"71270400","351","351","351","172.92364501953125","172.92364501953125","172.92364501953125"
+"72089600","355","355","355","174.5887908935547","174.5887908935547","174.5887908935547"
+"72908800","359","359","359","174.84999084472656","174.84999084472656","174.84999084472656"
+"73728000","363","363","363","174.98684692382812","174.98684692382812","174.98684692382812"
+"74547200","367","367","367","174.7688446044922","174.7688446044922","174.7688446044922"
+"75366400","371","371","371","174.26998901367188","174.26998901367188","174.26998901367188"
+"76185600","375","375","375","174.8275909423828","174.8275909423828","174.8275909423828"
+"77004800","379","379","379","174.82275390625","174.82275390625","174.82275390625"
+"77824000","383","383","383","174.65191650390625","174.65191650390625","174.65191650390625"
+"78643200","387","387","387","174.61007690429688","174.61007690429688","174.61007690429688"
+"79462400","391","391","391","173.5961456298828","173.5961456298828","173.5961456298828"
+"80281600","395","395","395","173.1287078857422","173.1287078857422","173.1287078857422"
+"81100800","399","399","399","172.93460083007812","172.93460083007812","172.93460083007812"
+"81920000","403","403","403","172.01792907714844","172.01792907714844","172.01792907714844"
+"82739200","407","407","407","171.6409149169922","171.6409149169922","171.6409149169922"
+"83558400","411","411","411","169.21780395507812","169.21780395507812","169.21780395507812"
+"84377600","415","415","415","170.4701385498047","170.4701385498047","170.4701385498047"
+"85196800","419","419","419","169.5417938232422","169.5417938232422","169.5417938232422"
+"86016000","423","423","423","169.1210174560547","169.1210174560547","169.1210174560547"
+"86835200","427","427","427","168.4161834716797","168.4161834716797","168.4161834716797"
+"87654400","431","431","431","168.18446350097656","168.18446350097656","168.18446350097656"
+"88473600","435","435","435","167.28439331054688","167.28439331054688","167.28439331054688"
+"89292800","439","439","439","166.75962829589844","166.75962829589844","166.75962829589844"
+"90112000","443","443","443","165.39999389648438","165.39999389648438","165.39999389648438"
+"90931200","447","447","447","164.89999389648438","164.89999389648438","164.89999389648438"
+"91750400","451","451","451","164.40187072753906","164.40187072753906","164.40187072753906"
+"92569600","455","455","455","163.65345764160156","163.65345764160156","163.65345764160156"
+"93388800","459","459","459","162.86085510253906","162.86085510253906","162.86085510253906"
+"94208000","463","463","463","162.4112091064453","162.4112091064453","162.4112091064453"
+"95027200","467","467","467","161.75","161.75","161.75"
+"95846400","471","471","471","160.51515197753906","160.51515197753906","160.51515197753906"
+"96665600","475","475","475","161.2857208251953","161.2857208251953","161.2857208251953"
+"97484800","479","479","479","160.56521606445312","160.56521606445312","160.56521606445312"
+"98304000","483","483","483","160.3577880859375","160.3577880859375","160.3577880859375"
+"99123200","487","487","487","159.6548614501953","159.6548614501953","159.6548614501953"
+"99942400","491","491","491","158.920166015625","158.920166015625","158.920166015625"
+"100761600","495","495","495","158.2131805419922","158.2131805419922","158.2131805419922"
+"101580800","499","499","499","157.6571502685547","157.6571502685547","157.6571502685547"
+"102400000","503","503","503","157.3620147705078","157.3620147705078","157.3620147705078"
+"103219200","507","507","507","157.00282287597656","157.00282287597656","157.00282287597656"
+"104038400","511","511","511","156.4301300048828","156.4301300048828","156.4301300048828"
+"104857600","515","515","515","155.7433624267578","155.7433624267578","155.7433624267578"
+"105676800","519","519","519","155.4818115234375","155.4818115234375","155.4818115234375"
+"106496000","523","523","523","155.06106567382812","155.06106567382812","155.06106567382812"
+"107315200","527","527","527","154.96609497070312","154.96609497070312","154.96609497070312"
+"108134400","531","531","531","154.42755126953125","154.42755126953125","154.42755126953125"
+"108953600","535","535","535","154.21737670898438","154.21737670898438","154.21737670898438"
+"109772800","539","539","539","153.72476196289062","153.72476196289062","153.72476196289062"
+"110592000","543","543","543","153.47000122070312","153.47000122070312","153.47000122070312"
+"111411200","547","547","547","153.40740966796875","153.40740966796875","153.40740966796875"
+"112230400","551","551","551","153.07823181152344","153.07823181152344","153.07823181152344"
+"113049600","555","555","555","153.1540985107422","153.1540985107422","153.1540985107422"
+"113868800","559","559","559","153.1724090576172","153.1724090576172","153.1724090576172"
+"114688000","563","563","563","152.70079040527344","152.70079040527344","152.70079040527344"
+"115507200","567","567","567","152.54367065429688","152.54367065429688","152.54367065429688"
+"116326400","571","571","571","152.28097534179688","152.28097534179688","152.28097534179688"
+"117145600","575","575","575","151.77862548828125","151.77862548828125","151.77862548828125"
+"117964800","579","579","579","151.58120727539062","151.58120727539062","151.58120727539062"
+"118784000","583","583","583","151.60421752929688","151.60421752929688","151.60421752929688"
+"119603200","587","587","587","151.20175170898438","151.20175170898438","151.20175170898438"
+"120422400","591","591","591","151.04957580566406","151.04957580566406","151.04957580566406"
+"121241600","595","595","595","150.7413787841797","150.7413787841797","150.7413787841797"
+"122060800","599","599","599","150.67794799804688","150.67794799804688","150.67794799804688"
+"122880000","603","603","603","150.383056640625","150.383056640625","150.383056640625"
+"123699200","607","607","607","150.16964721679688","150.16964721679688","150.16964721679688"
+"124518400","611","611","611","149.94117736816406","149.94117736816406","149.94117736816406"
+"125337600","615","615","615","149.76905822753906","149.76905822753906","149.76905822753906"
+"126156800","619","619","619","149.7118682861328","149.7118682861328","149.7118682861328"
+"126976000","623","623","623","149.50433349609375","149.50433349609375","149.50433349609375"
+"127795200","627","627","627","149.2818145751953","149.2818145751953","149.2818145751953"
+"128614400","631","631","631","148.95651245117188","148.95651245117188","148.95651245117188"
+"129433600","635","635","635","148.68931579589844","148.68931579589844","148.68931579589844"
+"130252800","639","639","639","148.57144165039062","148.57144165039062","148.57144165039062"
+"131072000","643","643","643","148.6885223388672","148.6885223388672","148.6885223388672"
+"131891200","647","647","647","148.50819396972656","148.50819396972656","148.50819396972656"
+"132710400","651","651","651","147.78152465820312","147.78152465820312","147.78152465820312"
+"133529600","655","655","655","147.9618377685547","147.9618377685547","147.9618377685547"
+"134348800","659","659","659","147.6752166748047","147.6752166748047","147.6752166748047"
+"135168000","663","663","663","147.56756591796875","147.56756591796875","147.56756591796875"
+"135987200","667","667","667","147.46212768554688","147.46212768554688","147.46212768554688"
+"136806400","671","671","671","147.41175842285156","147.41175842285156","147.41175842285156"
+"137625600","675","675","675","147.44000244140625","147.44000244140625","147.44000244140625"
+"138444800","679","679","679","147.38462829589844","147.38462829589844","147.38462829589844"
+"139264000","683","683","683","147.4339599609375","147.4339599609375","147.4339599609375"
+"140083200","687","687","687","147.25439453125","147.25439453125","147.25439453125"
+"140902400","691","691","691","147.2761993408203","147.2761993408203","147.2761993408203"
+"141721600","695","695","695","146.9781036376953","146.9781036376953","146.9781036376953"
+"142540800","699","699","699","145.85714721679688","145.85714721679688","145.85714721679688"
+"143360000","703","703","703","146.63551330566406","146.63551330566406","146.63551330566406"
+"144179200","707","707","707","146.6792449951172","146.6792449951172","146.6792449951172"
+"144998400","711","711","711","146.40179443359375","146.40179443359375","146.40179443359375"
+"145817600","715","715","715","146.07225036621094","146.07225036621094","146.07225036621094"
+"146636800","719","719","719","146.2042694091797","146.2042694091797","146.2042694091797"
+"147456000","723","723","723","146.19129943847656","146.19129943847656","146.19129943847656"
+"148275200","727","727","727","146.03419494628906","146.03419494628906","146.03419494628906"
+"149094400","731","731","731","146.3333282470703","146.3333282470703","146.3333282470703"
+"149913600","735","735","735","146.2539825439453","146.2539825439453","146.2539825439453"
+"150732800","739","739","739","146.21368408203125","146.21368408203125","146.21368408203125"
+"151552000","743","743","743","146.20755004882812","146.20755004882812","146.20755004882812"
+"152371200","747","747","747","146.14633178710938","146.14633178710938","146.14633178710938"
+"153190400","751","751","751","146.1428680419922","146.1428680419922","146.1428680419922"
+"154009600","755","755","755","146.03509521484375","146.03509521484375","146.03509521484375"
+"154828800","759","759","759","145.2649688720703","145.2649688720703","145.2649688720703"
+"155648000","763","763","763","145.73831176757812","145.73831176757812","145.73831176757812"
+"156467200","767","767","767","145.6981201171875","145.6981201171875","145.6981201171875"
+"157286400","771","771","771","145.68504333496094","145.68504333496094","145.68504333496094"
+"158105600","775","775","775","145.58653259277344","145.58653259277344","145.58653259277344"
+"158924800","779","779","779","145.5250701904297","145.5250701904297","145.5250701904297"
+"159744000","783","783","783","145.54385375976562","145.54385375976562","145.54385375976562"
+"160563200","787","787","787","145.5083465576172","145.5083465576172","145.5083465576172"
+"161382400","791","791","791","145.42063903808594","145.42063903808594","145.42063903808594"
+"162201600","795","795","795","145.36538696289062","145.36538696289062","145.36538696289062"
+"163020800","799","799","799","145.3251953125","145.3251953125","145.3251953125"
+"163840000","803","803","803","145.33644104003906","145.33644104003906","145.33644104003906"
+"164659200","807","807","807","145.3515625","145.3515625","145.3515625"
+"165478400","811","811","811","145.8867950439453","145.8867950439453","145.8867950439453"
+"166297600","815","815","815","145.66363525390625","145.66363525390625","145.66363525390625"
+"167116800","819","819","819","145.609375","145.609375","145.609375"
+"167936000","823","823","823","145.53042602539062","145.53042602539062","145.53042602539062"
+"168755200","827","827","827","145.54385375976562","145.54385375976562","145.54385375976562"
+"169574400","831","831","831","145.58714294433594","145.58714294433594","145.58714294433594"
+"170393600","835","835","835","145.49212646484375","145.49212646484375","145.49212646484375"
+"171212800","839","839","839","145.3920135498047","145.3920135498047","145.3920135498047"
+"172032000","843","843","843","145.32562255859375","145.32562255859375","145.32562255859375"
+"172851200","847","847","847","145.2954559326172","145.2954559326172","145.2954559326172"
+"173670400","851","851","851","144.5775909423828","144.5775909423828","144.5775909423828"
+"174489600","855","855","855","145.19468688964844","145.19468688964844","145.19468688964844"
+"175308800","859","859","859","145.036865234375","145.036865234375","145.036865234375"
+"176128000","863","863","863","145","145","145"
+"176947200","867","867","867","145.08572387695312","145.08572387695312","145.08572387695312"
+"177766400","871","871","871","144.7948760986328","144.7948760986328","144.7948760986328"
+"178585600","875","875","875","144.72032165527344","144.72032165527344","144.72032165527344"
+"179404800","879","879","879","144.84356689453125","144.84356689453125","144.84356689453125"
+"180224000","883","883","883","144.78260803222656","144.78260803222656","144.78260803222656"
+"181043200","887","887","887","144.59048461914062","144.59048461914062","144.59048461914062"
+"181862400","891","891","891","144.45713806152344","144.45713806152344","144.45713806152344"
+"182681600","895","895","895","144.57144165039062","144.57144165039062","144.57144165039062"
+"183500800","899","899","899","144.52679443359375","144.52679443359375","144.52679443359375"
+"184320000","903","903","903","144.46153259277344","144.46153259277344","144.46153259277344"
+"185139200","907","907","907","144.31582641601562","144.31582641601562","144.31582641601562"
+"185958400","911","911","911","144.20513916015625","144.20513916015625","144.20513916015625"
+"186777600","915","915","915","144.21929931640625","144.21929931640625","144.21929931640625"
+"187596800","919","919","919","144.12612915039062","144.12612915039062","144.12612915039062"
+"188416000","923","923","923","144.14048767089844","144.14048767089844","144.14048767089844"
+"189235200","927","927","927","144.0291290283203","144.0291290283203","144.0291290283203"
+"190054400","931","931","931","143.92913818359375","143.92913818359375","143.92913818359375"
+"190873600","935","935","935","144.21817016601562","144.21817016601562","144.21817016601562"
+"191692800","939","939","939","144.30555725097656","144.30555725097656","144.30555725097656"
+"192512000","943","943","943","144.33042907714844","144.33042907714844","144.33042907714844"
+"193331200","947","947","947","144.1428680419922","144.1428680419922","144.1428680419922"
+"194150400","951","951","951","144.49586486816406","144.49586486816406","144.49586486816406"
+"194969600","955","955","955","144.2882843017578","144.2882843017578","144.2882843017578"
+"195788800","959","959","959","144.23703002929688","144.23703002929688","144.23703002929688"
+"196608000","963","963","963","143.9593505859375","143.9593505859375","143.9593505859375"
+"197427200","967","967","967","144.1052703857422","144.1052703857422","144.1052703857422"
+"198246400","971","971","971","144.17857360839844","144.17857360839844","144.17857360839844"
+"199065600","975","975","975","144.07920837402344","144.07920837402344","144.07920837402344"
+"199884800","979","979","979","144.1739044189453","144.1739044189453","144.1739044189453"
+"200704000","983","983","983","143.96434020996094","143.96434020996094","143.96434020996094"
+"201523200","987","987","987","143.98095703125","143.98095703125","143.98095703125"
+"202342400","991","991","991","144.03509521484375","144.03509521484375","144.03509521484375"
+"203161600","995","995","995","143.92633056640625","143.92633056640625","143.92633056640625"
+"203980800","999","999","999","144","144","144"
+"204800000","1003","1003","1003","143.9327850341797","143.9327850341797","143.9327850341797"
+"205619200","1007","1007","1007","144.07501220703125","144.07501220703125","144.07501220703125"
+"206438400","1011","1011","1011","144.07208251953125","144.07208251953125","144.07208251953125"
+"207257600","1015","1015","1015","144.02305603027344","144.02305603027344","144.02305603027344"
+"208076800","1019","1019","1019","143.9352569580078","143.9352569580078","143.9352569580078"
+"208896000","1023","1023","1023","143.75238037109375","143.75238037109375","143.75238037109375"
+"209715200","1027","1027","1027","143.83050537109375","143.83050537109375","143.83050537109375"
+"210534400","1031","1031","1031","143.73846435546875","143.73846435546875","143.73846435546875"
+"211353600","1035","1035","1035","143.6320037841797","143.6320037841797","143.6320037841797"
+"212172800","1039","1039","1039","143.6525421142578","143.6525421142578","143.6525421142578"
+"212992000","1043","1043","1043","143.49166870117188","143.49166870117188","143.49166870117188"
+"213811200","1047","1047","1047","143.5086212158203","143.5086212158203","143.5086212158203"
+"214630400","1051","1051","1051","143.58824157714844","143.58824157714844","143.58824157714844"
+"215449600","1055","1055","1055","143.68067932128906","143.68067932128906","143.68067932128906"
+"216268800","1059","1059","1059","143.49618530273438","143.49618530273438","143.49618530273438"
+"217088000","1063","1063","1063","143.30357360839844","143.30357360839844","143.30357360839844"
+"217907200","1067","1067","1067","143.43809509277344","143.43809509277344","143.43809509277344"
+"218726400","1071","1071","1071","143.51695251464844","143.51695251464844","143.51695251464844"
+"219545600","1075","1075","1075","143.52992248535156","143.52992248535156","143.52992248535156"
+"220364800","1079","1079","1079","143.68333435058594","143.68333435058594","143.68333435058594"
+"221184000","1083","1083","1083","143.10317993164062","143.10317993164062","143.10317993164062"
+"222003200","1087","1087","1087","143.50457763671875","143.50457763671875","143.50457763671875"
+"222822400","1091","1091","1091","143.57144165039062","143.57144165039062","143.57144165039062"
+"223641600","1095","1095","1095","143.62608337402344","143.62608337402344","143.62608337402344"
+"224460800","1099","1099","1099","143","143","143"
+"225280000","1103","1103","1103","143.60194396972656","143.60194396972656","143.60194396972656"
+"226099200","1107","1107","1107","143.5462188720703","143.5462188720703","143.5462188720703"
+"226918400","1111","1111","1111","143.54031372070312","143.54031372070312","143.54031372070312"
+"227737600","1115","1115","1115","143.53773498535156","143.53773498535156","143.53773498535156"
+"228556800","1119","1119","1119","143.5800018310547","143.5800018310547","143.5800018310547"
+"229376000","1123","1123","1123","143.59292602539062","143.59292602539062","143.59292602539062"
+"230195200","1127","1127","1127","143.47750854492188","143.47750854492188","143.47750854492188"
+"231014400","1131","1131","1131","143.4608612060547","143.4608612060547","143.4608612060547"
+"231833600","1135","1135","1135","143.46279907226562","143.46279907226562","143.46279907226562"
+"232652800","1139","1139","1139","143.06153869628906","143.06153869628906","143.06153869628906"
+"233472000","1143","1143","1143","143.49090576171875","143.49090576171875","143.49090576171875"
+"234291200","1147","1147","1147","143.5137481689453","143.5137481689453","143.5137481689453"
+"235110400","1151","1151","1151","143.54348754882812","143.54348754882812","143.54348754882812"
+"235929600","1155","1155","1155","143.515869140625","143.515869140625","143.515869140625"
+"236748800","1159","1159","1159","143.47169494628906","143.47169494628906","143.47169494628906"
+"237568000","1163","1163","1163","143.5765838623047","143.5765838623047","143.5765838623047"
+"238387200","1167","1167","1167","143.51852416992188","143.51852416992188","143.51852416992188"
+"239206400","1171","1171","1171","143.5370330810547","143.5370330810547","143.5370330810547"
+"240025600","1175","1175","1175","143.62095642089844","143.62095642089844","143.62095642089844"
+"240844800","1179","1179","1179","143.61666870117188","143.61666870117188","143.61666870117188"
+"241664000","1183","1183","1183","143.37815856933594","143.37815856933594","143.37815856933594"
+"242483200","1187","1187","1187","143.55262756347656","143.55262756347656","143.55262756347656"
+"243302400","1191","1191","1191","143.62384033203125","143.62384033203125","143.62384033203125"
+"244121600","1195","1195","1195","143.61351013183594","143.61351013183594","143.61351013183594"
+"244940800","1199","1199","1199","143.55453491210938","143.55453491210938","143.55453491210938"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/train_log/splits_direct_rew.csv b/isaacgymenvs/tasks/drone_racing/demos/train_log/splits_direct_rew.csv
new file mode 100644
index 000000000..a968b01cd
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/train_log/splits_direct_rew.csv
@@ -0,0 +1,301 @@
+"global_step","DRAsset_30-15-26-50 - _step","DRAsset_30-15-26-50 - _step__MIN","DRAsset_30-15-26-50 - _step__MAX","DRAsset_30-15-26-50 - rewards/step","DRAsset_30-15-26-50 - rewards/step__MIN","DRAsset_30-15-26-50 - rewards/step__MAX"
+"0","0","0","0","-32.18203353881836","-32.18203353881836","-32.18203353881836"
+"819200","5","5","5","-31.31485939025879","-31.31485939025879","-31.31485939025879"
+"1638400","9","9","9","-29.983402252197266","-29.983402252197266","-29.983402252197266"
+"2457600","13","13","13","-28.452274322509766","-28.452274322509766","-28.452274322509766"
+"3276800","17","17","17","-29.7622013092041","-29.7622013092041","-29.7622013092041"
+"4096000","21","21","21","-26.898210525512695","-26.898210525512695","-26.898210525512695"
+"4915200","25","25","25","-22.582130432128906","-22.582130432128906","-22.582130432128906"
+"5734400","29","29","29","-18.98211669921875","-18.98211669921875","-18.98211669921875"
+"6553600","33","33","33","-13.359375","-13.359375","-13.359375"
+"7372800","37","37","37","-7.691965103149414","-7.691965103149414","-7.691965103149414"
+"8192000","41","41","41","-5.0782151222229","-5.0782151222229","-5.0782151222229"
+"9011200","45","45","45","-1.415287733078003","-1.415287733078003","-1.415287733078003"
+"9830400","49","49","49","1.708681583404541","1.708681583404541","1.708681583404541"
+"10649600","53","53","53","7.796047210693359","7.796047210693359","7.796047210693359"
+"11468800","57","57","57","8.537351608276367","8.537351608276367","8.537351608276367"
+"12288000","61","61","61","12.846026420593262","12.846026420593262","12.846026420593262"
+"13107200","65","65","65","15.166170120239258","15.166170120239258","15.166170120239258"
+"13926400","69","69","69","18.70228385925293","18.70228385925293","18.70228385925293"
+"14745600","73","73","73","23.124481201171875","23.124481201171875","23.124481201171875"
+"15564800","77","77","77","25.067079544067383","25.067079544067383","25.067079544067383"
+"16384000","81","81","81","29.463058471679688","29.463058471679688","29.463058471679688"
+"17203200","85","85","85","32.145843505859375","32.145843505859375","32.145843505859375"
+"18022400","89","89","89","33.79744338989258","33.79744338989258","33.79744338989258"
+"18841600","93","93","93","34.957698822021484","34.957698822021484","34.957698822021484"
+"19660800","97","97","97","38.76231002807617","38.76231002807617","38.76231002807617"
+"20480000","101","101","101","42.40336990356445","42.40336990356445","42.40336990356445"
+"21299200","105","105","105","44.89889144897461","44.89889144897461","44.89889144897461"
+"22118400","109","109","109","46.76588439941406","46.76588439941406","46.76588439941406"
+"22937600","113","113","113","47.22659683227539","47.22659683227539","47.22659683227539"
+"23756800","117","117","117","49.026268005371094","49.026268005371094","49.026268005371094"
+"24576000","121","121","121","51.38692092895508","51.38692092895508","51.38692092895508"
+"25395200","125","125","125","50.82630920410156","50.82630920410156","50.82630920410156"
+"26214400","129","129","129","52.42961883544922","52.42961883544922","52.42961883544922"
+"27033600","133","133","133","54.76578140258789","54.76578140258789","54.76578140258789"
+"27852800","137","137","137","57.36787796020508","57.36787796020508","57.36787796020508"
+"28672000","141","141","141","60.63254928588867","60.63254928588867","60.63254928588867"
+"29491200","145","145","145","60.6993293762207","60.6993293762207","60.6993293762207"
+"30310400","149","149","149","63.93501281738281","63.93501281738281","63.93501281738281"
+"31129600","153","153","153","64.21807098388672","64.21807098388672","64.21807098388672"
+"31948800","157","157","157","65.45503234863281","65.45503234863281","65.45503234863281"
+"32768000","161","161","161","67.21717834472656","67.21717834472656","67.21717834472656"
+"33587200","165","165","165","67.4539566040039","67.4539566040039","67.4539566040039"
+"34406400","169","169","169","67.46314239501953","67.46314239501953","67.46314239501953"
+"35225600","173","173","173","68.01870727539062","68.01870727539062","68.01870727539062"
+"36044800","177","177","177","68.63600158691406","68.63600158691406","68.63600158691406"
+"36864000","181","181","181","68.84632873535156","68.84632873535156","68.84632873535156"
+"37683200","185","185","185","70.38807678222656","70.38807678222656","70.38807678222656"
+"38502400","189","189","189","71.78939819335938","71.78939819335938","71.78939819335938"
+"39321600","193","193","193","73.10181427001953","73.10181427001953","73.10181427001953"
+"40140800","197","197","197","74.04694366455078","74.04694366455078","74.04694366455078"
+"40960000","201","201","201","74.77945709228516","74.77945709228516","74.77945709228516"
+"41779200","205","205","205","74.95346069335938","74.95346069335938","74.95346069335938"
+"42598400","209","209","209","75.55719757080078","75.55719757080078","75.55719757080078"
+"43417600","213","213","213","75.91909790039062","75.91909790039062","75.91909790039062"
+"44236800","217","217","217","76.4078140258789","76.4078140258789","76.4078140258789"
+"45056000","221","221","221","76.83942413330078","76.83942413330078","76.83942413330078"
+"45875200","225","225","225","77.5467300415039","77.5467300415039","77.5467300415039"
+"46694400","229","229","229","77.84815216064453","77.84815216064453","77.84815216064453"
+"47513600","233","233","233","78.38223266601562","78.38223266601562","78.38223266601562"
+"48332800","237","237","237","79.05500030517578","79.05500030517578","79.05500030517578"
+"49152000","241","241","241","79.21051788330078","79.21051788330078","79.21051788330078"
+"49971200","245","245","245","79.89398956298828","79.89398956298828","79.89398956298828"
+"50790400","249","249","249","80.40926361083984","80.40926361083984","80.40926361083984"
+"51609600","253","253","253","80.85880279541016","80.85880279541016","80.85880279541016"
+"52428800","257","257","257","80.37973022460938","80.37973022460938","80.37973022460938"
+"53248000","261","261","261","81.46005249023438","81.46005249023438","81.46005249023438"
+"54067200","265","265","265","81.43396759033203","81.43396759033203","81.43396759033203"
+"54886400","269","269","269","82.16582489013672","82.16582489013672","82.16582489013672"
+"55705600","273","273","273","82.521484375","82.521484375","82.521484375"
+"56524800","277","277","277","82.39838409423828","82.39838409423828","82.39838409423828"
+"57344000","281","281","281","82.33724212646484","82.33724212646484","82.33724212646484"
+"58163200","285","285","285","82.12281799316406","82.12281799316406","82.12281799316406"
+"58982400","289","289","289","82.57845306396484","82.57845306396484","82.57845306396484"
+"59801600","293","293","293","83.1097183227539","83.1097183227539","83.1097183227539"
+"60620800","297","297","297","84.41431427001953","84.41431427001953","84.41431427001953"
+"61440000","301","301","301","85.57048797607422","85.57048797607422","85.57048797607422"
+"62259200","305","305","305","86.07222747802734","86.07222747802734","86.07222747802734"
+"63078400","309","309","309","87.8832778930664","87.8832778930664","87.8832778930664"
+"63897600","313","313","313","87.98388671875","87.98388671875","87.98388671875"
+"64716800","317","317","317","88.31554412841797","88.31554412841797","88.31554412841797"
+"65536000","321","321","321","88.65139770507812","88.65139770507812","88.65139770507812"
+"66355200","325","325","325","88.98595428466797","88.98595428466797","88.98595428466797"
+"67174400","329","329","329","89.50712585449219","89.50712585449219","89.50712585449219"
+"67993600","333","333","333","90.13626098632812","90.13626098632812","90.13626098632812"
+"68812800","337","337","337","90.00422668457031","90.00422668457031","90.00422668457031"
+"69632000","341","341","341","90.47052764892578","90.47052764892578","90.47052764892578"
+"70451200","345","345","345","91.13899993896484","91.13899993896484","91.13899993896484"
+"71270400","349","349","349","90.34095764160156","90.34095764160156","90.34095764160156"
+"72089600","353","353","353","91.73001861572266","91.73001861572266","91.73001861572266"
+"72908800","357","357","357","92.36653900146484","92.36653900146484","92.36653900146484"
+"73728000","361","361","361","93.05995178222656","93.05995178222656","93.05995178222656"
+"74547200","365","365","365","93.31439971923828","93.31439971923828","93.31439971923828"
+"75366400","369","369","369","93.721923828125","93.721923828125","93.721923828125"
+"76185600","373","373","373","94.33381652832031","94.33381652832031","94.33381652832031"
+"77004800","377","377","377","95.08702850341797","95.08702850341797","95.08702850341797"
+"77824000","381","381","381","96.91255950927734","96.91255950927734","96.91255950927734"
+"78643200","385","385","385","98.64586639404297","98.64586639404297","98.64586639404297"
+"79462400","389","389","389","101.00004577636719","101.00004577636719","101.00004577636719"
+"80281600","393","393","393","104.25716400146484","104.25716400146484","104.25716400146484"
+"81100800","397","397","397","106.15159606933594","106.15159606933594","106.15159606933594"
+"81920000","401","401","401","105.84529113769531","105.84529113769531","105.84529113769531"
+"82739200","405","405","405","108.822021484375","108.822021484375","108.822021484375"
+"83558400","409","409","409","107.58392333984375","107.58392333984375","107.58392333984375"
+"84377600","413","413","413","108.7061767578125","108.7061767578125","108.7061767578125"
+"85196800","417","417","417","108.8290023803711","108.8290023803711","108.8290023803711"
+"86016000","421","421","421","110.257080078125","110.257080078125","110.257080078125"
+"86835200","425","425","425","110.03636169433594","110.03636169433594","110.03636169433594"
+"87654400","429","429","429","110.42456817626953","110.42456817626953","110.42456817626953"
+"88473600","433","433","433","110.46240234375","110.46240234375","110.46240234375"
+"89292800","437","437","437","110.53307342529297","110.53307342529297","110.53307342529297"
+"90112000","441","441","441","110.5341796875","110.5341796875","110.5341796875"
+"90931200","445","445","445","110.4532699584961","110.4532699584961","110.4532699584961"
+"91750400","449","449","449","110.55850982666016","110.55850982666016","110.55850982666016"
+"92569600","453","453","453","110.45596313476562","110.45596313476562","110.45596313476562"
+"93388800","457","457","457","110.50789642333984","110.50789642333984","110.50789642333984"
+"94208000","461","461","461","110.50423431396484","110.50423431396484","110.50423431396484"
+"95027200","465","465","465","110.63358306884766","110.63358306884766","110.63358306884766"
+"95846400","469","469","469","109.98017120361328","109.98017120361328","109.98017120361328"
+"96665600","473","473","473","110.89254760742188","110.89254760742188","110.89254760742188"
+"97484800","477","477","477","110.84244537353516","110.84244537353516","110.84244537353516"
+"98304000","481","481","481","110.84843444824219","110.84843444824219","110.84843444824219"
+"99123200","485","485","485","110.93870544433594","110.93870544433594","110.93870544433594"
+"99942400","489","489","489","110.77571868896484","110.77571868896484","110.77571868896484"
+"100761600","493","493","493","110.82785034179688","110.82785034179688","110.82785034179688"
+"101580800","497","497","497","110.77915954589844","110.77915954589844","110.77915954589844"
+"102400000","501","501","501","110.85020446777344","110.85020446777344","110.85020446777344"
+"103219200","505","505","505","110.82056427001953","110.82056427001953","110.82056427001953"
+"104038400","509","509","509","110.78627014160156","110.78627014160156","110.78627014160156"
+"104857600","513","513","513","110.69759368896484","110.69759368896484","110.69759368896484"
+"105676800","517","517","517","110.74956512451172","110.74956512451172","110.74956512451172"
+"106496000","521","521","521","110.75735473632812","110.75735473632812","110.75735473632812"
+"107315200","525","525","525","110.80030059814453","110.80030059814453","110.80030059814453"
+"108134400","529","529","529","110.71249389648438","110.71249389648438","110.71249389648438"
+"108953600","533","533","533","110.70784759521484","110.70784759521484","110.70784759521484"
+"109772800","537","537","537","110.73592376708984","110.73592376708984","110.73592376708984"
+"110592000","541","541","541","110.73344421386719","110.73344421386719","110.73344421386719"
+"111411200","545","545","545","110.70268249511719","110.70268249511719","110.70268249511719"
+"112230400","549","549","549","110.70188903808594","110.70188903808594","110.70188903808594"
+"113049600","553","553","553","110.82147979736328","110.82147979736328","110.82147979736328"
+"113868800","557","557","557","110.80201721191406","110.80201721191406","110.80201721191406"
+"114688000","561","561","561","110.82105255126953","110.82105255126953","110.82105255126953"
+"115507200","565","565","565","110.78156280517578","110.78156280517578","110.78156280517578"
+"116326400","569","569","569","110.81396484375","110.81396484375","110.81396484375"
+"117145600","573","573","573","110.77930450439453","110.77930450439453","110.77930450439453"
+"117964800","577","577","577","110.7258071899414","110.7258071899414","110.7258071899414"
+"118784000","581","581","581","110.83123016357422","110.83123016357422","110.83123016357422"
+"119603200","585","585","585","110.73233032226562","110.73233032226562","110.73233032226562"
+"120422400","589","589","589","110.80208587646484","110.80208587646484","110.80208587646484"
+"121241600","593","593","593","110.69791412353516","110.69791412353516","110.69791412353516"
+"122060800","597","597","597","110.66498565673828","110.66498565673828","110.66498565673828"
+"122880000","601","601","601","110.74213409423828","110.74213409423828","110.74213409423828"
+"123699200","605","605","605","110.70230102539062","110.70230102539062","110.70230102539062"
+"124518400","609","609","609","110.68431091308594","110.68431091308594","110.68431091308594"
+"125337600","613","613","613","110.72357940673828","110.72357940673828","110.72357940673828"
+"126156800","617","617","617","110.73878479003906","110.73878479003906","110.73878479003906"
+"126976000","621","621","621","110.78778076171875","110.78778076171875","110.78778076171875"
+"127795200","625","625","625","110.7831039428711","110.7831039428711","110.7831039428711"
+"128614400","629","629","629","110.72936248779297","110.72936248779297","110.72936248779297"
+"129433600","633","633","633","110.75981903076172","110.75981903076172","110.75981903076172"
+"130252800","637","637","637","110.7753677368164","110.7753677368164","110.7753677368164"
+"131072000","641","641","641","110.66571807861328","110.66571807861328","110.66571807861328"
+"131891200","645","645","645","110.86940002441406","110.86940002441406","110.86940002441406"
+"132710400","649","649","649","110.3696060180664","110.3696060180664","110.3696060180664"
+"133529600","653","653","653","110.90158081054688","110.90158081054688","110.90158081054688"
+"134348800","657","657","657","110.8233642578125","110.8233642578125","110.8233642578125"
+"135168000","661","661","661","110.92154693603516","110.92154693603516","110.92154693603516"
+"135987200","665","665","665","110.96006774902344","110.96006774902344","110.96006774902344"
+"136806400","669","669","669","110.95464324951172","110.95464324951172","110.95464324951172"
+"137625600","673","673","673","111.09141540527344","111.09141540527344","111.09141540527344"
+"138444800","677","677","677","111.0863037109375","111.0863037109375","111.0863037109375"
+"139264000","681","681","681","111.18468475341797","111.18468475341797","111.18468475341797"
+"140083200","685","685","685","111.18415832519531","111.18415832519531","111.18415832519531"
+"140902400","689","689","689","111.17858123779297","111.17858123779297","111.17858123779297"
+"141721600","693","693","693","111.18983459472656","111.18983459472656","111.18983459472656"
+"142540800","697","697","697","110.33888244628906","110.33888244628906","110.33888244628906"
+"143360000","701","701","701","110.50321197509766","110.50321197509766","110.50321197509766"
+"144179200","705","705","705","111.21772003173828","111.21772003173828","111.21772003173828"
+"144998400","709","709","709","111.2286605834961","111.2286605834961","111.2286605834961"
+"145817600","713","713","713","111.16268920898438","111.16268920898438","111.16268920898438"
+"146636800","717","717","717","111.27171325683594","111.27171325683594","111.27171325683594"
+"147456000","721","721","721","111.22493743896484","111.22493743896484","111.22493743896484"
+"148275200","725","725","725","110.67684936523438","110.67684936523438","110.67684936523438"
+"149094400","729","729","729","111.26483917236328","111.26483917236328","111.26483917236328"
+"149913600","733","733","733","111.3096923828125","111.3096923828125","111.3096923828125"
+"150732800","737","737","737","111.32949829101562","111.32949829101562","111.32949829101562"
+"151552000","741","741","741","111.29817199707031","111.29817199707031","111.29817199707031"
+"152371200","745","745","745","111.36493682861328","111.36493682861328","111.36493682861328"
+"153190400","749","749","749","111.47444915771484","111.47444915771484","111.47444915771484"
+"154009600","753","753","753","111.39006805419922","111.39006805419922","111.39006805419922"
+"154828800","757","757","757","110.8421630859375","110.8421630859375","110.8421630859375"
+"155648000","761","761","761","111.31809997558594","111.31809997558594","111.31809997558594"
+"156467200","765","765","765","111.32988739013672","111.32988739013672","111.32988739013672"
+"157286400","769","769","769","111.32363891601562","111.32363891601562","111.32363891601562"
+"158105600","773","773","773","111.32723236083984","111.32723236083984","111.32723236083984"
+"158924800","777","777","777","111.32120513916016","111.32120513916016","111.32120513916016"
+"159744000","781","781","781","111.4076919555664","111.4076919555664","111.4076919555664"
+"160563200","785","785","785","111.3929443359375","111.3929443359375","111.3929443359375"
+"161382400","789","789","789","111.36479949951172","111.36479949951172","111.36479949951172"
+"162201600","793","793","793","111.30738830566406","111.30738830566406","111.30738830566406"
+"163020800","797","797","797","111.37686157226562","111.37686157226562","111.37686157226562"
+"163840000","801","801","801","111.47047424316406","111.47047424316406","111.47047424316406"
+"164659200","805","805","805","111.44316101074219","111.44316101074219","111.44316101074219"
+"165478400","809","809","809","111.5976333618164","111.5976333618164","111.5976333618164"
+"166297600","813","813","813","111.51726531982422","111.51726531982422","111.51726531982422"
+"167116800","817","817","817","111.55801391601562","111.55801391601562","111.55801391601562"
+"167936000","821","821","821","111.55133819580078","111.55133819580078","111.55133819580078"
+"168755200","825","825","825","111.57056427001953","111.57056427001953","111.57056427001953"
+"169574400","829","829","829","111.56879425048828","111.56879425048828","111.56879425048828"
+"170393600","833","833","833","111.571533203125","111.571533203125","111.571533203125"
+"171212800","837","837","837","111.55996704101562","111.55996704101562","111.55996704101562"
+"172032000","841","841","841","111.58295440673828","111.58295440673828","111.58295440673828"
+"172851200","845","845","845","111.58222198486328","111.58222198486328","111.58222198486328"
+"173670400","849","849","849","111.02129364013672","111.02129364013672","111.02129364013672"
+"174489600","853","853","853","111.5956802368164","111.5956802368164","111.5956802368164"
+"175308800","857","857","857","111.61061096191406","111.61061096191406","111.61061096191406"
+"176128000","861","861","861","111.59146118164062","111.59146118164062","111.59146118164062"
+"176947200","865","865","865","111.63449096679688","111.63449096679688","111.63449096679688"
+"177766400","869","869","869","111.56141662597656","111.56141662597656","111.56141662597656"
+"178585600","873","873","873","111.6049575805664","111.6049575805664","111.6049575805664"
+"179404800","877","877","877","111.61854553222656","111.61854553222656","111.61854553222656"
+"180224000","881","881","881","111.5946044921875","111.5946044921875","111.5946044921875"
+"181043200","885","885","885","111.54036712646484","111.54036712646484","111.54036712646484"
+"181862400","889","889","889","111.55754852294922","111.55754852294922","111.55754852294922"
+"182681600","893","893","893","111.56049346923828","111.56049346923828","111.56049346923828"
+"183500800","897","897","897","111.58182525634766","111.58182525634766","111.58182525634766"
+"184320000","901","901","901","111.61589813232422","111.61589813232422","111.61589813232422"
+"185139200","905","905","905","111.57329559326172","111.57329559326172","111.57329559326172"
+"185958400","909","909","909","111.52533721923828","111.52533721923828","111.52533721923828"
+"186777600","913","913","913","111.57328033447266","111.57328033447266","111.57328033447266"
+"187596800","917","917","917","111.52156066894531","111.52156066894531","111.52156066894531"
+"188416000","921","921","921","111.591064453125","111.591064453125","111.591064453125"
+"189235200","925","925","925","110.59596252441406","110.59596252441406","110.59596252441406"
+"190054400","929","929","929","111.06100463867188","111.06100463867188","111.06100463867188"
+"190873600","933","933","933","111.54386138916016","111.54386138916016","111.54386138916016"
+"191692800","937","937","937","111.58763122558594","111.58763122558594","111.58763122558594"
+"192512000","941","941","941","111.61695861816406","111.61695861816406","111.61695861816406"
+"193331200","945","945","945","111.53097534179688","111.53097534179688","111.53097534179688"
+"194150400","949","949","949","110.97347259521484","110.97347259521484","110.97347259521484"
+"194969600","953","953","953","111.61117553710938","111.61117553710938","111.61117553710938"
+"195788800","957","957","957","111.62594604492188","111.62594604492188","111.62594604492188"
+"196608000","961","961","961","111.55712890625","111.55712890625","111.55712890625"
+"197427200","965","965","965","111.58842468261719","111.58842468261719","111.58842468261719"
+"198246400","969","969","969","111.58175659179688","111.58175659179688","111.58175659179688"
+"199065600","973","973","973","111.60126495361328","111.60126495361328","111.60126495361328"
+"199884800","977","977","977","111.61060333251953","111.61060333251953","111.61060333251953"
+"200704000","981","981","981","111.55136108398438","111.55136108398438","111.55136108398438"
+"201523200","985","985","985","111.5947036743164","111.5947036743164","111.5947036743164"
+"202342400","989","989","989","111.61116027832031","111.61116027832031","111.61116027832031"
+"203161600","993","993","993","111.6195297241211","111.6195297241211","111.6195297241211"
+"203980800","997","997","997","111.63127899169922","111.63127899169922","111.63127899169922"
+"204800000","1001","1001","1001","111.62285614013672","111.62285614013672","111.62285614013672"
+"205619200","1005","1005","1005","111.69459533691406","111.69459533691406","111.69459533691406"
+"206438400","1009","1009","1009","111.72270202636719","111.72270202636719","111.72270202636719"
+"207257600","1013","1013","1013","111.68287658691406","111.68287658691406","111.68287658691406"
+"208076800","1017","1017","1017","111.71575927734375","111.71575927734375","111.71575927734375"
+"208896000","1021","1021","1021","111.69246673583984","111.69246673583984","111.69246673583984"
+"209715200","1025","1025","1025","111.70613098144531","111.70613098144531","111.70613098144531"
+"210534400","1029","1029","1029","111.69783782958984","111.69783782958984","111.69783782958984"
+"211353600","1033","1033","1033","111.71296691894531","111.71296691894531","111.71296691894531"
+"212172800","1037","1037","1037","111.67806243896484","111.67806243896484","111.67806243896484"
+"212992000","1041","1041","1041","111.66828155517578","111.66828155517578","111.66828155517578"
+"213811200","1045","1045","1045","111.66458129882812","111.66458129882812","111.66458129882812"
+"214630400","1049","1049","1049","111.68214416503906","111.68214416503906","111.68214416503906"
+"215449600","1053","1053","1053","111.67250061035156","111.67250061035156","111.67250061035156"
+"216268800","1057","1057","1057","111.64888763427734","111.64888763427734","111.64888763427734"
+"217088000","1061","1061","1061","111.61158752441406","111.61158752441406","111.61158752441406"
+"217907200","1065","1065","1065","111.64892578125","111.64892578125","111.64892578125"
+"218726400","1069","1069","1069","111.65438079833984","111.65438079833984","111.65438079833984"
+"219545600","1073","1073","1073","111.62885284423828","111.62885284423828","111.62885284423828"
+"220364800","1077","1077","1077","111.66571044921875","111.66571044921875","111.66571044921875"
+"221184000","1081","1081","1081","111.09687042236328","111.09687042236328","111.09687042236328"
+"222003200","1085","1085","1085","111.58106994628906","111.58106994628906","111.58106994628906"
+"222822400","1089","1089","1089","111.64144134521484","111.64144134521484","111.64144134521484"
+"223641600","1093","1093","1093","111.6723403930664","111.6723403930664","111.6723403930664"
+"224460800","1097","1097","1097","110.99393463134766","110.99393463134766","110.99393463134766"
+"225280000","1101","1101","1101","111.66114044189453","111.66114044189453","111.66114044189453"
+"226099200","1105","1105","1105","111.69221496582031","111.69221496582031","111.69221496582031"
+"226918400","1109","1109","1109","111.68419647216797","111.68419647216797","111.68419647216797"
+"227737600","1113","1113","1113","111.63948059082031","111.63948059082031","111.63948059082031"
+"228556800","1117","1117","1117","111.63236236572266","111.63236236572266","111.63236236572266"
+"229376000","1121","1121","1121","111.64939880371094","111.64939880371094","111.64939880371094"
+"230195200","1125","1125","1125","111.62156677246094","111.62156677246094","111.62156677246094"
+"231014400","1129","1129","1129","111.57876586914062","111.57876586914062","111.57876586914062"
+"231833600","1133","1133","1133","111.6370849609375","111.6370849609375","111.6370849609375"
+"232652800","1137","1137","1137","111.10572814941406","111.10572814941406","111.10572814941406"
+"233472000","1141","1141","1141","111.6113052368164","111.6113052368164","111.6113052368164"
+"234291200","1145","1145","1145","111.61180114746094","111.61180114746094","111.61180114746094"
+"235110400","1149","1149","1149","111.64984130859375","111.64984130859375","111.64984130859375"
+"235929600","1153","1153","1153","111.65251922607422","111.65251922607422","111.65251922607422"
+"236748800","1157","1157","1157","111.62240600585938","111.62240600585938","111.62240600585938"
+"237568000","1161","1161","1161","111.63762664794922","111.63762664794922","111.63762664794922"
+"238387200","1165","1165","1165","111.6535415649414","111.6535415649414","111.6535415649414"
+"239206400","1169","1169","1169","111.65385437011719","111.65385437011719","111.65385437011719"
+"240025600","1173","1173","1173","111.61310577392578","111.61310577392578","111.61310577392578"
+"240844800","1177","1177","1177","111.61869049072266","111.61869049072266","111.61869049072266"
+"241664000","1181","1181","1181","111.58061218261719","111.58061218261719","111.58061218261719"
+"242483200","1185","1185","1185","111.73097229003906","111.73097229003906","111.73097229003906"
+"243302400","1189","1189","1189","111.52400970458984","111.52400970458984","111.52400970458984"
+"244121600","1193","1193","1193","111.55033874511719","111.55033874511719","111.55033874511719"
+"244940800","1197","1197","1197","111.55796813964844","111.55796813964844","111.55796813964844"
\ No newline at end of file
diff --git a/isaacgymenvs/tasks/drone_racing/demos/urdf/kingfisher_250.urdf b/isaacgymenvs/tasks/drone_racing/demos/urdf/kingfisher_250.urdf
new file mode 100644
index 000000000..0280764bb
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/demos/urdf/kingfisher_250.urdf
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/__init__.py b/isaacgymenvs/tasks/drone_racing/drone_sim/__init__.py
new file mode 100644
index 000000000..b1db4b6ff
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/__init__.py
@@ -0,0 +1,8 @@
+"""
+Package for drone simulation.
+"""
+
+from .controllers import *
+from .models import *
+from .presets import *
+from .utils import *
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/controllers/__init__.py b/isaacgymenvs/tasks/drone_racing/drone_sim/controllers/__init__.py
new file mode 100644
index 000000000..de949498c
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/controllers/__init__.py
@@ -0,0 +1 @@
+from .simple_betaflight import SimpleBetaflightParams, SimpleBetaflight
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/controllers/simple_betaflight.py b/isaacgymenvs/tasks/drone_racing/drone_sim/controllers/simple_betaflight.py
new file mode 100644
index 000000000..f730e3fc5
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/controllers/simple_betaflight.py
@@ -0,0 +1,357 @@
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+import torch
+
+from ..utils import FirstOrderLowPassFilterParams, FirstOrderLowPassFilter
+
+
+@dataclass
+class SimpleBetaflightParams:
+ # number of envs in parallel
+ num_envs: int = 64
+
+ # tensor device
+ device: str = "cuda"
+
+ # control period (seconds)
+ dt: float = 1 / 500
+
+ # stick position to angular rates (deg/s), for RPY
+ # the pilot can adjust their Rates to suit their flying style
+ # racers prefer a more linear curve with a maximum turn rate of around 550-650 deg/s
+ # freestyle typically uses a combination of a soft center region with high maximum turn rates (850-1200 deg/s)
+ # cinematic flying will be smoother with a flatter center region
+ center_sensitivity: List[float] = field(
+ default_factory=lambda: [100.0, 100.0, 100.0]
+ )
+ max_rate: List[float] = field(default_factory=lambda: [670.0, 670.0, 670.0])
+ rate_expo: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.0])
+
+ # PID (rad) for RPY
+ kp: List[float] = field(default_factory=lambda: [150.0, 150.0, 100.0])
+ ki: List[float] = field(default_factory=lambda: [2.0, 2.0, 15.0])
+ kd: List[float] = field(default_factory=lambda: [2.0, 2.0, 0.0])
+ kff: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.0])
+ iterm_lim: List[float] = field(default_factory=lambda: [10.0, 10.0, 10.0])
+ pid_sum_lim: List[float] = field(default_factory=lambda: [1000.0, 1000.0, 1000.0])
+
+ # d-term low pass filter cutoff frequency in Hz
+ dterm_lpf_cutoff: float = 200
+
+ # rotor positions in body FRD frame
+ # all rotors are assumed to only produce thrust along the body-z axis
+ # so z component does not matter anyway
+ # rotor indexing: https://betaflight.com/docs/wiki/configurator/motors-tab
+ rotors_x: List[float] = field(
+ default_factory=lambda: [-0.078665, 0.078665, -0.078665, 0.078665]
+ )
+ rotors_y: List[float] = field(
+ default_factory=lambda: [0.097143, 0.097143, -0.097143, -0.097143]
+ )
+ rotors_dir: List[int] = field(default_factory=lambda: [1, -1, -1, 1])
+ pid_sum_mixer_scale: float = 1000.0
+
+ # output idle
+ output_idle: float = 0.05
+
+ # throttle boost
+ throttle_boost_gain: float = 10.0
+ throttle_boost_freq: float = 50.0
+
+ # thrust linearization
+ thrust_linearization_gain: float = 0.4
+
+
+class SimpleBetaflight:
+ """
+ Simplified Betaflight rate PID control.
+
+ I/O:
+ - In: normalized stick positions in AETR channels, from -1 to 1.
+ - Out: normalized rotor command of the rotors (u from 0 to 1).
+
+ Implemented:
+ - Actual rates mapping from AETR to angular velocity.
+ - Angular rate PID with error-derivative I-term, D-term LPF, and FF based on setpoint value.
+ - Mixing supporting customizable airframe.
+ - AirMode using betaflight default (LEGACY) mixer adjustment.
+ - Throttle Boost: throttle command is boosted by high-frequency component of itself.
+ - Thrust Linearization: boosting output at low throttle, and lowering it at high throttle.
+
+ Not implemented:
+ - Antigravity: boosting PI during fast throttle movement.
+ - Throttle PID Attenuation: reducing PID at high throttle to cope with motor noise.
+ - I-term relax: disabling I-term calculation during fast maneuvers.
+ - Dynamic damping: higher D-term coefficient during fast maneuvers.
+ - Integrated yaw: integrating PID sum about z-axis before putting it into the mixer.
+ - Absolute control: for better tracking to sticks, particularly during rotations involving fast yaw movement.
+ - Sensor noise (gyro noise) and additional filtering (gyro filters, notch filters).
+ - Dynamic Idle: controlling the minimum command level using PID to prevent motor-ESC de-synchronization.
+ - Battery voltage compensation: for consistent response throughout a battery run.
+
+ Reference:
+ - [1] https://betaflight.com/docs/wiki
+ - [2] https://www.desmos.com/calculator/r5pkxlxhtb
+ - [3] https://en.wikipedia.org/wiki/Low-pass_filter
+ """
+
+ def __init__(self, params: SimpleBetaflightParams):
+ self.params = params
+ self.all_env_id = torch.arange(params.num_envs, device=params.device)
+
+ # input
+ self.command = torch.zeros(params.num_envs, 4, device=params.device)
+
+ # rate
+ self.center_sensitivity = torch.tensor(
+ params.center_sensitivity, device=params.device
+ )
+ self.max_rate = torch.tensor(params.max_rate, device=params.device)
+ self.rate_expo = torch.tensor(params.rate_expo, device=params.device)
+
+ # pid
+ self.kp = torch.tensor(params.kp, device=params.device)
+ self.ki = torch.tensor(params.ki, device=params.device)
+ self.kd = torch.tensor(params.kd, device=params.device)
+ self.kff = torch.tensor(params.kff, device=params.device)
+ self.iterm_lim = torch.tensor(params.iterm_lim, device=params.device)
+ self.pid_sum_lim = torch.tensor(params.pid_sum_lim, device=params.device)
+ self.int_err_ang_vel = torch.zeros(params.num_envs, 3, device=params.device)
+ self.last_ang_vel = torch.zeros(params.num_envs, 3, device=params.device)
+ dterm_lpf_params = FirstOrderLowPassFilterParams()
+ dterm_lpf_params.device = params.device
+ dterm_lpf_params.dim = self.last_ang_vel.size()
+ dterm_lpf_params.dt = params.dt
+ dterm_lpf_params.cutoff_frequency = params.dterm_lpf_cutoff
+ dterm_lpf_params.initial_value = 0.0
+ self.dterm_lpf = FirstOrderLowPassFilter(dterm_lpf_params)
+
+ # mixing table
+ if not (
+ len(params.rotors_x) == len(params.rotors_y)
+ and len(params.rotors_y) == len(params.rotors_dir)
+ ):
+ raise ValueError("Rotors configuration error.")
+ self.num_rotors = len(params.rotors_x)
+ rotors_x_abs = [abs(item) for item in params.rotors_x]
+ rotors_y_abs = [abs(item) for item in params.rotors_y]
+ scale = max(max(rotors_x_abs), max(rotors_y_abs))
+ mix_table_data = []
+ for i in range(self.num_rotors):
+ mix_table_data.append(
+ [
+ 1, # throttle
+ -params.rotors_y[i] / scale, # roll
+ params.rotors_x[i] / scale, # pitch
+ -params.rotors_dir[i], # yaw
+ ]
+ )
+ self.mix_table = torch.tensor(mix_table_data, device=params.device)
+
+ # throttle boost
+ throttle_boost_lpf_params = FirstOrderLowPassFilterParams()
+ throttle_boost_lpf_params.device = params.device
+ throttle_boost_lpf_params.dim = torch.Size([params.num_envs])
+ throttle_boost_lpf_params.dt = params.dt
+ throttle_boost_lpf_params.cutoff_frequency = params.throttle_boost_freq
+ throttle_boost_lpf_params.initial_value = 0.0
+ self.throttle_boost_lpf = FirstOrderLowPassFilter(throttle_boost_lpf_params)
+
+ # thrust linearization
+ self.thrust_linearization_throttle_compensation = (
+ params.thrust_linearization_gain - 0.5 * params.thrust_linearization_gain**2
+ )
+
+ def reset(self, env_id: torch.Tensor = None):
+ if env_id is None:
+ env_id = self.all_env_id
+
+ self.int_err_ang_vel[env_id, ...] = 0
+ self.last_ang_vel[env_id, ...] = 0
+ self.dterm_lpf.reset(env_id)
+ self.throttle_boost_lpf.reset(env_id)
+
+ def set_command(self, command: torch.Tensor):
+ """
+ Sets the command (stick positions).
+
+ Args:
+ command: normalized stick positions in tensor shaped (num_envs, 4).
+ """
+
+ self.command[:] = command
+
+ def compute(self, ang_vel: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Runs main controller logic.
+
+ Args:
+ ang_vel: the current sensed angular velocity in rad/s, shaped (num_envs, 3).
+
+ Returns:
+ - Desired angular velocity in rad/s, shaped (num_envs, 3).
+ - Normalized rotor command u[0, 1], shaped (num_envs, num_rotors).
+ """
+
+ # desired angular velocity
+ des_ang_vel = _compute_input_map_script(
+ command=self.command,
+ center_sensitivity=self.center_sensitivity,
+ max_rate=self.max_rate,
+ rate_expo=self.rate_expo,
+ )
+
+ # angular velocity error
+ err_ang_vel = des_ang_vel - ang_vel
+
+ # integral of error rate, and limit the integral amount
+ self.int_err_ang_vel += err_ang_vel
+ self.int_err_ang_vel.clamp_(min=-self.iterm_lim, max=self.iterm_lim)
+
+ # derivative term
+ d_ang_vel = self.dterm_lpf.get_output()
+
+ pid_sum = _compute_pid_sum_script(
+ kp=self.kp,
+ ki=self.ki,
+ kd=self.kd,
+ kff=self.kff,
+ pid_sum_lim=self.pid_sum_lim,
+ pid_sum_mixer_scale=self.params.pid_sum_mixer_scale,
+ err_ang_vel=err_ang_vel,
+ int_err_ang_vel=self.int_err_ang_vel,
+ d_ang_vel=d_ang_vel,
+ des_ang_vel=des_ang_vel,
+ )
+
+ # update dterm low-pass filter
+ self.dterm_lpf.update((ang_vel - self.last_ang_vel) / self.params.dt)
+ self.last_ang_vel[:] = ang_vel
+
+ # mixing
+ cmd_t = (self.command[:, 2] + 1) / 2 # (num_envs, )
+ throttle_low_freq_component = self.throttle_boost_lpf.get_output()
+
+ u = _compute_mixing_script(
+ mix_table=self.mix_table,
+ throttle_boost_gain=self.params.throttle_boost_gain,
+ thrust_linearization_throttle_compensation=self.thrust_linearization_throttle_compensation,
+ thrust_linearization_gain=self.params.thrust_linearization_gain,
+ output_idle=self.params.output_idle,
+ pid_sum=pid_sum,
+ cmd_t=cmd_t,
+ throttle_low_freq_component=throttle_low_freq_component,
+ )
+
+ self.throttle_boost_lpf.update(cmd_t)
+
+ # return results
+ return des_ang_vel, u
+
+
+@torch.jit.script
+def _compute_input_map_script(
+ command: torch.Tensor,
+ center_sensitivity: torch.Tensor,
+ max_rate: torch.Tensor,
+ rate_expo: torch.Tensor,
+) -> torch.Tensor:
+ """
+ Maps stick positions to desired body angular velocity:
+ https://betaflight.com/docs/wiki/guides/current/Rate-Calculator.
+
+ Assuming FRD body frame:
+ channel A -> roll (body x),
+ channel E -> pitch (body y),
+ channel R -> yaw (body z).
+
+ Let x[-1, 1] be the stick position, d the center sensitivity, f the max rate, g the expo,
+ desired body rate = sgn(x) * ( d|x| + (f-d) * ( (1-g)x^2 + gx^6 ) )
+ """
+
+ cmd_aer = command[:, [0, 1, 3]]
+ des_body_rates = torch.sgn(cmd_aer) * (
+ center_sensitivity * torch.abs(cmd_aer)
+ + (max_rate - center_sensitivity)
+ * ((1 - rate_expo) * torch.pow(cmd_aer, 2) + rate_expo * torch.pow(cmd_aer, 6))
+ )
+ return torch.deg2rad(des_body_rates)
+
+
+@torch.jit.script
+def _compute_pid_sum_script(
+ kp: torch.Tensor,
+ ki: torch.Tensor,
+ kd: torch.Tensor,
+ kff: torch.Tensor,
+ pid_sum_lim: torch.Tensor,
+ pid_sum_mixer_scale: float,
+ err_ang_vel: torch.Tensor,
+ int_err_ang_vel: torch.Tensor,
+ d_ang_vel: torch.Tensor,
+ des_ang_vel: torch.Tensor,
+) -> torch.Tensor:
+ # PID sum and clamp
+ pid_sum = (
+ kp * err_ang_vel + ki * int_err_ang_vel - kd * d_ang_vel + kff * des_ang_vel
+ )
+ pid_sum.clamp_(min=-pid_sum_lim, max=pid_sum_lim)
+
+ # scale the PID sum before mixing
+ pid_sum /= pid_sum_mixer_scale
+
+ return pid_sum
+
+
+@torch.jit.script
+def _compute_mixing_script(
+ mix_table: torch.Tensor,
+ throttle_boost_gain: float,
+ thrust_linearization_throttle_compensation: float,
+ thrust_linearization_gain: float,
+ output_idle: float,
+ pid_sum: torch.Tensor,
+ cmd_t: torch.Tensor,
+ throttle_low_freq_component: torch.Tensor,
+):
+ # find desired motor command from RPY PID, shape (num_envs, num_rotors)
+ rpy_u = torch.matmul(mix_table[:, 1:], pid_sum.T).T
+
+ # u range for each environment, shape (num_envs, )
+ rpy_u_max = torch.max(rpy_u, 1).values
+ rpy_u_min = torch.min(rpy_u, 1).values
+ rpy_u_range = rpy_u_max - rpy_u_min
+
+ # normalization factor
+ norm_factor = 1 / rpy_u_range # (num_envs, )
+ norm_factor.clamp_(max=1.0)
+
+ # mixer adjustment
+ rpy_u_normalized = norm_factor.view(-1, 1) * rpy_u
+ rpy_u_normalized_max = norm_factor * rpy_u_max
+ rpy_u_normalized_min = norm_factor * rpy_u_min
+
+ # throttle boost
+ throttle_high_freq_component = cmd_t - throttle_low_freq_component
+ throttle = cmd_t + throttle_boost_gain * throttle_high_freq_component
+ throttle.clamp_(min=0.0, max=1.0)
+
+ # thrust linearization step 1
+ throttle /= 1 + thrust_linearization_throttle_compensation * torch.pow(
+ 1 - throttle, 2
+ )
+
+ # constrain throttle so it won't clip any outputs
+ throttle.clamp_(min=-rpy_u_normalized_min, max=(1 - rpy_u_normalized_max))
+
+ # synthesize output
+ u_rpy_t = rpy_u_normalized + throttle.view(-1, 1)
+
+ # thrust linearization step 2
+ u_rpy_t *= 1 + thrust_linearization_gain * torch.pow(1 - u_rpy_t, 2)
+
+ # calculate final u based on idle
+ u = output_idle + (1 - output_idle) * u_rpy_t
+
+ return u
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/models/__init__.py b/isaacgymenvs/tasks/drone_racing/drone_sim/models/__init__.py
new file mode 100644
index 000000000..5d1d9449d
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/models/__init__.py
@@ -0,0 +1,4 @@
+from .body_drag_poly import BodyDragPolyParams, BodyDragPoly
+from .propeller_poly import PropellerPolyParams, PropellerPoly
+from .rotor_poly_lag import RotorPolyLagParams, RotorPolyLag
+from .wrench_sum import WrenchSumParams, WrenchSum
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/models/body_drag_poly.py b/isaacgymenvs/tasks/drone_racing/drone_sim/models/body_drag_poly.py
new file mode 100644
index 000000000..18240b68e
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/models/body_drag_poly.py
@@ -0,0 +1,110 @@
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+import torch
+
+
+@dataclass
+class BodyDragPolyParams:
+ """
+ Default data source: https://agilicious.readthedocs.io/en/latest/hardware/overview.html
+ """
+
+ # number of parallel envs
+ num_envs: int = 64
+
+ # device to host tensor
+ device: str = "cuda"
+
+ # ISA air density [kg / m^3]
+ air_density: float = 1.204
+
+ # area pushing against air in body xyz direction (translational)
+ a_trans: List[float] = field(default_factory=lambda: [1.5e-2, 1.5e-2, 3.0e-2])
+
+ # quadratic translational drag coefficient in body xyz plane
+ k_trans_quadratic: List[float] = field(default_factory=lambda: [1.04, 1.04, 1.04])
+
+ # linear translational drag coefficient in body xyz plane
+ k_trans_linear: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.0])
+
+ # equivalent area for calculating rotational drag
+ a_rot: List[float] = field(default_factory=lambda: [1e-2, 1e-2, 1e-2])
+
+ # quadratic rotational drag coefficient on body xyz axis
+ k_rot_quadratic: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.0])
+
+ # linear rotational drag coefficient on body xyz axis
+ k_rot_linear: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.0])
+
+
+class BodyDragPoly:
+
+ def __init__(self, params: BodyDragPolyParams):
+ self.params = params
+
+ self.a_trans = torch.tensor(params.a_trans, device=params.device)
+ self.k_trans_quadratic = torch.tensor(
+ params.k_trans_quadratic, device=params.device
+ )
+ self.k_trans_linear = torch.tensor(params.k_trans_linear, device=params.device)
+
+ self.a_rot = torch.tensor(params.a_rot, device=params.device)
+ self.k_rot_quadratic = torch.tensor(
+ params.k_rot_quadratic, device=params.device
+ )
+ self.k_rot_linear = torch.tensor(params.k_rot_linear, device=params.device)
+
+ def compute(
+ self, lin_vel: torch.Tensor, ang_vel: torch.Tensor
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Main processing logic.
+
+ Args:
+ lin_vel: Linear velocity in body frame (num_envs, 3).
+ ang_vel: Angular velocity in body frame (num_envs, 3).
+
+ Returns:
+ - Drag force (num_envs, 3).
+ - Drag torque (num_envs, 3).
+ """
+
+ return _compute_script(
+ self.params.air_density,
+ self.a_trans,
+ self.k_trans_quadratic,
+ self.k_trans_linear,
+ self.a_rot,
+ self.k_rot_quadratic,
+ self.k_rot_linear,
+ lin_vel,
+ ang_vel,
+ )
+
+
+@torch.jit.script
+def _compute_script(
+ air_density: float,
+ a_trans: torch.Tensor,
+ k_trans_quadratic: torch.Tensor,
+ k_trans_linear: torch.Tensor,
+ a_rot: torch.Tensor,
+ k_rot_quadratic: torch.Tensor,
+ k_rot_linear: torch.Tensor,
+ lin_vel: torch.Tensor,
+ ang_vel: torch.Tensor,
+) -> Tuple[torch.Tensor, torch.Tensor]:
+ force = (
+ -0.5
+ * air_density
+ * a_trans
+ * (k_trans_quadratic * lin_vel * torch.abs(lin_vel) + k_trans_linear * lin_vel)
+ )
+ torque = (
+ -0.5
+ * air_density
+ * a_rot
+ * (k_rot_quadratic * ang_vel * torch.abs(ang_vel) + k_rot_linear * ang_vel)
+ )
+ return force, torque
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/models/propeller_poly.py b/isaacgymenvs/tasks/drone_racing/drone_sim/models/propeller_poly.py
new file mode 100644
index 000000000..912cd031d
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/models/propeller_poly.py
@@ -0,0 +1,88 @@
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+import torch
+
+
+@dataclass
+class PropellerPolyParams:
+ """
+ Default data source: https://store.tmotor.com/goods.php?id=1106
+ and https://agilicious.readthedocs.io/en/latest/hardware/overview.html
+ """
+
+ # number of parallel envs
+ num_envs: int = 64
+
+ # tensor device
+ device: str = "cuda"
+
+ # number of propellers per environment
+ num_props: int = 4
+
+ # propeller directions relative to body z axis (FRD)
+ prop_dir: List[int] = field(default_factory=lambda: [1, -1, -1, 1])
+
+ # quadratic coefficient for force calculation
+ k_force_quadratic: float = 2.1549e-08
+
+ # linear coefficient for force calculation
+ k_force_linear: float = -4.5101e-05
+
+ # quadratic coefficient for torque calculation
+ k_torque_quadratic: float = 2.1549e-08 * 0.022
+
+ # linear coefficient for torque calculation
+ k_torque_linear: float = -4.5101e-05 * 0.022
+
+
+class PropellerPoly:
+
+ def __init__(self, params: PropellerPolyParams):
+ self.params = params
+
+ self.torque_dir = -torch.tensor(params.prop_dir, device=params.device)
+
+ self.force = torch.zeros(
+ params.num_envs, params.num_props, 3, device=params.device
+ )
+ self.torque = torch.zeros(
+ params.num_envs, params.num_props, 3, device=params.device
+ )
+
+ def compute(self, rpm: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Main processing logic.
+
+ Args:
+ rpm: propeller RPM tensor in (num_envs, num_propellers).
+
+ Returns:
+ - Force caused by propeller in (num_envs, num_propellers, 3).
+ - Torque caused by propeller in (num_envs, num_propellers, 3).
+ """
+
+ self.force[:, :, 2], self.torque[:, :, 2] = _compute_script(
+ self.params.k_force_quadratic,
+ self.params.k_force_linear,
+ self.params.k_torque_quadratic,
+ self.params.k_torque_linear,
+ self.torque_dir,
+ rpm,
+ )
+
+ return self.force, self.torque
+
+
+@torch.jit.script
+def _compute_script(
+ k_force_quadratic: float,
+ k_force_linear: float,
+ k_torque_quadratic: float,
+ k_torque_linear: float,
+ torque_dir: torch.Tensor,
+ rpm: torch.Tensor,
+) -> Tuple[torch.Tensor, torch.Tensor]:
+ f = (-1) * (k_force_quadratic * torch.pow(rpm, 2) + k_force_linear * rpm)
+ t = (k_torque_quadratic * torch.pow(rpm, 2) + k_torque_linear * rpm) * torque_dir
+ return f, t
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/models/rotor_poly_lag.py b/isaacgymenvs/tasks/drone_racing/drone_sim/models/rotor_poly_lag.py
new file mode 100644
index 000000000..a5aa265c6
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/models/rotor_poly_lag.py
@@ -0,0 +1,146 @@
+import math
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+import torch
+
+from isaacgymenvs.utils.torch_jit_utils import quaternion_to_matrix
+
+
+@dataclass
+class RotorPolyLagParams:
+ """
+ Default data source: https://store.tmotor.com/goods.php?id=1106
+ and https://agilicious.readthedocs.io/en/latest/hardware/overview.html
+ """
+
+ # number of envs in parallel
+ num_envs: int = 64
+
+ # tensor device
+ device: str = "cuda"
+
+ # update period (seconds)
+ dt: float = 1 / 500
+
+ # number of rotors per env
+ num_rotors: int = 4
+
+ # rotor directions
+ rotors_dir: List[float] = field(default_factory=lambda: [1, -1, -1, 1])
+
+ # Time constant for rotor acceleration for first-order lag
+ spinup_time_constant: float = 0.033
+
+ # Time constant for rotor deceleration for first-order lag
+ slowdown_time_constant: float = 0.033
+
+ # Quadratic term of the polynomial model
+ k_rpm_quadratic: float = -13421.95
+
+ # Linear term of the polynomial model
+ k_rpm_linear: float = 37877.42
+
+ # The diagonal elements of the 3x3 diagonal inertia matrix
+ rotor_diagonal_inertia: List[float] = field(
+ default_factory=lambda: [0.0, 0.0, 9.3575e-6]
+ )
+
+ # The quaternion (w, x, y, z) representing the same rotation as the principal axes matrix
+ rotor_principle_axes_q: List[float] = field(
+ default_factory=lambda: [1.0, 0.0, 0.0, 0.0]
+ )
+
+
+class RotorPolyLag:
+
+ def __init__(self, params: RotorPolyLagParams):
+ self.params = params
+ self.all_env_id = torch.arange(params.num_envs, device=params.device)
+
+ # first-order lag param
+ self.alpha_spinup = math.exp(-params.dt / params.spinup_time_constant)
+ self.alpha_slowdown = math.exp(-params.dt / params.slowdown_time_constant)
+
+ # rotor direction tensor
+ self.rotor_dir = torch.tensor(params.rotors_dir, device=params.device)
+
+ # init inertia matrices
+ principle_axes_q = torch.tensor(
+ params.rotor_principle_axes_q, device=params.device
+ )
+ principle_axes = quaternion_to_matrix(principle_axes_q)
+ diagonal_inertia_mat = torch.diag(
+ torch.tensor(params.rotor_diagonal_inertia, device=params.device)
+ )
+ rotated_inertia_mat = principle_axes @ diagonal_inertia_mat @ principle_axes.T
+ self.rotor_inertia = torch.zeros(
+ params.num_envs, params.num_rotors, 3, 3, device=params.device
+ )
+ self.rotor_inertia[:] = rotated_inertia_mat
+
+ # init zero tensors
+ self.rpm = torch.zeros(params.num_envs, params.num_rotors, device=params.device)
+ self.rpm_ss = torch.zeros(
+ params.num_envs, params.num_rotors, device=params.device
+ )
+ self.omega_dot = torch.zeros(
+ params.num_envs, params.num_rotors, 3, device=params.device
+ )
+ self.force = torch.zeros(
+ params.num_envs, params.num_rotors, 3, device=params.device
+ )
+ self.torque = torch.zeros(
+ params.num_envs, params.num_rotors, 3, device=params.device
+ )
+
+ def reset(self, env_id: torch.Tensor = None):
+ if env_id is None:
+ env_id = self.all_env_id
+
+ self.rpm[env_id, ...] = 0
+ self.rpm_ss[env_id, ...] = 0
+ self.omega_dot[env_id, ...] = 0
+ self.force[env_id, ...] = 0
+ self.torque[env_id, ...] = 0
+
+ def compute(
+ self, command: torch.Tensor
+ ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
+ """
+ Main processing logic.
+
+ Args:
+ command: normalized rotor command in (num_envs, num_rotors).
+
+ Returns:
+ - Rotor RPM in (num_envs, num_rotors).
+ - Force caused by motor dynamics in (num_envs, num_rotors, 3).
+ - Torque caused by motor dynamics in (num_envs, num_rotors, 3).
+ """
+
+ # update rpm from first order lag
+ rpm_to_ss = self.rpm_ss - self.rpm
+ d_rpm = torch.where(
+ rpm_to_ss >= 0,
+ (1 - self.alpha_spinup) * rpm_to_ss,
+ (1 - self.alpha_slowdown) * rpm_to_ss,
+ )
+ self.rpm += d_rpm
+
+ # torque due to rotor acceleration
+ self.omega_dot[:, :, -1] = ( # (num_envs, num_rotors)
+ -d_rpm * 2 * torch.pi / 60 / self.params.dt * self.rotor_dir
+ )
+ self.torque[:, :] = torch.matmul(
+ self.rotor_inertia, # (num_envs, num_rotors, 3, 3)
+ self.omega_dot.unsqueeze(-1), # (num_envs, num_rotors, 3, 1)
+ ).squeeze(3)
+
+ # target RPM, as input to the first order lag system
+ self.rpm_ss[:] = (
+ self.params.k_rpm_quadratic * torch.pow(command, 2)
+ + self.params.k_rpm_linear * command
+ )
+
+ return self.rpm, self.force, self.torque
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/models/wrench_sum.py b/isaacgymenvs/tasks/drone_racing/drone_sim/models/wrench_sum.py
new file mode 100644
index 000000000..d44376a55
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/models/wrench_sum.py
@@ -0,0 +1,66 @@
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+import torch
+
+
+@dataclass
+class WrenchSumParams:
+ num_envs: int = 64
+ device: str = "cuda"
+ # wrench application positions in body FRD frame
+ # the order should match that of the wrench
+ # default values mean there are 4 positions of application
+ # the n-th position is (position_x[n], position_y[n], position_z[n]) w.r.t. body FRD frame
+ num_positions: int = 4
+ position_x: List[float] = field(
+ default_factory=lambda: [-0.078665, 0.078665, -0.078665, 0.078665]
+ )
+ position_y: List[float] = field(
+ default_factory=lambda: [0.097143, 0.097143, -0.097143, -0.097143]
+ )
+ position_z: List[float] = field(default_factory=lambda: [0.0, 0.0, 0.0, 0.0])
+
+
+class WrenchSum:
+
+ def __init__(self, params: WrenchSumParams):
+ self.params = params
+
+ self.r = torch.zeros(
+ params.num_envs, params.num_positions, 3, device=params.device
+ )
+ self.r[:] = torch.tensor(
+ [params.position_x, params.position_y, params.position_z],
+ device=params.device,
+ ).T
+
+ def compute(
+ self, force: torch.Tensor, torque: torch.Tensor
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Computes total force and torque from scattered wrench.
+
+ The total force is the sum of all scattered forces.
+ The total torque is the sum of all scattered torques plus force-induced torques.
+
+ Args:
+ force: force applied to scattered positions, (num_envs, num_positions, 3).
+ torque: torque applied to scattered positions, (num_envs, num_positions, 3).
+
+
+ Returns:
+ - Total force tensor (num_envs, 3) to be applied to the body frame origin.
+ - Total torque tensor (num_envs, 3) to be applied to the body frame origin.
+ """
+
+ return _compute_script(self.r, force, torque)
+
+
+@torch.jit.script
+def _compute_script(
+ r: torch.Tensor, force: torch.Tensor, torque: torch.Tensor
+) -> Tuple[torch.Tensor, torch.Tensor]:
+ total_force = force.sum(dim=1)
+ total_torque = torque.sum(dim=1) + torch.cross(r, force, 2).sum(dim=1)
+ return total_force, total_torque
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/presets/__init__.py b/isaacgymenvs/tasks/drone_racing/drone_sim/presets/__init__.py
new file mode 100644
index 000000000..bcbbb40b2
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/presets/__init__.py
@@ -0,0 +1 @@
+from .kingfisher_250 import Kingfisher250
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/presets/kingfisher_250.py b/isaacgymenvs/tasks/drone_racing/drone_sim/presets/kingfisher_250.py
new file mode 100644
index 000000000..9c9a9cf74
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/presets/kingfisher_250.py
@@ -0,0 +1,159 @@
+import math
+
+import numpy as np
+
+from isaacgym import gymapi
+from ..controllers import SimpleBetaflightParams
+from ..models import (
+ BodyDragPolyParams,
+ PropellerPolyParams,
+ RotorPolyLagParams,
+ WrenchSumParams,
+)
+from ...assets import DroneQuadcopterOptions
+
+
+class Kingfisher250:
+ """
+ A collection of options, params, properties for the Kingfisher quad running modules at 250Hz.
+ """
+
+ def __init__(self, num_envs: int, device: str):
+ # geometry
+ self.arm_length = 0.125
+ self.arm_angle = math.radians(102)
+ self.num_rotors = 4
+ x = self.arm_length * math.cos(self.arm_angle / 2)
+ y = self.arm_length * math.sin(self.arm_angle / 2)
+ self.rotor_x = [-x, x, -x, x]
+ self.rotor_y = [y, y, -y, -y]
+ self.rotor_dir = [1, -1, -1, 1]
+
+ # sim
+ self.dt = 1 / 250
+ self.num_envs = num_envs
+ self.device = device
+
+ # module params
+ self.quad_asset_options = DroneQuadcopterOptions()
+ self.init_quad_asset_options()
+
+ self.simple_bf_params = SimpleBetaflightParams()
+ self.init_simple_bf_params()
+
+ self.rotor_params = RotorPolyLagParams()
+ self.init_rotor_params()
+
+ self.propeller_params = PropellerPolyParams()
+ self.init_propeller_params()
+
+ self.body_drag_params = BodyDragPolyParams()
+ self.init_body_drag_params()
+
+ self.wrench_sum_params = WrenchSumParams()
+ self.init_wrench_sum_params()
+
+ self.camera_props = gymapi.CameraProperties()
+ self.camera_pose = gymapi.Transform()
+ self.init_camera_props()
+
+ def init_quad_asset_options(self):
+ self.quad_asset_options.file_name = "kingfisher_250"
+ self.quad_asset_options.arm_length_front = self.arm_length
+ self.quad_asset_options.arm_length_back = self.arm_length
+ self.quad_asset_options.arm_thickness = 0.01
+ self.quad_asset_options.arm_front_angle = self.arm_angle
+ self.quad_asset_options.motor_diameter = 0.023
+ self.quad_asset_options.motor_height = 0.006
+ self.quad_asset_options.central_body_pos = [0.0, 0.0, 0.015]
+ self.quad_asset_options.central_body_dim = [0.15, 0.05, 0.05]
+ self.quad_asset_options.propeller_diameter = 0.12954
+ self.quad_asset_options.propeller_height = 0.01
+ self.quad_asset_options.mass = 0.752
+ self.quad_asset_options.center_of_mass = [0.0, 0.0, 0.0]
+ self.quad_asset_options.diagonal_inertia = [0.0025, 0.0021, 0.0043]
+ self.quad_asset_options.principle_axes_q = [1.0, 0.0, 0.0, 0.0]
+ self.quad_asset_options.asset_options = gymapi.AssetOptions()
+
+ def init_simple_bf_params(self):
+ # basic settings
+ self.simple_bf_params.num_envs = self.num_envs
+ self.simple_bf_params.device = self.device
+ self.simple_bf_params.dt = self.dt
+ # rate mapping
+ self.simple_bf_params.center_sensitivity = [100.0, 100.0, 100.0]
+ self.simple_bf_params.max_rate = [670.0, 670.0, 670.0]
+ self.simple_bf_params.rate_expo = [0.0, 0.0, 0.0]
+ # pid
+ self.simple_bf_params.kp = [70.0, 70.0, 125.0]
+ self.simple_bf_params.ki = [0.5, 0.5, 25.0]
+ self.simple_bf_params.kd = [1.0, 1.0, 0.0]
+ self.simple_bf_params.kff = [0.0, 0.0, 0.0]
+ self.simple_bf_params.iterm_lim = [5.0, 5.0, 5.0]
+ self.simple_bf_params.pid_sum_lim = [1000.0, 1000.0, 1000.0]
+ self.simple_bf_params.dterm_lpf_cutoff = 1000
+ # mixer
+ self.simple_bf_params.rotors_x = self.rotor_x
+ self.simple_bf_params.rotors_y = self.rotor_y
+ self.simple_bf_params.rotors_dir = self.rotor_dir
+ self.simple_bf_params.pid_sum_mixer_scale = 1000.0
+ self.simple_bf_params.output_idle = 0.05
+ self.simple_bf_params.throttle_boost_gain = 0.0
+ self.simple_bf_params.throttle_boost_freq = 125.0
+ self.simple_bf_params.thrust_linearization_gain = 0.4
+
+ def init_rotor_params(self):
+ self.rotor_params.num_envs = self.num_envs
+ self.rotor_params.device = self.device
+ self.rotor_params.dt = self.dt
+ self.rotor_params.num_rotors = self.num_rotors
+ self.rotor_params.rotors_dir = self.rotor_dir
+ self.rotor_params.spinup_time_constant = 0.033
+ self.rotor_params.slowdown_time_constant = 0.033
+ self.rotor_params.k_rpm_quadratic = -13421.95
+ self.rotor_params.k_rpm_linear = 37877.42
+ self.rotor_params.rotor_diagonal_inertia = [0.0, 0.0, 9.3575e-6]
+ self.rotor_params.rotor_principle_axes_q = [1.0, 0.0, 0.0, 0.0]
+
+ def init_propeller_params(self):
+ self.propeller_params.num_envs = self.num_envs
+ self.propeller_params.device = self.device
+ self.propeller_params.num_props = self.num_rotors
+ self.propeller_params.prop_dir = self.rotor_dir
+ self.propeller_params.k_force_quadratic = 2.1549e-08
+ self.propeller_params.k_force_linear = -4.5101e-05
+ self.propeller_params.k_torque_quadratic = 2.1549e-08 * 0.022
+ self.propeller_params.k_torque_linear = -4.5101e-05 * 0.022
+
+ def init_body_drag_params(self):
+ # basic settings
+ self.body_drag_params.num_envs = self.num_envs
+ self.body_drag_params.device = self.device
+ self.body_drag_params.air_density = 1.204
+ # translational
+ self.body_drag_params.a_trans = [1.5e-2, 1.5e-2, 3.0e-2]
+ self.body_drag_params.k_trans_quadratic = [1.04, 1.04, 1.04]
+ self.body_drag_params.k_trans_linear = [0.0, 0.0, 0.0]
+ # rotational
+ self.body_drag_params.a_rot = [1e-2, 1e-2, 1e-2]
+ self.body_drag_params.k_rot_quadratic = [0.0, 0.0, 0.0]
+ self.body_drag_params.k_rot_linear = [0.0, 0.0, 0.0]
+
+ def init_wrench_sum_params(self):
+ self.wrench_sum_params.num_envs = self.num_envs
+ self.wrench_sum_params.device = self.device
+ self.wrench_sum_params.num_positions = self.num_rotors
+ self.wrench_sum_params.position_x = self.rotor_x
+ self.wrench_sum_params.position_y = self.rotor_y
+ self.wrench_sum_params.position_z = [0.0, 0.0, 0.0, 0.0]
+
+ def init_camera_props(self):
+ self.camera_props.enable_tensors = True
+ self.camera_props.width = 640
+ self.camera_props.height = 480
+ self.camera_props.horizontal_fov = 90
+
+ self.camera_pose.p = gymapi.Vec3(0.08, 0.0, 0.015)
+ self.camera_pose.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 1, 0), np.radians(-20.0)
+ )
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/utils/__init__.py b/isaacgymenvs/tasks/drone_racing/drone_sim/utils/__init__.py
new file mode 100644
index 000000000..bb5bd7a80
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/utils/__init__.py
@@ -0,0 +1 @@
+from .low_pass_filter import FirstOrderLowPassFilterParams, FirstOrderLowPassFilter
diff --git a/isaacgymenvs/tasks/drone_racing/drone_sim/utils/low_pass_filter.py b/isaacgymenvs/tasks/drone_racing/drone_sim/utils/low_pass_filter.py
new file mode 100644
index 000000000..d4b1591c4
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/drone_sim/utils/low_pass_filter.py
@@ -0,0 +1,41 @@
+from dataclasses import dataclass
+
+import torch
+
+
+@dataclass
+class FirstOrderLowPassFilterParams:
+ device: str = "cuda"
+ dim: torch.Size = torch.Size([64, 1])
+ dt: float = 0.001
+ cutoff_frequency: float = 100.0
+ initial_value: float = 0.0
+
+
+class FirstOrderLowPassFilter:
+
+ def __init__(self, params: FirstOrderLowPassFilterParams):
+ self.params = params
+ self.all_env_id = torch.arange(params.dim[0], device=params.device)
+
+ self.alpha = 1 / (
+ 1 + 1 / (2 * torch.pi * params.cutoff_frequency * self.params.dt)
+ )
+ self.output = params.initial_value * torch.ones(
+ self.params.dim, device=self.params.device
+ )
+
+ def reset(self, env_id: torch.Tensor = None, initial_value: float = None):
+ if env_id is None:
+ env_id = self.all_env_id
+
+ if initial_value is None:
+ initial_value = self.params.initial_value
+
+ self.output[env_id, ...] = initial_value
+
+ def get_output(self) -> torch.Tensor:
+ return self.output
+
+ def update(self, data: torch.Tensor):
+ self.output += self.alpha * (data - self.output)
diff --git a/isaacgymenvs/tasks/drone_racing/encoders/__init__.py b/isaacgymenvs/tasks/drone_racing/encoders/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/isaacgymenvs/tasks/drone_racing/encoders/dce/VAE.py b/isaacgymenvs/tasks/drone_racing/encoders/dce/VAE.py
new file mode 100644
index 000000000..0e479d847
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/encoders/dce/VAE.py
@@ -0,0 +1,311 @@
+# BSD 3-Clause License
+#
+# Copyright (c) 2023, Autonomous Robots Lab, Norwegian University of Science and Technology
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# https://github.com/ntnu-arl/aerial_gym_simulator.git
+# commit 070391cc30d92b76dcd3e4e41a49c8d1b60080ae (HEAD -> main, origin/main, origin/HEAD)
+# Author: Mihir Kulkarni
+# Date: Fri Jul 26 14:47:14 2024 +0200
+#
+# Fix bug that misplaced function arguments
+#
+# Signed-off-by: Mihir Kulkarni
+
+import torch
+import torch.nn as nn
+
+
+class ImgDecoder(nn.Module):
+ def __init__(self, input_dim=1, latent_dim=64, with_logits=False):
+ """
+ Parameters
+ ----------
+ latent_dim: int
+ The latent dimension.
+ """
+
+ super(ImgDecoder, self).__init__()
+ print("[ImgDecoder] Starting create_model")
+ self.with_logits = with_logits
+ self.n_channels = input_dim
+ self.dense = nn.Linear(latent_dim, 512)
+ self.dense1 = nn.Linear(512, 9 * 15 * 128)
+ # Pytorch docs: output_padding is only used to find output shape, but does not actually add zero-padding to output
+ self.deconv1 = nn.ConvTranspose2d(128, 128, kernel_size=3, stride=1, padding=1)
+ self.deconv2 = nn.ConvTranspose2d(
+ 128,
+ 64,
+ kernel_size=5,
+ stride=2,
+ padding=(2, 2),
+ output_padding=(0, 1),
+ dilation=1,
+ )
+ self.deconv4 = nn.ConvTranspose2d(
+ 64,
+ 32,
+ kernel_size=6,
+ stride=4,
+ padding=(2, 2),
+ output_padding=(0, 0),
+ dilation=1,
+ )
+ self.deconv6 = nn.ConvTranspose2d(
+ 32, 16, kernel_size=6, stride=2, padding=(0, 0), output_padding=(0, 1)
+ )
+ self.deconv7 = nn.ConvTranspose2d(
+ 16, self.n_channels, kernel_size=4, stride=2, padding=2
+ ) # tanh activation or sigmoid
+ print("[ImgDecoder] Done with create_model")
+ print("Defined decoder.")
+
+ def forward(self, z):
+ return self.decode(z)
+
+ def decode(self, z):
+ x = self.dense(z)
+ x = torch.relu(x)
+ x = self.dense1(x)
+ x = x.view(x.size(0), 128, 9, 15)
+
+ x = self.deconv1(x)
+ x = torch.relu(x)
+
+ x = self.deconv2(x)
+ x = torch.relu(x)
+
+ x = self.deconv4(x)
+ x = torch.relu(x)
+
+ x = self.deconv6(x)
+ x = torch.relu(x)
+
+ x = self.deconv7(x)
+ # print(f"- After deconv 7, mean: {x.mean():.3f} var: {x.var():.3f}")
+ if self.with_logits:
+ return x
+
+ x = torch.sigmoid(x)
+ # print(f"- After sigmoid, mean: {x.mean():.3f} var: {x.var():.3f}")
+ return x
+
+
+class ImgEncoder(nn.Module):
+ """
+ ResNet8 architecture as encoder.
+ """
+
+ def __init__(self, input_dim, latent_dim):
+ """
+ Parameters:
+ ----------
+ input_dim: int
+ Number of input channels in the image.
+ latent_dim: int
+ Number of latent dimensions
+ """
+ super(ImgEncoder, self).__init__()
+ self.input_dim = input_dim
+ self.latent_dim = latent_dim
+ self.define_encoder()
+ self.elu = nn.ELU()
+ print("Defined encoder.")
+
+ def define_encoder(self):
+ # define conv functions
+ self.conv0 = nn.Conv2d(self.input_dim, 32, kernel_size=5, stride=2, padding=2)
+ self.conv0_1 = nn.Conv2d(32, 32, kernel_size=3, stride=2, padding=2)
+ nn.init.xavier_uniform_(
+ self.conv0_1.weight, gain=nn.init.calculate_gain("linear")
+ )
+ nn.init.zeros_(self.conv0_1.bias)
+
+ self.conv1_0 = nn.Conv2d(32, 32, kernel_size=5, stride=2, padding=1)
+ self.conv1_1 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
+ nn.init.xavier_uniform_(
+ self.conv1_1.weight, gain=nn.init.calculate_gain("linear")
+ )
+ nn.init.zeros_(self.conv1_1.bias)
+
+ self.conv2_0 = nn.Conv2d(64, 64, kernel_size=5, stride=2, padding=2)
+ self.conv2_1 = nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1)
+ nn.init.xavier_uniform_(
+ self.conv2_1.weight, gain=nn.init.calculate_gain("linear")
+ )
+ nn.init.zeros_(self.conv2_1.bias)
+
+ self.conv3_0 = nn.Conv2d(128, 128, kernel_size=5, stride=2)
+
+ self.conv0_jump_2 = nn.Conv2d(32, 64, kernel_size=4, stride=2, padding=1)
+ self.conv1_jump_3 = nn.Conv2d(64, 128, kernel_size=5, stride=4, padding=(2, 1))
+
+ self.dense0 = nn.Linear(3 * 6 * 128, 512)
+ self.dense1 = nn.Linear(512, 2 * self.latent_dim)
+
+ print("Encoder network initialized.")
+
+ def forward(self, img):
+ return self.encode(img)
+
+ def encode(self, img):
+ """
+ Encodes the input image.
+ """
+
+ # conv0
+ x0_0 = self.conv0(img)
+ x0_1 = self.conv0_1(x0_0)
+ x0_1 = self.elu(x0_1)
+
+ x1_0 = self.conv1_0(x0_1)
+ x1_1 = self.conv1_1(x1_0)
+
+ x0_jump_2 = self.conv0_jump_2(x0_1)
+
+ x1_1 = x1_1 + x0_jump_2
+
+ x1_1 = self.elu(x1_1)
+
+ x2_0 = self.conv2_0(x1_1)
+ x2_1 = self.conv2_1(x2_0)
+
+ x1_jump3 = self.conv1_jump_3(x1_1)
+
+ x2_1 = x2_1 + x1_jump3
+
+ x2_1 = self.elu(x2_1)
+
+ x3_0 = self.conv3_0(x2_1)
+
+ x = x3_0.view(x3_0.size(0), -1)
+
+ x = self.dense0(x)
+ x = self.elu(x)
+ x = self.dense1(x)
+ return x
+
+
+class Lambda(nn.Module):
+ """Lambda function that accepts tensors as input."""
+
+ def __init__(self, func):
+ super(Lambda, self).__init__()
+ self.func = func
+
+ def forward(self, x):
+ return self.func(x)
+
+
+class VAE(nn.Module):
+ """Variational Autoencoder for reconstruction of depth images."""
+
+ def __init__(
+ self, input_dim=1, latent_dim=64, with_logits=False, inference_mode=False
+ ):
+ """
+ Parameters
+ ----------
+ input_dim: int
+ The number of input channels in an image.
+ latent_dim: int
+ The latent dimension.
+ """
+
+ super(VAE, self).__init__()
+
+ self.with_logits = with_logits
+ self.input_dim = input_dim
+ self.latent_dim = latent_dim
+ self.inference_mode = inference_mode
+ self.encoder = ImgEncoder(input_dim=self.input_dim, latent_dim=self.latent_dim)
+ self.img_decoder = ImgDecoder(
+ input_dim=1, latent_dim=self.latent_dim, with_logits=self.with_logits
+ )
+
+ self.mean_params = Lambda(lambda x: x[:, : self.latent_dim]) # mean parameters
+ self.logvar_params = Lambda(
+ lambda x: x[:, self.latent_dim :]
+ ) # log variance parameters
+
+ def forward(self, img):
+ """Do a forward pass of the VAE. Generates a reconstructed image based on img
+ Parameters
+ ----------
+ img: torch.Tensor
+ The input image.
+ """
+
+ # encode
+ z = self.encoder(img)
+
+ # reparametrization trick
+ mean = self.mean_params(z)
+ logvar = self.logvar_params(z)
+ std = torch.exp(0.5 * logvar)
+ eps = torch.randn_like(std)
+ if self.inference_mode:
+ eps = torch.zeros_like(eps)
+ z_sampled = mean + eps * std
+
+ # decode
+ img_recon = self.img_decoder(z_sampled)
+ return img_recon, mean, logvar, z_sampled
+
+ def encode(self, img):
+ """Do a forward pass of the VAE. Generates a latent vector based on img
+ Parameters
+ ----------
+ img: torch.Tensor
+ The input image.
+ """
+ z = self.encoder(img)
+
+ means = self.mean_params(z)
+ logvars = self.logvar_params(z)
+ std = torch.exp(0.5 * logvars)
+ eps = torch.randn_like(logvars)
+ if self.inference_mode:
+ eps = torch.zeros_like(eps)
+ z_sampled = means + eps * std
+
+ return z_sampled, means, std
+
+ def decode(self, z):
+ """Do a forward pass of the VAE. Generates a reconstructed image based on z
+ Parameters
+ ----------
+ z: torch.Tensor
+ The latent vector.
+ """
+ img_recon = self.img_decoder(z)
+ if self.with_logits:
+ return torch.sigmoid(img_recon)
+ return img_recon
+
+ def set_inference_mode(self, mode):
+ self.inference_mode = mode
diff --git a/isaacgymenvs/tasks/drone_racing/encoders/dce/__init__.py b/isaacgymenvs/tasks/drone_racing/encoders/dce/__init__.py
new file mode 100644
index 000000000..36ccb25db
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/encoders/dce/__init__.py
@@ -0,0 +1,2 @@
+from .vae_image_encoder import VAEImageEncoder
+from .vae_image_encoder_config import VAEImageEncoderConfig
diff --git a/isaacgymenvs/tasks/drone_racing/encoders/dce/pth/ICRA_test_set_more_sim_data_kld_beta_3_LD_64_epoch_49.pth b/isaacgymenvs/tasks/drone_racing/encoders/dce/pth/ICRA_test_set_more_sim_data_kld_beta_3_LD_64_epoch_49.pth
new file mode 100644
index 000000000..898b82dac
Binary files /dev/null and b/isaacgymenvs/tasks/drone_racing/encoders/dce/pth/ICRA_test_set_more_sim_data_kld_beta_3_LD_64_epoch_49.pth differ
diff --git a/isaacgymenvs/tasks/drone_racing/encoders/dce/vae_image_encoder.py b/isaacgymenvs/tasks/drone_racing/encoders/dce/vae_image_encoder.py
new file mode 100644
index 000000000..5ce713157
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/encoders/dce/vae_image_encoder.py
@@ -0,0 +1,115 @@
+# BSD 3-Clause License
+#
+# Copyright (c) 2023, Autonomous Robots Lab, Norwegian University of Science and Technology
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# https://github.com/ntnu-arl/aerial_gym_simulator.git
+# commit 070391cc30d92b76dcd3e4e41a49c8d1b60080ae (HEAD -> main, origin/main, origin/HEAD)
+# Author: Mihir Kulkarni
+# Date: Fri Jul 26 14:47:14 2024 +0200
+#
+# Fix bug that misplaced function arguments
+#
+# Signed-off-by: Mihir Kulkarni
+
+import os
+
+import torch
+
+from .VAE import VAE
+
+
+def clean_state_dict(state_dict):
+ clean_dict = {}
+ for key, value in state_dict.items():
+ if "module." in key:
+ key = key.replace("module.", "")
+ if "dronet." in key:
+ key = key.replace("dronet.", "encoder.")
+ clean_dict[key] = value
+ return clean_dict
+
+
+class VAEImageEncoder:
+ """
+ Class that wraps around the VAE class for efficient inference for the aerial_gym class
+ """
+
+ def __init__(self, config, device="cuda:0"):
+ self.config = config
+ self.vae_model = VAE(input_dim=1, latent_dim=self.config.latent_dims).to(device)
+ # combine module path with model file name
+ weight_file_path = os.path.join(
+ self.config.model_folder, self.config.model_file
+ )
+ # load model weights
+ print("Loading weights from file: ", weight_file_path)
+ state_dict = clean_state_dict(torch.load(weight_file_path)) # noqa
+ self.vae_model.load_state_dict(state_dict)
+ self.vae_model.eval()
+
+ def encode(self, image_tensors):
+ """
+ Class to encode the set of images to a latent space. We can return both the means and sampled latent space variables.
+ """
+ with torch.no_grad():
+ # need to squeeze 0th dimension and unsqueeze 1st dimension to make it work with the VAE
+ image_tensors = image_tensors.squeeze(0).unsqueeze(1)
+ x_res, y_res = image_tensors.shape[-2], image_tensors.shape[-1]
+ if self.config.image_res != (x_res, y_res):
+ interpolated_image = torch.nn.functional.interpolate(
+ image_tensors,
+ self.config.image_res,
+ mode=self.config.interpolation_mode,
+ )
+ else:
+ interpolated_image = image_tensors
+ z_sampled, means, *_ = self.vae_model.encode(interpolated_image)
+ if self.config.return_sampled_latent:
+ returned_val = z_sampled
+ else:
+ returned_val = means
+ return returned_val
+
+ def decode(self, latent_spaces):
+ """
+ Decode a latent space to reconstruct full images
+ """
+ with torch.no_grad():
+ if latent_spaces.shape[-1] != self.config.latent_dims:
+ print(
+ f"ERROR: Latent space size of {latent_spaces.shape[-1]} "
+ f"does not match network size {self.config.latent_dims}"
+ )
+ decoded_image = self.vae_model.decode(latent_spaces)
+ return decoded_image
+
+ def get_latent_dims_size(self):
+ """
+ Function to get latent space dims
+ """
+ return self.config.latent_dims
diff --git a/isaacgymenvs/tasks/drone_racing/encoders/dce/vae_image_encoder_config.py b/isaacgymenvs/tasks/drone_racing/encoders/dce/vae_image_encoder_config.py
new file mode 100644
index 000000000..0d89b0d72
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/encoders/dce/vae_image_encoder_config.py
@@ -0,0 +1,22 @@
+import os
+from dataclasses import dataclass
+from typing import Tuple
+
+from typing_extensions import LiteralString
+
+
+@dataclass
+class VAEImageEncoderConfig:
+ use_vae: bool = True
+ latent_dims: int = 64
+ model_file: LiteralString = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)),
+ "pth",
+ "ICRA_test_set_more_sim_data_kld_beta_3_LD_64_epoch_49.pth",
+ )
+ model_folder: LiteralString = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "pth"
+ )
+ image_res: Tuple[float, float] = (270, 480)
+ interpolation_mode: str = "nearest"
+ return_sampled_latent: bool = True # TODO: why True?
diff --git a/isaacgymenvs/tasks/drone_racing/env/__init__.py b/isaacgymenvs/tasks/drone_racing/env/__init__.py
new file mode 100644
index 000000000..ee6509325
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/env/__init__.py
@@ -0,0 +1,2 @@
+from .env_creator import EnvCreatorParams, EnvCreator
+from .vis_data import OrbitVisData, WallRegionVisData
diff --git a/isaacgymenvs/tasks/drone_racing/env/env_creator.py b/isaacgymenvs/tasks/drone_racing/env/env_creator.py
new file mode 100644
index 000000000..288b6973f
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/env/env_creator.py
@@ -0,0 +1,567 @@
+from dataclasses import dataclass, field
+from typing import List
+
+import torch
+from tqdm import tqdm
+
+from isaacgym import gymapi
+from isaacgym.gymapi import Gym, Sim, Vec3, Env, Asset, AssetOptions
+from isaacgym.gymapi import Transform, MESH_VISUAL
+from ..assets import (
+ DroneQuadcopterOptions,
+ create_drone_quadcopter,
+ CollectionBox,
+ CollectionCapsule,
+ CollectionCuboidWireframe,
+ CollectionCylinder,
+ CollectionHollowCuboid,
+ CollectionSphere,
+ CollectionTree,
+ CollectionBoxOptions,
+ CollectionCapsuleOptions,
+ CollectionCuboidWireframeOptions,
+ CollectionCylinderOptions,
+ CollectionHollowCuboidOptions,
+ CollectionSphereOptions,
+ CollectionTreeOptions,
+)
+
+
+@dataclass
+class EnvCreatorParams:
+ # number of environments to create and manage
+ num_envs: int = 64
+
+ # size of the environment bounding box [m]
+ env_size: float = 40.0
+
+ # positive offset to move obstacles further down [m]
+ backstage_z_offset: float = 20.0
+
+ # ground color
+ ground_color: List[float] = field(default_factory=lambda: [0.25, 0.25, 0.25])
+
+ # ground length in z direction (thickness) [m]
+ ground_len_z: float = 0.3
+
+ # all possible length x, ascending order
+ gate_bar_len_x: List[float] = field(default_factory=lambda: [0.15, 0.3])
+
+ # all possible length y, ascending order
+ gate_bar_len_y: List[float] = field(default_factory=lambda: [1.0, 2.0, 3.0])
+
+ # all possible length z, ascending order
+ gate_bar_len_z: List[float] = field(default_factory=lambda: [0.15, 0.3])
+
+ # gate color in rgb [0, 1]
+ gate_color: List[float] = field(default_factory=lambda: [1.0, 0.5, 0.3])
+
+ # enabling tqdm shows progress of loading assets and creating envs
+ disable_tqdm: bool = False
+
+ # drone asset options, here we assume quadcopter
+ drone_asset_options: DroneQuadcopterOptions = DroneQuadcopterOptions()
+
+ # other asset options
+ static_asset_opts: AssetOptions = AssetOptions()
+ static_asset_opts.fix_base_link = True
+ static_asset_opts.disable_gravity = True
+ static_asset_opts.collapse_fixed_joints = True
+
+ # random boxes, params: [size_x, size_y, size_z]
+ num_box_actors: int = 20 # per env
+ num_box_assets: int = 100
+ box_params_min: List[float] = field(default_factory=lambda: [0.2, 0.2, 0.2])
+ box_params_max: List[float] = field(default_factory=lambda: [2.0, 2.0, 2.0])
+ box_color: List[float] = field(
+ default_factory=lambda: [31 / 255, 119 / 255, 180 / 255]
+ )
+
+ # random capsules, params: [radius, length]
+ num_capsule_actors: int = 20 # per env
+ num_capsule_assets: int = 100
+ capsule_params_min: List[float] = field(default_factory=lambda: [0.1, 0.1])
+ capsule_params_max: List[float] = field(default_factory=lambda: [1.0, 1.0])
+ capsule_color: List[float] = field(
+ default_factory=lambda: [186 / 255, 54 / 255, 87 / 255]
+ )
+
+ # random cuboid wireframes, params: [size_x, size_y, size_z, weight]
+ num_cuboid_wireframe_actors: int = 20 # per env
+ num_cuboid_wireframe_assets: int = 100
+ cuboid_wireframe_params_min: List[float] = field(
+ default_factory=lambda: [0.2, 0.2, 0.2, 0.1]
+ )
+ cuboid_wireframe_params_max: List[float] = field(
+ default_factory=lambda: [2.0, 2.0, 2.0, 0.4]
+ )
+ cuboid_wireframe_color: List[float] = field(
+ default_factory=lambda: [148 / 255, 103 / 255, 189 / 255]
+ )
+
+ # random cylinders, params: [radius, length]
+ num_cylinder_actors: int = 20 # per env
+ num_cylinder_assets: int = 100
+ cylinder_params_min: List[float] = field(default_factory=lambda: [0.1, 0.2])
+ cylinder_params_max: List[float] = field(default_factory=lambda: [1.0, 2.0])
+ cylinder_color: List[float] = field(
+ default_factory=lambda: [140 / 255, 86 / 255, 75 / 255]
+ )
+
+ # random hollow cuboids, params: [length_x, inner_length_y, inner_length_z, diff_length_y, diff_length_z]
+ num_hollow_cuboid_actors: int = 20 # per env
+ num_hollow_cuboid_assets: int = 100
+ hollow_cuboid_params_min: List[float] = field(
+ default_factory=lambda: [0.05, 0.5, 0.5, 0.2, 0.2]
+ )
+ hollow_cuboid_params_max: List[float] = field(
+ default_factory=lambda: [0.25, 1.4, 1.4, 0.6, 0.6]
+ )
+ hollow_cuboid_color: List[float] = field(
+ default_factory=lambda: [227 / 255, 119 / 255, 194 / 255]
+ )
+
+ # random spheres, params: [radius]
+ num_sphere_actors: int = 20 # per env
+ num_sphere_assets: int = 100
+ sphere_params_min: List[float] = field(default_factory=lambda: [0.1])
+ sphere_params_max: List[float] = field(default_factory=lambda: [1.0])
+ sphere_color: List[float] = field(
+ default_factory=lambda: [188 / 255, 189 / 255, 34 / 255]
+ )
+
+ # random trees, params: none
+ num_tree_actors: int = 20 # per env
+ num_tree_assets: int = 100
+ tree_color: List[float] = field(
+ default_factory=lambda: [107 / 255, 138 / 255, 122 / 255]
+ )
+
+ # random walls, params: [size_x, size_y, size_z]
+ num_wall_actors: int = 20 # per env
+ num_wall_assets: int = 100
+ wall_params_min: List[float] = field(default_factory=lambda: [0.2, 2.0, 2.0])
+ wall_params_max: List[float] = field(default_factory=lambda: [0.2, 4.0, 4.0])
+ wall_color: List[float] = field(
+ default_factory=lambda: [23 / 255, 190 / 255, 207 / 255]
+ )
+
+
+class EnvCreator:
+ """
+ Creates drone and obstacle actors for 4-waypoint racing envs.
+ """
+
+ def __init__(self, gym: Gym, sim: Sim, params: EnvCreatorParams):
+ self.gym: Gym = gym
+ self.sim: Sim = sim
+ self.params = params
+
+ # ========== create assets ==========
+
+ # drone
+ self.drone_asset = create_drone_quadcopter(
+ self.gym, self.sim, params.drone_asset_options
+ )
+
+ # ground
+ ground_x = ground_y = params.env_size
+ self.ground_asset = self.gym.create_box(
+ self.sim, ground_x, ground_y, params.ground_len_z, params.static_asset_opts
+ )
+
+ # gate bars
+ self.gate_bar_assets: List[List[List[Asset]]] = []
+ for x in params.gate_bar_len_x:
+ list_y = []
+ for y in params.gate_bar_len_y:
+ list_z = []
+ for z in params.gate_bar_len_z:
+ bar = self.gym.create_box(
+ self.sim, x, y, z, params.static_asset_opts
+ )
+ list_z.append(bar)
+ list_y.append(list_z)
+ self.gate_bar_assets.append(list_y)
+
+ # boxes
+ self.collection_box = CollectionBox(
+ self.gym,
+ self.sim,
+ CollectionBoxOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_box_actors,
+ num_blueprints=params.num_box_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(params.disable_tqdm or params.num_box_assets == 0),
+ params_min=params.box_params_min,
+ params_max=params.box_params_max,
+ ),
+ )
+
+ # capsules
+ self.collection_capsule = CollectionCapsule(
+ self.gym,
+ self.sim,
+ CollectionCapsuleOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_capsule_actors,
+ num_blueprints=params.num_capsule_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(params.disable_tqdm or params.num_capsule_assets == 0),
+ params_min=params.capsule_params_min,
+ params_max=params.capsule_params_max,
+ ),
+ )
+
+ # cuboid wireframes
+ self.collection_cuboid_wireframe = CollectionCuboidWireframe(
+ self.gym,
+ self.sim,
+ CollectionCuboidWireframeOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_cuboid_wireframe_actors,
+ num_blueprints=params.num_cuboid_wireframe_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(
+ params.disable_tqdm or params.num_cuboid_wireframe_assets == 0
+ ),
+ params_min=params.cuboid_wireframe_params_min,
+ params_max=params.cuboid_wireframe_params_max,
+ ),
+ )
+
+ # cylinders
+ self.collection_cylinder = CollectionCylinder(
+ self.gym,
+ self.sim,
+ CollectionCylinderOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_cylinder_actors,
+ num_blueprints=params.num_cylinder_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(params.disable_tqdm or params.num_cylinder_assets == 0),
+ params_min=params.cylinder_params_min,
+ params_max=params.cylinder_params_max,
+ ),
+ )
+
+ # hollow cuboids
+ self.collection_hollow_cuboid = CollectionHollowCuboid(
+ self.gym,
+ self.sim,
+ CollectionHollowCuboidOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_hollow_cuboid_actors,
+ num_blueprints=params.num_hollow_cuboid_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(
+ params.disable_tqdm or params.num_hollow_cuboid_assets == 0
+ ),
+ params_min=params.hollow_cuboid_params_min,
+ params_max=params.hollow_cuboid_params_max,
+ ),
+ )
+
+ # spheres
+ self.collection_sphere = CollectionSphere(
+ self.gym,
+ self.sim,
+ CollectionSphereOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_sphere_actors,
+ num_blueprints=params.num_sphere_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(params.disable_tqdm or params.num_sphere_assets == 0),
+ params_min=params.sphere_params_min,
+ params_max=params.sphere_params_max,
+ ),
+ )
+
+ # trees
+ self.collection_tree = CollectionTree(
+ self.gym,
+ self.sim,
+ CollectionTreeOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_tree_actors,
+ num_blueprints=params.num_tree_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(params.disable_tqdm or params.num_tree_assets == 0),
+ ),
+ )
+
+ # walls
+ self.collection_wall = CollectionBox(
+ self.gym,
+ self.sim,
+ CollectionBoxOptions(
+ num_envs=params.num_envs,
+ num_assets=params.num_wall_actors,
+ num_blueprints=params.num_wall_assets,
+ asset_options=params.static_asset_opts,
+ disable_tqdm=(params.disable_tqdm or params.num_wall_assets == 0),
+ params_min=params.wall_params_min,
+ params_max=params.wall_params_max,
+ ),
+ )
+
+ # ========== prepare other variables ==========
+
+ self.envs: List[Env] = []
+ self.quad_actors: List[int] = []
+
+ num_gate_bar_actors = (
+ 8 # 2 (waypoints) * 4 (bars per waypoint)
+ * len(params.gate_bar_len_x)
+ * len(params.gate_bar_len_y)
+ * len(params.gate_bar_len_z)
+ )
+
+ self.drone_actor_id = torch.zeros(params.num_envs, 1, dtype=torch.int)
+ self.ground_actor_id = torch.zeros(params.num_envs, 1, dtype=torch.int)
+ self.gate_bar_actor_id = torch.zeros(
+ params.num_envs, num_gate_bar_actors, dtype=torch.int
+ )
+ self.box_actor_id = torch.zeros(
+ params.num_envs, params.num_box_actors, dtype=torch.int
+ )
+ self.capsule_actor_id = torch.zeros(
+ params.num_envs, params.num_capsule_actors, dtype=torch.int
+ )
+ self.cuboid_wireframe_actor_id = torch.zeros(
+ params.num_envs,
+ params.num_cuboid_wireframe_actors,
+ dtype=torch.int,
+ )
+ self.cylinder_actor_id = torch.zeros(
+ params.num_envs, params.num_cylinder_actors, dtype=torch.int
+ )
+ self.hollow_cuboid_actor_id = torch.zeros(
+ params.num_envs, params.num_hollow_cuboid_actors, dtype=torch.int
+ )
+ self.sphere_actor_id = torch.zeros(
+ params.num_envs, params.num_sphere_actors, dtype=torch.int
+ )
+ self.tree_actor_id = torch.zeros(
+ params.num_envs, params.num_tree_actors, dtype=torch.int
+ )
+ self.wall_actor_id = torch.zeros(
+ params.num_envs, params.num_wall_actors, dtype=torch.int
+ )
+
+ self.num_actors_per_env = (
+ 2
+ + num_gate_bar_actors
+ + params.num_box_actors
+ + params.num_capsule_actors
+ + params.num_cuboid_wireframe_actors
+ + params.num_cylinder_actors
+ + params.num_hollow_cuboid_actors
+ + params.num_sphere_actors
+ + params.num_tree_actors
+ + params.num_wall_actors
+ )
+ self.envs_created = False
+
+ def create(self, drone_position: List[float]):
+ """
+ Creates envs, actors.
+
+ Args:
+ drone_position: spawning position of the drone.
+ """
+
+ count = 0
+
+ for i in tqdm(range(self.params.num_envs), disable=self.params.disable_tqdm):
+
+ # ========== env ==========
+
+ env_size = self.params.env_size
+ env = self.gym.create_env(
+ self.sim,
+ Vec3(-env_size / 2, -env_size / 2, 0),
+ Vec3(env_size / 2, env_size / 2, env_size),
+ int(self.params.num_envs**0.5),
+ )
+ self.envs.append(env)
+
+ tf = gymapi.Transform()
+
+ # ========== drone ==========
+
+ x, y, z = drone_position
+ tf.p = gymapi.Vec3(x, y, z)
+ quad_actor = self.gym.create_actor(env, self.drone_asset, tf, "drone", i, 0)
+ self.quad_actors.append(quad_actor)
+ self.drone_actor_id[i] = count
+ count += 1
+
+ # ========== ground ==========
+
+ tf.p = gymapi.Vec3(0.0, 0.0, -self.params.ground_len_z / 2)
+ ground_actor = self.gym.create_actor(
+ env, self.ground_asset, tf, "ground", i, 1
+ )
+ r, g, b = self.params.ground_color
+ self.gym.set_rigid_body_color(
+ env, ground_actor, 0, gymapi.MESH_VISUAL, gymapi.Vec3(r, g, b)
+ )
+ self.ground_actor_id[i] = count
+ count += 1
+
+ # ========== gate ==========
+
+ for wp_id in [1, 2]:
+ for x_id in range(len(self.params.gate_bar_len_x)):
+ for y_id in range(len(self.params.gate_bar_len_y)):
+ for z_id in range(len(self.params.gate_bar_len_z)):
+ for bar_id in [0, 1, 2, 3]:
+ bar_x = self.params.gate_bar_len_x[x_id]
+ bar_y = self.params.gate_bar_len_y[y_id]
+ bar_z = self.params.gate_bar_len_z[z_id]
+ actor = self.gym.create_actor(
+ env,
+ self.gate_bar_assets[x_id][y_id][z_id],
+ rand_backstage_tf(
+ self.params.env_size,
+ self.params.backstage_z_offset,
+ ),
+ get_gate_actor_name(
+ wp_id, bar_x, bar_y, bar_z, bar_id
+ ),
+ i,
+ 1,
+ )
+ r, g, b = self.params.gate_color
+ self.gym.set_rigid_body_color(
+ env,
+ actor,
+ 0,
+ gymapi.MESH_VISUAL,
+ gymapi.Vec3(r, g, b),
+ )
+ for j in range(self.gate_bar_actor_id.shape[1]):
+ self.gate_bar_actor_id[i, j] = count
+ count += 1
+
+ # ========== other obstacles ==========
+
+ collections = [
+ self.collection_box,
+ self.collection_capsule,
+ self.collection_cuboid_wireframe,
+ self.collection_cylinder,
+ self.collection_hollow_cuboid,
+ self.collection_sphere,
+ self.collection_tree,
+ self.collection_wall,
+ ]
+ names = [
+ "box",
+ "capsule",
+ "wireframe",
+ "cylinder",
+ "hollow",
+ "sphere",
+ "tree",
+ "wall",
+ ]
+ colors = [
+ self.params.box_color,
+ self.params.capsule_color,
+ self.params.cuboid_wireframe_color,
+ self.params.cylinder_color,
+ self.params.hollow_cuboid_color,
+ self.params.sphere_color,
+ self.params.tree_color,
+ self.params.wall_color,
+ ]
+ actor_ids = [
+ self.box_actor_id,
+ self.capsule_actor_id,
+ self.cuboid_wireframe_actor_id,
+ self.cylinder_actor_id,
+ self.hollow_cuboid_actor_id,
+ self.sphere_actor_id,
+ self.tree_actor_id,
+ self.wall_actor_id,
+ ]
+
+ for j in range(len(collections)):
+ create_collection_actors(
+ gym=self.gym,
+ env=env,
+ env_id=i,
+ env_size=self.params.env_size,
+ z_offset=self.params.backstage_z_offset,
+ assets=collections[j].assets[i],
+ name=names[j],
+ color=colors[j],
+ )
+ for k in range(actor_ids[j].shape[1]):
+ actor_ids[j][i, k] = count
+ count += 1
+
+ self.envs_created = True
+
+
+def rand_backstage_tf(env_size: float, z_offset: float) -> Transform:
+ x, y, z = (
+ torch.rand(3) * torch.tensor(env_size)
+ - torch.tensor(
+ [
+ env_size / 2,
+ env_size / 2,
+ env_size + z_offset,
+ ]
+ )
+ ).tolist()
+ tf = Transform()
+ tf.p = Vec3(x, y, z)
+ return tf
+
+
+def create_collection_actors(
+ gym: Gym,
+ env: Env,
+ env_id: int,
+ env_size: float,
+ z_offset: float,
+ assets: List[Asset],
+ name: str,
+ color: List[float] = None,
+):
+ if color is None:
+ color = [0.5, 0.5, 0.5]
+ for i in range(len(assets)):
+ actor = gym.create_actor(
+ env,
+ assets[i],
+ rand_backstage_tf(env_size, z_offset),
+ name + "_" + str(i),
+ env_id,
+ 1,
+ )
+ r, g, b = color
+ gym.set_rigid_body_color(env, actor, 0, MESH_VISUAL, Vec3(r, g, b))
+
+
+def get_gate_actor_name(
+ wp_id: int, len_x: float, len_y: float, len_z: float, bar_id: int
+):
+ name = (
+ "gate_"
+ + str(wp_id)
+ + "_("
+ + str(len_x)
+ + ", "
+ + str(len_y)
+ + ", "
+ + str(len_z)
+ + ")"
+ + "_"
+ + str(bar_id)
+ )
+ return name
diff --git a/isaacgymenvs/tasks/drone_racing/env/vis_data.py b/isaacgymenvs/tasks/drone_racing/env/vis_data.py
new file mode 100644
index 000000000..6418ecea0
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/env/vis_data.py
@@ -0,0 +1,127 @@
+from typing import List
+
+import torch
+
+from isaacgym import gymutil
+from isaacgym.gymapi import Gym, Vec3, Env, Viewer, Transform, Quat
+
+
+class OrbitVisData:
+
+ def __init__(
+ self,
+ position: torch.Tensor,
+ r_min: torch.Tensor,
+ r_mean: torch.Tensor,
+ r_max: torch.Tensor,
+ ):
+ """
+ Args:
+ position: tensor in (num_envs, num_orbits, 3).
+ r_min: tensor in (num_envs, num_orbits).
+ r_mean: tensor in (num_envs, num_orbits).
+ r_max: tensor in (num_envs, num_orbits).
+ """
+ self.position = position
+ self.r_min = r_min
+ self.r_mean = r_mean
+ self.r_max = r_max
+
+ @property
+ def num_envs(self):
+ return int(self.position.shape[0])
+
+ @property
+ def num_orbits(self):
+ return int(self.position.shape[1])
+
+ def visualize(
+ self,
+ gym: Gym,
+ envs: List[Env],
+ viewer: Viewer,
+ draw_min: bool = True,
+ draw_mean: bool = True,
+ draw_max: bool = True,
+ min_color: List[float] = None,
+ mean_color: List[float] = None,
+ max_color: List[float] = None,
+ ):
+ num_envs = len(envs)
+ assert num_envs == self.num_envs
+
+ if min_color is None:
+ min_color = (1.0, 1.0, 1.0)
+ if mean_color is None:
+ mean_color = (0.0, 0.0, 1.0)
+ if max_color is None:
+ max_color = (0.6, 0.2, 0.7)
+
+ tf = Transform()
+ for i in range(num_envs):
+ for j in range(self.num_orbits):
+ x, y, z = self.position[i, j].tolist()
+ tf.p = Vec3(x, y, z)
+ if draw_min:
+ sphere = gymutil.WireframeSphereGeometry(
+ radius=self.r_min[i, j], color=min_color
+ )
+ gymutil.draw_lines(sphere, gym, viewer, envs[i], tf)
+ if draw_mean:
+ sphere = gymutil.WireframeSphereGeometry(
+ radius=self.r_mean[i, j], color=mean_color
+ )
+ gymutil.draw_lines(sphere, gym, viewer, envs[i], tf)
+ if draw_max:
+ sphere = gymutil.WireframeSphereGeometry(
+ radius=self.r_max[i, j], color=max_color
+ )
+ gymutil.draw_lines(sphere, gym, viewer, envs[i], tf)
+
+
+class WallRegionVisData:
+
+ def __init__(
+ self, position: torch.Tensor, quaternion: torch.Tensor, dim: torch.Tensor
+ ):
+ """
+ Args:
+ position: tensor in (num_envs, num_regions, 3).
+ quaternion: tensor in (num_envs, num_regions, 4).
+ dim: tensor in (num_envs, num_regions).
+ """
+ self.position = position
+ self.quaternion = quaternion
+ self.dim = dim
+
+ @property
+ def num_envs(self):
+ return int(self.position.shape[0])
+
+ @property
+ def num_regions(self):
+ return int(self.position.shape[1])
+
+ def visualize(
+ self,
+ gym: Gym,
+ envs: List[Env],
+ viewer: Viewer,
+ color: List[float] = None,
+ ):
+ num_envs = len(envs)
+ assert num_envs == self.num_envs
+
+ if color is None:
+ color = (1.0, 1.0, 0.0)
+
+ tf = Transform()
+ for i in range(num_envs):
+ for j in range(self.num_regions):
+ x, y, z = self.position[i, j]
+ qx, qy, qz, qw = self.quaternion[i, j]
+ tf.p = Vec3(x, y, z)
+ tf.r = Quat(qx, qy, qz, qw)
+ dim = self.dim[i, j]
+ square = gymutil.WireframeBoxGeometry(dim, dim, dim, color=color)
+ gymutil.draw_lines(square, gym, viewer, envs[i], tf)
diff --git a/isaacgymenvs/tasks/drone_racing/managers/__init__.py b/isaacgymenvs/tasks/drone_racing/managers/__init__.py
new file mode 100644
index 000000000..6b483ea5a
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/managers/__init__.py
@@ -0,0 +1,7 @@
+"""
+Package for managing camera, drone, and obstacle.
+"""
+
+from .camera_manager import CameraManager, RandCameraOptions
+from .drone_manager import DroneManagerParams, DroneManager, RandDroneOptions
+from .obstacle_manager import ObstacleManager, RandObstacleOptions
diff --git a/isaacgymenvs/tasks/drone_racing/managers/camera_manager.py b/isaacgymenvs/tasks/drone_racing/managers/camera_manager.py
new file mode 100644
index 000000000..281ca8dc9
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/managers/camera_manager.py
@@ -0,0 +1,77 @@
+from dataclasses import dataclass
+from typing import List
+
+import torch
+
+from isaacgym import gymapi
+from isaacgym.gymapi import Gym, Env
+
+
+@dataclass
+class RandCameraOptions:
+ d_x_max: float = 0.01
+ d_y_max: float = 0.0
+ d_z_max: float = 0.01
+ d_angle_max: float = 10.0
+
+
+class CameraManager:
+
+ def __init__(
+ self,
+ gym: Gym,
+ cams: List[int],
+ envs: List[Env],
+ drones: List[int],
+ init_cam_pos: List[float],
+ init_cam_angle: float,
+ ):
+
+ self.gym: Gym = gym
+ self.cams: List[int] = cams
+ self.envs: List[Env] = envs
+ self.drones: List[int] = drones
+ self.num_envs = len(envs)
+ self.init_cam_position = init_cam_pos
+ self.init_cam_angle = init_cam_angle
+
+ def randomize_camera_tf(self, options: RandCameraOptions) -> List[gymapi.Transform]:
+ x = (
+ torch.rand(self.num_envs) * 2 * options.d_x_max
+ - options.d_x_max
+ + self.init_cam_position[0]
+ )
+ y = (
+ torch.rand(self.num_envs) * 2 * options.d_y_max
+ - options.d_y_max
+ + self.init_cam_position[1]
+ )
+ z = (
+ torch.rand(self.num_envs) * 2 * options.d_z_max
+ - options.d_z_max
+ + self.init_cam_position[2]
+ )
+ angle = (
+ torch.rand(self.num_envs) * 2 * options.d_angle_max
+ - options.d_angle_max
+ + self.init_cam_angle
+ )
+
+ cam_tf_list = []
+ for i in range(self.num_envs):
+ cam_tf = gymapi.Transform()
+ cam_tf.p = gymapi.Vec3(x[i], y[i], z[i])
+ cam_tf.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 1, 0), -angle[i] * torch.pi / 180
+ )
+ if len(self.cams) > 0:
+ self.gym.attach_camera_to_body(
+ self.cams[i],
+ self.envs[i],
+ self.drones[i],
+ cam_tf,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+ cam_tf_list.append(cam_tf)
+
+ return cam_tf_list
diff --git a/isaacgymenvs/tasks/drone_racing/managers/drone_manager.py b/isaacgymenvs/tasks/drone_racing/managers/drone_manager.py
new file mode 100644
index 000000000..34fc98f40
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/managers/drone_manager.py
@@ -0,0 +1,232 @@
+from dataclasses import dataclass
+from typing import Tuple, Optional
+
+import torch
+
+from isaacgym import torch_utils
+from isaacgymenvs.utils.torch_jit_utils import quat_rotate, quaternion_to_matrix
+from ..waypoint import WaypointData
+
+
+@dataclass
+class DroneManagerParams:
+ num_envs: int = 64
+ device: str = "cuda"
+
+
+@dataclass
+class RandDroneOptions:
+ # if min not specified and noted, it means min = -max
+
+ # if -1, will be set to the max allowed value
+ # min = 0, max value is included
+ next_wp_id_max: int = 1
+
+ dist_along_line_min: float = 0.0
+ dist_along_line_max: float = 0.1
+ drone_rotation_x_max: float = 1.57
+ dist_to_line_max: float = 1.0 # min = 0
+
+ # linear velocity in body frame [m/s]
+ lin_vel_x_max: float = 1.0
+ lin_vel_y_max: float = 1.0
+ lin_vel_z_max: float = 1.0
+
+ # angular velocity in body frame [rad/s]
+ ang_vel_x_max: float = 1.0
+ ang_vel_y_max: float = 1.0
+ ang_vel_z_max: float = 1.0
+
+ # cmd range [-1, 1]
+ aileron_max: float = 0.2
+ elevator_max: float = 0.2
+ rudder_max: float = 0.2
+ throttle_min: float = -1.0
+ throttle_max: float = -0.5
+
+
+class DroneManager:
+
+ def __init__(self, params: DroneManagerParams):
+ self.params = params
+ self.all_env_id = torch.arange(params.num_envs, device=params.device)
+
+ self.drone_state = torch.zeros(params.num_envs, 13, device=params.device)
+ self.drone_state[:, 6] = 1
+ self.init_cmd = torch.zeros(params.num_envs, 4, device=params.device)
+
+ self.wp_position: Optional[torch.Tensor] = None
+ self.wp_quaternion: Optional[torch.Tensor] = None
+ self.wp_psi: Optional[torch.Tensor] = None
+ self.wp_theta: Optional[torch.Tensor] = None
+ self.wp_num: Optional[int] = None
+
+ self.next_wp_id = torch.ones(
+ params.num_envs, dtype=torch.long, device=params.device
+ )
+
+ def set_waypoint(self, wp_data: WaypointData):
+ self.wp_position = wp_data.position.to(self.params.device)
+ self.wp_quaternion = wp_data.quaternion.to(self.params.device)
+ self.wp_psi = wp_data.psi.to(self.params.device)
+ self.wp_theta = wp_data.theta.to(self.params.device)
+ self.wp_num = wp_data.num_waypoints
+
+ def compute(
+ self,
+ rand_drone_opts: RandDroneOptions,
+ force_wp_center: bool = True,
+ env_id: torch.Tensor = None,
+ ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
+ """
+ Compute full state tensor of drones in world frame, initial commands and next waypoint.
+ Only partial values selected by ``env_id`` in the returned tensors are meaningful.
+
+ The drone is initialized within cylinder spaces between waypoints.
+ For a multi-waypoint track, there are multiple cylinder spaces.
+
+ Firstly, the next waypoint id ``n`` is randomly selected in set {1, 2, ..., ``num_waypoints`` - 1}.
+ This determines within which cylinder space the drone will be spawned.
+
+ Secondly, 3 parameters ``d``, ``phi_p``, ``r``, are sampled to determine the position of the drone.
+ If ``restrict_to_wp`` is ``True``, ``d`` and ``r`` are set to zero in a post-processing step.
+
+ There are 2 modes to initialize the orientation: same as the starting waypoint,
+ and random orientation with body x aligned with the line connecting the starting and terminal waypoints.
+ So thirdly, the mode integer ``m`` and rotation ``phi_x`` are sampled to determine the orientation.
+
+ Finally, velocities in body frame and initial commands are sampled.
+
+ To vectorize the operation, the parameters are sampled all together,
+ actual pose and velocities are then calculated from the parameters.
+
+ Args:
+ env_id: ids of envs that need reset.
+ force_wp_center: if True, force init at waypoint center.
+ rand_drone_opts: options for random drones initial states.
+
+ Returns:
+ - Full state tensor of drone actors in world frame (num_envs, 13).
+ - Initial commands in (num_envs, 4).
+ - Next waypoint id in (num_envs, ).
+ """
+
+ if env_id is None:
+ env_id = self.all_env_id
+ num_envs_to_reset = env_id.shape[0]
+
+ # sample the next waypoint id and orientation mode
+ wp_id_max = rand_drone_opts.next_wp_id_max
+ assert wp_id_max > 0
+ if wp_id_max == -1:
+ wp_id_max = self.wp_num - 2
+ n = torch.randint(
+ 1,
+ wp_id_max + 1,
+ (num_envs_to_reset,),
+ device=self.params.device,
+ )
+ m = torch.randint(0, 2, (num_envs_to_reset,), device=self.params.device)
+
+ # sample other parameters
+ p_min = torch.tensor(
+ [
+ rand_drone_opts.dist_along_line_min, # [0] d
+ -torch.pi, # [1] phi_p
+ 0.0, # [2] r
+ -rand_drone_opts.drone_rotation_x_max, # [3] phi_x
+ -rand_drone_opts.lin_vel_x_max, # [4] vx
+ -rand_drone_opts.lin_vel_y_max, # [5] vy
+ -rand_drone_opts.lin_vel_z_max, # [6] vz
+ -rand_drone_opts.ang_vel_x_max, # [7] wx
+ -rand_drone_opts.ang_vel_y_max, # [8] wy
+ -rand_drone_opts.ang_vel_z_max, # [9] wz
+ -rand_drone_opts.aileron_max, # [10] a
+ -rand_drone_opts.elevator_max, # [11] e
+ rand_drone_opts.throttle_min, # [12] t
+ -rand_drone_opts.rudder_max, # [13] r
+ ],
+ device=self.params.device,
+ )
+ p_max = torch.tensor(
+ [
+ rand_drone_opts.dist_along_line_max, # [0] d
+ torch.pi, # [1] phi_p
+ rand_drone_opts.dist_to_line_max, # [2] r
+ rand_drone_opts.drone_rotation_x_max, # [3] phi_x
+ rand_drone_opts.lin_vel_x_max, # [4] vx
+ rand_drone_opts.lin_vel_y_max, # [5] vy
+ rand_drone_opts.lin_vel_z_max, # [6] vz
+ rand_drone_opts.ang_vel_x_max, # [7] wx
+ rand_drone_opts.ang_vel_y_max, # [8] wy
+ rand_drone_opts.ang_vel_z_max, # [9] wz
+ rand_drone_opts.aileron_max, # [10] a
+ rand_drone_opts.elevator_max, # [11] e
+ rand_drone_opts.throttle_max, # [12] t
+ rand_drone_opts.rudder_max, # [13] r
+ ],
+ device=self.params.device,
+ )
+ if force_wp_center:
+ p_min[[0, 2]] = 0
+ m.zero_()
+
+ p = (
+ torch.rand(num_envs_to_reset, 14, device=self.params.device)
+ * (p_max - p_min)
+ + p_min
+ )
+
+ # update drone position
+ # TODO: MOST POSITIONS ARE AT RIGHT HAND SIDE (BUG?)
+ n_1 = n - 1
+ starting_wp_pos = self.wp_position[env_id, n_1]
+ terminal_wp_pos = self.wp_position[env_id, n]
+ d_vec = terminal_wp_pos - starting_wp_pos
+ quat_for_drone_pos = torch_utils.quat_mul(
+ self.wp_quaternion[env_id, n_1],
+ torch_utils.quat_from_euler_xyz(
+ p[:, 1],
+ -self.wp_theta[env_id, n_1],
+ self.wp_psi[env_id, n_1],
+ ),
+ )
+ mat_for_drone_pos = quaternion_to_matrix(quat_for_drone_pos.roll(1))
+ r_vec = mat_for_drone_pos[:, 1]
+ self.drone_state[env_id, :3] = (
+ starting_wp_pos
+ + p[:, 0].unsqueeze(1) * d_vec
+ + p[:, 2].unsqueeze(1) * r_vec
+ )
+
+ # update drone quaternion
+ id_mode_0 = torch.nonzero(torch.eq(m, 0)).flatten()
+ id_mode_1 = torch.nonzero(torch.eq(m, 1)).flatten()
+ env_id_mode_0 = env_id[id_mode_0]
+ env_id_mode_1 = env_id[id_mode_1]
+ n_1_mode_0 = n_1[id_mode_0]
+ n_1_mode_1 = n_1[id_mode_1]
+ phi_x_mode_1 = p[id_mode_1, 3]
+ self.drone_state[env_id_mode_0, 3:7] = self.wp_quaternion[
+ env_id_mode_0, n_1_mode_0
+ ]
+ self.drone_state[env_id_mode_1, 3:7] = torch_utils.quat_mul(
+ self.wp_quaternion[env_id_mode_1, n_1_mode_1],
+ torch_utils.quat_from_euler_xyz(
+ phi_x_mode_1,
+ -self.wp_theta[env_id_mode_1, n_1_mode_1],
+ self.wp_psi[env_id_mode_1, n_1_mode_1],
+ ),
+ )
+
+ # update drone velocity (note: should be in world frame)
+ self.drone_state[env_id, 7:] = p[:, 4:10]
+ self.drone_state[env_id, 7:10] = quat_rotate(
+ self.drone_state[env_id, 3:7], self.drone_state[env_id, 7:10]
+ )
+
+ # update init command and next waypoint id
+ self.init_cmd[env_id] = p[:, -4:]
+ self.next_wp_id[env_id] = n
+
+ return self.drone_state, self.init_cmd, self.next_wp_id
diff --git a/isaacgymenvs/tasks/drone_racing/managers/obstacle_manager.py b/isaacgymenvs/tasks/drone_racing/managers/obstacle_manager.py
new file mode 100644
index 000000000..26da86ed8
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/managers/obstacle_manager.py
@@ -0,0 +1,435 @@
+from dataclasses import dataclass
+from typing import List, Tuple, Optional
+
+import torch
+from torch import pi
+
+from isaacgym import torch_utils
+from isaacgym.gymapi import Gym, Env, DOMAIN_SIM
+from isaacgymenvs.utils.torch_jit_utils import quaternion_to_matrix
+from ..env import OrbitVisData, WallRegionVisData
+from ..env.env_creator import EnvCreator, get_gate_actor_name
+from ..waypoint import WaypointData
+
+
+@dataclass
+class RandObstacleOptions:
+ # extra distance added to waypoints' half diagonal lengths to make safe spheres
+ extra_clearance: float = 1.42
+
+ # number of orbital obstacles per surface area m^2 of the orbit spheres
+ orbit_density: float = 1 / 6
+
+ # number of trees per meter on the line segments connecting waypoints
+ tree_density: float = 1 / 3
+
+ # number of walls per m^2 of the mid-planes
+ wall_density: float = 1 / 25
+
+ # a scaling factor for wall center deviation from the line
+ wall_dist_scale: float = 1.0
+
+ # scaling factor of standard deviation of obstacles' normal distribution
+ std_dev_scale: float = 1.0
+
+ # minimum ground distance to the lowest waypoints' safety sphere
+ gnd_distance_min: float = 1.0
+
+ # maximum ground distance to the lowest waypoints' safety sphere
+ # final gnd height will not be lower than -backstage_z_offset
+ gnd_distance_max: float = 20.0
+
+
+class ObstacleManager:
+ """
+ Manages obstacle poses around 4-waypoint tracks.
+ """
+
+ def __init__(self, env_creator: EnvCreator):
+ assert env_creator.envs_created
+
+ self.gym: Gym = env_creator.gym
+ self.envs: List[Env] = env_creator.envs
+
+ self.num_envs = env_creator.params.num_envs
+ self.env_size = env_creator.params.env_size
+ self.backstage_z_offset = env_creator.params.backstage_z_offset
+ self.gate_bar_len_x = env_creator.params.gate_bar_len_x
+ self.gate_bar_len_y = env_creator.params.gate_bar_len_y
+ self.gate_bar_len_z = env_creator.params.gate_bar_len_z
+
+ self.ground_actor_id = env_creator.ground_actor_id
+ self.orbit_actor_id = torch.cat(
+ (
+ env_creator.box_actor_id,
+ env_creator.capsule_actor_id,
+ env_creator.cuboid_wireframe_actor_id,
+ env_creator.cylinder_actor_id,
+ env_creator.hollow_cuboid_actor_id,
+ env_creator.sphere_actor_id,
+ ),
+ dim=1,
+ )
+
+ self.tree_actor_id = env_creator.tree_actor_id
+ self.wall_actor_id = env_creator.wall_actor_id
+ self.gate_bar_actor_id = env_creator.gate_bar_actor_id
+ self.obs_no_gnd_actor_flat_id = torch.cat(
+ (self.orbit_actor_id, self.tree_actor_id, self.wall_actor_id),
+ dim=1,
+ ).flatten()
+ self.obs_all_actor_flat_id = torch.cat(
+ (
+ self.ground_actor_id.flatten(),
+ self.obs_no_gnd_actor_flat_id,
+ self.gate_bar_actor_id.flatten(),
+ )
+ )
+
+ self.actor_pose = torch.zeros(self.num_envs * env_creator.num_actors_per_env, 7)
+ self.vis_data_updated = False
+
+ self.orbit_vis_data: Optional[OrbitVisData] = None
+ self.wall_vis_data: Optional[WallRegionVisData] = None
+
+ def compute(
+ self, waypoint_data: WaypointData, rand_obs_opts: RandObstacleOptions
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Computes a pose tensor holding updated poses for obstacle actors: ground, gate bars,
+ orbit obstacles, trees, and walls. The shape of the pose tensor is
+ (num_envs * num_actors_per_env, 7), every row is: [px, py, pz, qx, qy, qz, qw].
+ Additionally, the flat id of updated actors is returned as 1-dim tensor.
+ Also, the data for visualization is updated.
+
+ Args:
+ waypoint_data: an instance of ``WaypointData``.
+ rand_obs_opts: an instance of ``RandActorOptions``.
+
+ Returns:
+ - Actor pose tensor (num_envs * num_actors_per_env, 7).
+ - Flat id of updated obstacle actors.
+ """
+
+ # only for 4-waypoint envs, and only wp[0] and wp[1] will be given gates
+ assert waypoint_data.num_envs == self.num_envs
+ assert waypoint_data.num_waypoints == 4
+
+ # refresh the pose tensor, move all actors to backstage
+ self.actor_pose[:, :3] = torch.rand_like(
+ self.actor_pose[:, :3]
+ ) * self.env_size - torch.tensor(
+ [
+ self.env_size / 2,
+ self.env_size / 2,
+ self.env_size + self.backstage_z_offset,
+ ]
+ )
+ self.actor_pose[:, 3:7] = torch.tensor([0.0, 0.0, 0.0, 1.0])
+
+ # ========== gate ==========
+
+ # calculate gate bar actors' states
+ enable_gate = waypoint_data.gate_flag >= 0.5
+ gate_hor_bar_len_y = torch.ceil(waypoint_data.width)
+ gate_ver_bar_len_y = torch.ceil(waypoint_data.height)
+ q_hor_to_ver = torch_utils.quat_from_euler_xyz(
+ torch.tensor(pi / 2), torch.tensor(0.0), torch.tensor(0.0)
+ )
+
+ # TODO: whoa! nested loops! what have I done? multiprocessing?
+ for env_id in range(self.num_envs):
+ for wp_id in [1, 2]:
+ for bar_id in range(4):
+ if enable_gate[env_id, wp_id]:
+ wp_p = waypoint_data.position[env_id, wp_id]
+ wp_q = waypoint_data.quaternion[env_id, wp_id]
+ wp_mat = quaternion_to_matrix(wp_q.roll(1))
+ wp_axis_y = wp_mat[:, 1]
+ wp_axis_z = wp_mat[:, 2]
+
+ bar_len_x = self.gate_bar_len_x[
+ int(waypoint_data.gate_x_len_choice[env_id, wp_id].round())
+ ]
+ bar_len_z = self.gate_bar_len_z[
+ int(waypoint_data.gate_weight_choice[env_id, wp_id].round())
+ ]
+
+ if bar_id == 0:
+ # 0: horizontal top (z+)
+ bar_len_y = gate_hor_bar_len_y[env_id, wp_id]
+ actor_q = wp_q
+ actor_p = (
+ wp_p
+ + wp_axis_z
+ * (waypoint_data.height[env_id, wp_id] + bar_len_z)
+ / 2
+ )
+ elif bar_id == 1:
+ # 1: horizontal bottom (z-)
+ bar_len_y = gate_hor_bar_len_y[env_id, wp_id]
+ actor_q = wp_q
+ actor_p = (
+ wp_p
+ - wp_axis_z
+ * (waypoint_data.height[env_id, wp_id] + bar_len_z)
+ / 2
+ )
+ elif bar_id == 2:
+ # 2: vertical left (y+)
+ bar_len_y = gate_ver_bar_len_y[env_id, wp_id]
+ actor_q = torch_utils.quat_mul(wp_q, q_hor_to_ver)
+ actor_p = (
+ wp_p
+ + wp_axis_y
+ * (waypoint_data.width[env_id, wp_id] + bar_len_z)
+ / 2
+ )
+ else:
+ # 3: vertical right (y-)
+ bar_len_y = gate_ver_bar_len_y[env_id, wp_id]
+ actor_q = torch_utils.quat_mul(wp_q, q_hor_to_ver)
+ actor_p = (
+ wp_p
+ - wp_axis_y
+ * (waypoint_data.width[env_id, wp_id] + bar_len_z)
+ / 2
+ )
+
+ actor_name = get_gate_actor_name(
+ wp_id, bar_len_x, float(bar_len_y), bar_len_z, bar_id
+ )
+ gate_actor_id = self.gym.find_actor_index(
+ self.envs[env_id], actor_name, DOMAIN_SIM
+ )
+ self.actor_pose[gate_actor_id, :3] = actor_p
+ self.actor_pose[gate_actor_id, 3:7] = actor_q
+
+ # ========== orbit, trees, walls ==========
+
+ # calculate orbit spheres
+ r_wp = (
+ waypoint_data.width**2 + waypoint_data.height**2
+ ) ** 0.5 + rand_obs_opts.extra_clearance # (num_envs, num_waypoints)
+ r_orbit_min = r_wp[:, :2] # (num_envs, 2)
+ r_orbit_max = waypoint_data.r[:, :2] - r_wp[:, 1:3]
+ r_orbit_max.clamp_(min=r_orbit_min)
+ r_orbit_range = r_orbit_max - r_orbit_min
+ r_orbit_mean = (r_orbit_max + r_orbit_min) / 2
+
+ # calculate total number of actors for each category to put onto stage
+ orbit_area = 4 * pi * torch.linalg.norm(r_orbit_mean, dim=1) ** 2
+ tree_length = torch.sum(r_orbit_range, dim=1)
+ wall_area = torch.linalg.norm(waypoint_data.r[:, :2], dim=1) ** 2
+
+ num_orbit = orbit_area * rand_obs_opts.orbit_density
+ num_trees = tree_length * rand_obs_opts.tree_density
+ num_walls = wall_area * rand_obs_opts.wall_density
+
+ torch.ceil(input=num_orbit, out=num_orbit)
+ torch.ceil(input=num_trees, out=num_trees)
+ torch.ceil(input=num_walls, out=num_walls)
+
+ num_orbit_env_total = int(self.orbit_actor_id.shape[1])
+ num_trees_env_total = int(self.tree_actor_id.shape[1])
+ num_walls_env_total = int(self.wall_actor_id.shape[1])
+
+ num_orbit.clamp_(max=num_orbit_env_total)
+ num_trees.clamp_(max=num_trees_env_total)
+ num_walls.clamp_(max=num_walls_env_total)
+
+ # loop through envs to fill in state buffer
+ # TODO: this is too slow for large num of envs
+ square_vis_q = torch.zeros(self.num_envs, 2, 4)
+ for i in range(self.num_envs):
+ # allocate actor id
+ if self.orbit_actor_id.shape[1] == 0:
+ init_orbit_actor_id = 0
+ else:
+ init_orbit_actor_id = int(self.orbit_actor_id[i, 0])
+ num_orbit_list, orbit_actor_id_list = allocate_actor_id(
+ int(num_orbit[i]),
+ num_orbit_env_total,
+ init_orbit_actor_id,
+ float(r_orbit_mean[i, 0] ** 2),
+ float(r_orbit_mean[i, 1] ** 2),
+ )
+
+ if self.tree_actor_id.shape[1] == 0:
+ init_tree_actor_id = 0
+ else:
+ init_tree_actor_id = int(self.tree_actor_id[i, 0])
+ num_trees_list, tree_actor_id_list = allocate_actor_id(
+ int(num_trees[i]),
+ num_trees_env_total,
+ init_tree_actor_id,
+ float(r_orbit_range[i, 0]),
+ float(r_orbit_range[i, 1]),
+ )
+
+ if self.wall_actor_id.shape[1] == 0:
+ init_wall_actor_id = 0
+ else:
+ init_wall_actor_id = int(self.wall_actor_id[i, 0])
+ num_walls_list, wall_actor_id_list = allocate_actor_id(
+ int(num_walls[i]),
+ num_walls_env_total,
+ init_wall_actor_id,
+ float(waypoint_data.r[i, 0] ** 2),
+ float(waypoint_data.r[i, 1] ** 2),
+ )
+
+ # sample and calculate actors' state
+ for j in range(2):
+ # orbit
+ psi_rand = torch.rand(num_orbit_list[j]) * 2 * pi
+ theta_rand = torch.arcsin(2 * torch.rand(num_orbit_list[j]) - 1)
+ r_std_dev = r_orbit_range[i, j] / 6 * rand_obs_opts.std_dev_scale
+ r_rand = torch.randn(num_orbit_list[j]) * r_std_dev + r_orbit_mean[i, j]
+ q_rand = torch.rand(num_orbit_list[j], 4)
+ q_rand /= torch.linalg.norm(q_rand, dim=1, keepdim=True)
+
+ self.actor_pose[orbit_actor_id_list[j], 0] = (
+ r_rand * torch.cos(theta_rand) * torch.cos(psi_rand)
+ + waypoint_data.position[i, j, 0]
+ )
+ self.actor_pose[orbit_actor_id_list[j], 1] = (
+ r_rand * torch.cos(theta_rand) * torch.sin(psi_rand)
+ + waypoint_data.position[i, j, 1]
+ )
+ self.actor_pose[orbit_actor_id_list[j], 2] = (
+ r_rand * torch.sin(theta_rand) + waypoint_data.position[i, j, 2]
+ )
+ self.actor_pose[orbit_actor_id_list[j], 3:7] = q_rand
+
+ # tree
+ x_rand = (
+ torch.rand(num_trees_list[j]) * r_orbit_range[i, j]
+ + r_orbit_min[i, j]
+ )
+ roll_rand = torch.rand(num_trees_list[j]) * 2 * pi
+
+ vec_x = waypoint_data.position[i, j + 1] - waypoint_data.position[i, j]
+ self.actor_pose[tree_actor_id_list[j], :3] = (
+ x_rand.unsqueeze(1) * vec_x / torch.linalg.norm(vec_x)
+ + waypoint_data.position[i, j]
+ )
+
+ q = torch_utils.quat_mul(
+ waypoint_data.quaternion[i, j],
+ torch_utils.quat_from_euler_xyz(
+ torch.zeros_like(waypoint_data.theta[i, j]),
+ -waypoint_data.theta[i, j],
+ waypoint_data.psi[i, j],
+ ),
+ )
+ local_coord_q = torch.zeros(num_trees_list[j], 4)
+ local_coord_q[:] = q
+ rot_q_rand = torch_utils.quat_from_euler_xyz(
+ roll_rand,
+ torch.zeros_like(roll_rand),
+ torch.zeros_like(roll_rand),
+ )
+ self.actor_pose[tree_actor_id_list[j], 3:7] = torch_utils.quat_mul(
+ local_coord_q, rot_q_rand
+ )
+
+ # wall
+ yz_rand = (
+ torch.rand(num_walls_list[j], 2) * waypoint_data.r[i, j]
+ - waypoint_data.r[i, j] / 2
+ ) * rand_obs_opts.wall_dist_scale
+ x_rand = (
+ torch.randn(num_walls_list[j]) * waypoint_data.r[i, j] / 6
+ + waypoint_data.r[i, j] / 2
+ )
+
+ self.actor_pose[wall_actor_id_list[j], 3:7] = q
+ local_coord_mat = quaternion_to_matrix(q.roll(1))
+ vec_x = local_coord_mat[:, 0]
+ vec_y = local_coord_mat[:, 1]
+ vec_z = local_coord_mat[:, 2]
+ self.actor_pose[wall_actor_id_list[j], :3] = (
+ x_rand.unsqueeze(1) * vec_x
+ + yz_rand[:, 0].unsqueeze(1) * vec_y
+ + yz_rand[:, 1].unsqueeze(1) * vec_z
+ + waypoint_data.position[i, j]
+ )
+ square_vis_q[i, j] = q
+
+ # remove obstacles too close to waypoints
+ actor_pose = self.actor_pose[self.obs_no_gnd_actor_flat_id].view(
+ self.num_envs, -1, 7
+ )
+ actor_pos = actor_pose[:, :, :3]
+ wp_pos_check = waypoint_data.position[:, :3]
+ dist = torch.linalg.norm(
+ actor_pos.unsqueeze(2) - wp_pos_check.unsqueeze(1), dim=-1
+ )
+ wp_safe_dist: torch.Tensor = r_wp[:, :3]
+ too_close = (dist < wp_safe_dist.unsqueeze(1)).any(dim=-1)
+ actor_pose[:, :, 2] = torch.where(
+ too_close, -self.env_size - self.backstage_z_offset, actor_pose[:, :, 2]
+ )
+
+ self.actor_pose[self.obs_no_gnd_actor_flat_id] = actor_pose.view(-1, 7)
+
+ # ========== ground ==========
+
+ wp_pos_z = waypoint_data.position[:, :, -1]
+ wp_pos_z_safe = wp_pos_z - r_wp
+ wp_pos_z_safe_min = torch.min(wp_pos_z_safe, dim=-1).values
+ gnd_z_max = wp_pos_z_safe_min - rand_obs_opts.gnd_distance_min # (num_envs, )
+ gnd_z_min = wp_pos_z_safe_min - rand_obs_opts.gnd_distance_max
+ gnd_z_range = gnd_z_max - gnd_z_min
+ gnd_z_rand = torch.rand(self.num_envs) * gnd_z_range + gnd_z_min
+ gnd_z_rand.clamp_(min=-self.backstage_z_offset)
+ self.actor_pose[self.ground_actor_id.flatten(), :2] = 0
+ self.actor_pose[self.ground_actor_id.flatten(), 2] = gnd_z_rand
+
+ # ========== visualization ==========
+
+ # create visualization data
+ self.orbit_vis_data = OrbitVisData(
+ position=waypoint_data.position[:, :2],
+ r_min=r_orbit_min,
+ r_mean=r_orbit_mean,
+ r_max=r_orbit_max,
+ )
+ self.wall_vis_data = WallRegionVisData(
+ position=(waypoint_data.position[:, :2] + waypoint_data.position[:, 1:3])
+ / 2,
+ quaternion=square_vis_q,
+ dim=waypoint_data.r[:, :2],
+ )
+ self.vis_data_updated = True
+
+ return self.actor_pose, self.obs_all_actor_flat_id
+
+ def get_vis_data(self) -> Tuple[OrbitVisData, WallRegionVisData]:
+ assert self.vis_data_updated is True
+ return self.orbit_vis_data, self.wall_vis_data
+
+
+def allocate_actor_id(
+ num_to_alloc: int,
+ num_env_total: int,
+ init_actor_id: int,
+ portion_0: float,
+ portion_1: float,
+) -> Tuple[List[int], List[torch.Tensor]]:
+ if portion_0 + portion_1 == 0:
+ num_0 = num_1 = 0
+ else:
+ num_0 = min(
+ num_to_alloc, int(num_to_alloc * portion_0 / (portion_0 + portion_1))
+ )
+ num_1 = num_to_alloc - num_0
+
+ permuted_actor_id = torch.randperm(num_env_total) + init_actor_id
+ alloc_actor_id = [
+ permuted_actor_id[:num_0],
+ permuted_actor_id[num_0:num_to_alloc],
+ ]
+
+ return [num_0, num_1], alloc_actor_id
diff --git a/isaacgymenvs/tasks/drone_racing/mdp/__init__.py b/isaacgymenvs/tasks/drone_racing/mdp/__init__.py
new file mode 100644
index 000000000..f19c13094
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/mdp/__init__.py
@@ -0,0 +1,2 @@
+from .observation import ObservationParams, Observation
+from .reward import RewardParams, Reward
diff --git a/isaacgymenvs/tasks/drone_racing/mdp/observation.py b/isaacgymenvs/tasks/drone_racing/mdp/observation.py
new file mode 100644
index 000000000..299b4b801
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/mdp/observation.py
@@ -0,0 +1,229 @@
+from dataclasses import dataclass
+from typing import List, Tuple, Optional
+
+import torch
+
+from isaacgym import gymapi
+from isaacgymenvs.utils.torch_jit_utils import (
+ quaternion_to_matrix,
+ quat_rotate_inverse,
+)
+from ..waypoint import WaypointData
+
+
+@dataclass
+class ObservationParams:
+ # number of parallel envs
+ num_envs: int = 64
+
+ # device to run tensor
+ device: str = "cuda"
+
+ # action dim
+ dim_action: int = 4
+
+ # drone position relative to start is clamped and normalized (m)
+ pos_max: float = 40.0
+
+ # vel of each channel is clamped at this value and normalized (m/s)
+ vel_max: float = 20.0
+
+ # angular vel of each channel is also clamped and normalized (rad/s)
+ ang_vel_max: float = 6 * torch.pi
+
+ # distances to waypoint corners are as well clamped and normalized (m)
+ dist_to_corner_max: float = 25.0
+
+
+class Observation:
+
+ def __init__(self, params: ObservationParams):
+ self.params = params
+ self.all_env_id = torch.arange(params.num_envs, device=params.device)
+
+ self.cam_tf_tensor = torch.zeros(params.num_envs, 12, device=params.device)
+
+ self.init_drone_pos = torch.zeros(params.num_envs, 3, device=params.device)
+ self.last_action = torch.zeros(
+ params.num_envs, params.dim_action, device=params.device
+ )
+
+ self.wp_x_axis: Optional[torch.Tensor] = None
+ self.wp_corner_pos: Optional[torch.Tensor] = None
+ self.wp_center_pos: Optional[torch.Tensor] = None
+
+ def set_waypoint_and_cam(
+ self, wp_data: WaypointData, cam_tf: List[gymapi.Transform]
+ ):
+ # extract useful waypoint info
+ num_waypoints = wp_data.num_waypoints
+ wp_x_axis = torch.zeros(self.params.num_envs, num_waypoints, 3)
+ wp_corner_pos = torch.zeros(self.params.num_envs, num_waypoints, 4, 3)
+
+ for i in range(num_waypoints):
+ # loop through waypoints, envs are still vectorized
+ wp_q = wp_data.quaternion[:, i]
+ wp_mat = quaternion_to_matrix(wp_q.roll(1, dims=1))
+ wp_x_axis[:, i] = wp_mat[:, :, 0] # (num_envs, 3)
+
+ wp_p = wp_data.position[:, i]
+ dw = wp_data.width[:, i].unsqueeze(1) / 2
+ dh = wp_data.height[:, i].unsqueeze(1) / 2
+ # upper left corner
+ wp_corner_pos[:, i, 0] = wp_p + wp_mat[:, :, 1] * dw + wp_mat[:, :, 2] * dh
+ # upper right corner
+ wp_corner_pos[:, i, 1] = wp_p - wp_mat[:, :, 1] * dw + wp_mat[:, :, 2] * dh
+ # lower right corner
+ wp_corner_pos[:, i, 2] = wp_p - wp_mat[:, :, 1] * dw - wp_mat[:, :, 2] * dh
+ # lower left corner
+ wp_corner_pos[:, i, 3] = wp_p + wp_mat[:, :, 1] * dw - wp_mat[:, :, 2] * dh
+
+ self.wp_x_axis = wp_x_axis.to(device=self.params.device)
+ self.wp_corner_pos = wp_corner_pos.to(device=self.params.device)
+ self.wp_center_pos = wp_data.position.to(device=self.params.device)
+
+ # update cam_tf_tensor
+ # TODO: optimize for large number of envs
+ for i in range(self.params.num_envs):
+ self.cam_tf_tensor[i, :3] = torch.tensor(
+ [cam_tf[i].p.x, cam_tf[i].p.y, cam_tf[i].p.z], device=self.params.device
+ )
+ cam_q = torch.tensor(
+ [cam_tf[i].r.x, cam_tf[i].r.y, cam_tf[i].r.z, cam_tf[i].r.w],
+ device=self.params.device,
+ )
+ cam_mat = quaternion_to_matrix(cam_q.roll(1))
+ self.cam_tf_tensor[i, 3:] = cam_mat.flatten()
+
+ self.cam_tf_tensor.clamp_(min=-1.0, max=1.0)
+
+ def set_init_drone_state_action(
+ self,
+ drone_state: torch.Tensor,
+ action: torch.Tensor,
+ env_id: torch.Tensor = None,
+ ):
+ if env_id is None:
+ env_id = self.all_env_id
+
+ self.init_drone_pos[env_id] = drone_state[env_id, :3]
+ self.last_action[env_id] = action[env_id]
+
+ def compute(
+ self,
+ drone_state: torch.Tensor,
+ next_wp_id: torch.Tensor,
+ action: torch.Tensor,
+ ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
+ """
+ Computes observation terms. The waypoint info tensor is in (num_envs, 34), whose
+ ``[:17]`` of last dim is the next waypoint's: [``cos_sim`` (1), ``dist_to_corners`` (4),
+ ``unit_vec_to_corners`` (12)], and ``[17:]`` is the same info for the further next waypoint.
+
+ Args:
+ drone_state: full drone state tensor in (num_envs, 13).
+ next_wp_id: 1-dim int tensor indicating next wp id in (num_envs, ).
+ action: current action tensor in (num_envs, dim_action).
+
+ Returns:
+ - Flat drone state (normalized) [p, R, v, w] tensor in (num_envs, 18).
+ - Camera pose (clamped -1 to 1) (p, R) in body frame tensor in (num_envs, 12).
+ - Waypoint info (with dist normalized) tensor in (num_envs, 34).
+ - Last action in (num_envs, dim_action).
+ """
+
+ flat_drone_state, wp_info, last_action = _compute_script(
+ pos_max=self.params.pos_max,
+ vel_max=self.params.vel_max,
+ ang_vel_max=self.params.ang_vel_max,
+ dist_to_corner_max=self.params.dist_to_corner_max,
+ wp_x_axis=self.wp_x_axis,
+ wp_corner_pos=self.wp_corner_pos,
+ wp_center_pos=self.wp_center_pos,
+ init_drone_p=self.init_drone_pos,
+ last_action=self.last_action,
+ all_env_id=self.all_env_id,
+ drone_state=drone_state,
+ next_wp_id=next_wp_id,
+ )
+ self.last_action[:] = action
+
+ return flat_drone_state, self.cam_tf_tensor, wp_info, last_action
+
+
+@torch.jit.script
+def _compute_script(
+ pos_max: float,
+ vel_max: float,
+ ang_vel_max: float,
+ dist_to_corner_max: float,
+ wp_x_axis: torch.Tensor,
+ wp_corner_pos: torch.Tensor,
+ wp_center_pos: torch.Tensor,
+ init_drone_p: torch.Tensor,
+ last_action: torch.Tensor,
+ all_env_id: torch.Tensor,
+ drone_state: torch.Tensor,
+ next_wp_id: torch.Tensor,
+) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
+ # flat drone state tensor (num_envs, 18)
+ drone_p = drone_state[:, :3]
+ drone_q = drone_state[:, 3:7]
+ drone_r_mat = quaternion_to_matrix(drone_q.roll(1, dims=1))
+ drone_ang_vel_b = quat_rotate_inverse(drone_q, drone_state[:, 10:])
+ flat_drone_state = torch.cat(
+ (
+ torch.clamp((drone_p - init_drone_p) / pos_max, min=-1, max=1),
+ drone_r_mat.transpose(1, 2).flatten(1), # better readability after flatten
+ torch.clamp(drone_state[:, 7:10] / vel_max, min=-1, max=1),
+ torch.clamp(drone_ang_vel_b / ang_vel_max, min=-1, max=1),
+ ),
+ dim=1,
+ )
+
+ # waypoint info tensor (num_envs, 34)
+ wp_info = torch.zeros(wp_x_axis.shape[0], 34, device=wp_x_axis.device)
+ max_wp_id = wp_x_axis.shape[1] - 1
+ for i in range(2):
+ # we need info of two future waypoints
+ wp_id = next_wp_id + i
+ wp_id.clamp_(max=max_wp_id)
+
+ # cosine similarity between wp x-axis and vector to wp center
+ next_wp_x_axis = wp_x_axis[all_env_id, wp_id] # (num_envs, 3)
+ next_wp_center = wp_center_pos[all_env_id, wp_id]
+ vec_to_center = next_wp_center - drone_p
+ cos_sim = torch.sum(next_wp_x_axis * vec_to_center, dim=-1) / (
+ torch.linalg.norm(next_wp_x_axis, dim=-1)
+ * torch.linalg.norm(vec_to_center, dim=-1)
+ )
+ cos_sim.nan_to_num_(nan=0.0)
+
+ # relative corner position in drone body frame
+ next_wp_corners = wp_corner_pos[all_env_id, wp_id] # (num_envs, 4, 3)
+ vec_to_corners_w = next_wp_corners - drone_p.unsqueeze(1) # (num_envs, 4, 3)
+ dist_to_corners = torch.linalg.norm(
+ vec_to_corners_w, dim=-1, keepdim=True
+ ) # (num_envs, 4, 1)
+ q = drone_q.unsqueeze(1).expand(-1, 4, -1)
+ vec_to_corners_b = quat_rotate_inverse(
+ q.reshape(-1, 4), vec_to_corners_w.view(-1, 3)
+ ).view(-1, 4, 3)
+ unit_vec_b = vec_to_corners_b / dist_to_corners # (num_envs, 4, 3)
+ unit_vec_b.nan_to_num_(nan=0.0)
+
+ # update wp_info tensor
+ data_id_start = i * 17
+ data_id_end = (i + 1) * 17
+ wp_info[:, data_id_start:data_id_end] = torch.cat(
+ (
+ cos_sim.view(-1, 1),
+ torch.clamp(
+ dist_to_corners.view(-1, 4) / dist_to_corner_max, min=0, max=1
+ ),
+ unit_vec_b.view(-1, 12),
+ ),
+ dim=-1,
+ )
+
+ return flat_drone_state, wp_info, last_action
diff --git a/isaacgymenvs/tasks/drone_racing/mdp/reward.py b/isaacgymenvs/tasks/drone_racing/mdp/reward.py
new file mode 100644
index 000000000..308882a20
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/mdp/reward.py
@@ -0,0 +1,335 @@
+from dataclasses import dataclass
+from typing import Tuple, Optional, List
+
+import torch
+
+from isaacgym import gymapi
+from isaacgymenvs.utils.torch_jit_utils import (
+ quaternion_to_matrix,
+ quat_mul,
+ quat_rotate,
+ quat_rotate_inverse,
+)
+from ..waypoint import WaypointData
+
+
+@dataclass
+class RewardParams:
+ # number of parallel envs
+ num_envs: int = 64
+
+ # device to run tensor
+ device: str = "cuda"
+
+ # progress reward coefficient (swift: 1.0)
+ k_progress: float = 1.0
+
+ # perception reward coefficient (swift: 0.02)
+ k_perception: float = 0.02
+
+ # camera deviation coefficient (swift: -10)
+ k_cam_dev: float = -10.0
+
+ # cmd reward (ang vel part) coefficient (swift: -2e-4)
+ k_cmd_ang_vel: float = -2e-4
+
+ # cmd reward (diff) coefficient (swift: -1e-4)
+ k_cmd_diff: float = -1e-4
+
+ # collision reward coefficient (swift: -5)
+ k_collision: float = -5.0
+
+ # guidance reward coefficient
+ k_guidance: float = 1.0
+
+ # rejection coefficient
+ k_rejection: float = 2.0
+
+ # waypoint passing reward coefficient
+ k_waypoint: float = 2.5
+
+ # timeout reward coefficient
+ k_timeout: float = -5.0
+
+ # guidance x threshold
+ guidance_x_thresh: float = 3.0
+
+ # guidance tolerance
+ guidance_tol: float = 1 / 8
+
+ # enable progress reward normalization by distance
+ # turning it on smoothes the progress reward when parallel envs are different
+ enable_normalization: bool = False
+
+
+class Reward:
+
+ def __init__(self, params: RewardParams):
+ self.params = params
+ self.all_env_id = torch.arange(params.num_envs, device=params.device)
+
+ self.cam_tf_p = torch.zeros(params.num_envs, 3, device=params.device)
+ self.cam_tf_q = torch.zeros(params.num_envs, 4, device=params.device)
+
+ self.last_dist_to_wp = torch.zeros(params.num_envs, device=params.device)
+ self.last_action = torch.zeros(params.num_envs, 4, device=params.device)
+
+ self.reward_progress = torch.zeros(params.num_envs, device=params.device)
+ self.reward_perception = torch.zeros(params.num_envs, device=params.device)
+ self.reward_cmd = torch.zeros(params.num_envs, device=params.device)
+ self.reward_collision = torch.zeros(params.num_envs, device=params.device)
+ self.reward_guidance = torch.zeros(params.num_envs, device=params.device)
+ self.reward_waypoint = torch.zeros(params.num_envs, device=params.device)
+ self.reward_timeout = torch.zeros(params.num_envs, device=params.device)
+
+ self.wp_position: Optional[torch.Tensor] = None
+ self.wp_quaternion: Optional[torch.Tensor] = None
+ self.wp_width: Optional[torch.Tensor] = None
+ self.wp_height: Optional[torch.Tensor] = None
+ self.wp_r_sum: Optional[torch.Tensor] = None
+
+ def set_waypoint_and_cam(
+ self, wp_data: WaypointData, cam_tf: List[gymapi.Transform]
+ ):
+ assert self.params.num_envs == wp_data.num_envs
+
+ self.wp_position = wp_data.position.to(device=self.params.device)
+ self.wp_quaternion = wp_data.quaternion.to(device=self.params.device)
+ self.wp_width = wp_data.width.to(device=self.params.device)
+ self.wp_height = wp_data.height.to(device=self.params.device)
+ self.wp_r_sum = torch.sum(
+ wp_data.r[:, :-1].to(device=self.params.device), dim=-1
+ )
+
+ for i in range(len(cam_tf)):
+ self.cam_tf_p[i] = torch.tensor(
+ [cam_tf[i].p.x, cam_tf[i].p.y, cam_tf[i].p.z], device=self.params.device
+ )
+ self.cam_tf_q[i] = torch.tensor(
+ [cam_tf[i].r.x, cam_tf[i].r.y, cam_tf[i].r.z, cam_tf[i].r.w],
+ device=self.params.device,
+ )
+
+ def set_init_drone_state_action(
+ self,
+ drone_state: torch.Tensor,
+ action: torch.Tensor,
+ env_id: torch.Tensor = None,
+ ):
+ if env_id is None:
+ env_id = self.all_env_id
+
+ drone_pos = drone_state[env_id, :3]
+ wp_pos = self.wp_position[env_id, 1]
+ self.last_dist_to_wp[env_id] = torch.linalg.norm(wp_pos - drone_pos, dim=1)
+ self.last_action[env_id] = action[env_id]
+
+ def compute(
+ self,
+ drone_state: torch.Tensor,
+ action: torch.Tensor,
+ drone_collision: torch.Tensor,
+ timeout: torch.Tensor,
+ wp_passing: torch.Tensor,
+ next_wp_id: torch.Tensor,
+ ) -> torch.Tensor:
+ """
+ Computes the total reward and updates reward terms, which can be accessed later by user.
+
+ Args:
+ drone_state: full drone state tensor in (num_envs, 13) [p, q, v, w], here w is in world frame.
+ action: action tensor in (num_envs, 4).
+ drone_collision: 1-dim bool tensor indicating presence of collision in (num_envs, ).
+ timeout: 1-dim bool tensor indicating timeout in (num_envs, ).
+ wp_passing: 1-dim bool tensor indicating waypoint passing in (num_envs, ).
+ next_wp_id: 1-dim int tensor indicating next wp id in (num_envs, ).
+
+ Returns:
+ - Reward tensor for all envs in (num_envs, ).
+ """
+
+ (
+ self.reward_progress[:],
+ self.reward_perception[:],
+ self.reward_cmd[:],
+ self.reward_collision[:],
+ self.reward_guidance[:],
+ self.reward_waypoint[:],
+ self.reward_timeout[:],
+ self.last_dist_to_wp[:],
+ self.last_action[:],
+ ) = _compute_script(
+ k_progress=self.params.k_progress,
+ k_perception=self.params.k_perception,
+ k_cam_dev=self.params.k_cam_dev,
+ k_cmd_ang_vel=self.params.k_cmd_ang_vel,
+ k_cmd_diff=self.params.k_cmd_diff,
+ k_collision=self.params.k_collision,
+ k_guidance=self.params.k_guidance,
+ k_rejection=self.params.k_rejection,
+ k_waypoint=self.params.k_waypoint,
+ k_timeout=self.params.k_timeout,
+ guidance_x_thresh=self.params.guidance_x_thresh,
+ guidance_tol=self.params.guidance_tol,
+ enable_normalization=self.params.enable_normalization,
+ wp_position=self.wp_position,
+ wp_quaternion=self.wp_quaternion,
+ wp_width=self.wp_width,
+ wp_height=self.wp_height,
+ wp_r_sum=self.wp_r_sum,
+ all_env_id=self.all_env_id,
+ cam_tf_p=self.cam_tf_p,
+ cam_tf_q=self.cam_tf_q,
+ last_dist_to_wp=self.last_dist_to_wp,
+ last_action=self.last_action,
+ drone_state=drone_state,
+ action=action,
+ drone_collision=drone_collision,
+ timeout=timeout,
+ wp_passing=wp_passing,
+ next_wp_id=next_wp_id,
+ )
+
+ reward = (
+ self.reward_progress
+ + self.reward_perception
+ + self.reward_cmd
+ + self.reward_collision
+ + self.reward_guidance
+ + self.reward_waypoint
+ + self.reward_timeout
+ )
+
+ return reward
+
+
+@torch.jit.script
+def _compute_script(
+ k_progress: float,
+ k_perception: float,
+ k_cam_dev: float,
+ k_cmd_ang_vel: float,
+ k_cmd_diff: float,
+ k_collision: float,
+ k_guidance: float,
+ k_rejection: float,
+ k_waypoint: float,
+ k_timeout: float,
+ guidance_x_thresh: float,
+ guidance_tol: float,
+ enable_normalization: bool,
+ wp_position: torch.Tensor,
+ wp_quaternion: torch.Tensor,
+ wp_width: torch.Tensor,
+ wp_height: torch.Tensor,
+ wp_r_sum: torch.Tensor,
+ all_env_id: torch.Tensor,
+ cam_tf_p: torch.Tensor,
+ cam_tf_q: torch.Tensor,
+ last_dist_to_wp: torch.Tensor,
+ last_action: torch.Tensor,
+ drone_state: torch.Tensor,
+ action: torch.Tensor,
+ drone_collision: torch.Tensor,
+ timeout: torch.Tensor,
+ wp_passing: torch.Tensor,
+ next_wp_id: torch.Tensor,
+) -> Tuple[
+ torch.Tensor,
+ torch.Tensor,
+ torch.Tensor,
+ torch.Tensor,
+ torch.Tensor,
+ torch.Tensor,
+ torch.Tensor,
+ torch.Tensor,
+ torch.Tensor,
+]:
+ # progress reward
+ drone_pos = drone_state[:, :3] # (num_envs, 3)
+ wp_pos = wp_position[all_env_id, next_wp_id] # (num_envs, 3)
+ dist_to_wp = torch.linalg.norm(wp_pos - drone_pos, dim=1) # (num_envs, )
+
+ # wp1 wp2
+ # O--------------|------>O |
+ # |<---last_d--->| |<--------this_d-------->|
+ # ^ here wp_passing = True, and next_wp_id = 2
+ # set progress to 0 at wp passing step
+ # to avoid undesired negative progress
+ reward_progress = k_progress * (last_dist_to_wp - dist_to_wp) * (~wp_passing)
+
+ # perception reward
+ drone_q = drone_state[:, 3:7]
+ cam_q = quat_mul(drone_q, cam_tf_q)
+ cam_mat = quaternion_to_matrix(cam_q.roll(1, dims=1))
+ cam_x_axis = cam_mat[:, :, 0]
+
+ cam_pos = drone_pos + quat_rotate(cam_tf_q, cam_tf_p)
+ vec_cam_to_wp = wp_pos - cam_pos
+ dist_cam_to_wp = torch.linalg.norm(vec_cam_to_wp, dim=-1)
+
+ cam_dev = torch.acos(torch.sum(cam_x_axis * vec_cam_to_wp, dim=-1) / dist_cam_to_wp)
+ cam_dev.nan_to_num_(nan=0.0)
+
+ reward_perception = k_perception * torch.exp(k_cam_dev * cam_dev**4)
+
+ # angular velocity reward
+ reward_cmd = k_cmd_ang_vel * torch.linalg.norm(
+ action[:, [0, 1, 3]], dim=1
+ ) + k_cmd_diff * torch.linalg.norm(action - last_action, dim=1)
+
+ # collision reward
+ reward_collision = k_collision * drone_collision
+
+ # guidance reward
+ # TODO: use positive guidance?
+ wp_to_drone = drone_pos - wp_pos
+ wp_q = wp_quaternion[all_env_id, next_wp_id]
+ drone_pos_wp_frame = quat_rotate_inverse(wp_q, wp_to_drone)
+ x, y, z = (
+ drone_pos_wp_frame[:, 0],
+ drone_pos_wp_frame[:, 1],
+ drone_pos_wp_frame[:, 2],
+ )
+ w = wp_width[all_env_id, next_wp_id]
+ h = wp_height[all_env_id, next_wp_id]
+
+ layer_x = -torch.sign(x) / guidance_x_thresh * x + 1
+ layer_x.clamp_(min=0.0)
+ guidance_x = -(layer_x**2)
+
+ tol = torch.where(x > 0, 0.5, guidance_tol)
+ yz_scale = (
+ (1 - guidance_x) * tol * ((z**2 + y**2) / ((z / h) ** 2 + (y / w) ** 2)) ** 0.5
+ )
+ yz_scale.nan_to_num_(nan=1.0) # caused by z**2 + y**2 == 0
+ guidance_yz = torch.where(
+ x > 0,
+ k_rejection * torch.exp(-0.5 * (y**2 + z**2) / yz_scale),
+ (1 - torch.exp(-0.5 * (y**2 + z**2) / yz_scale)),
+ )
+
+ guidance = guidance_x * guidance_yz
+ reward_guidance = k_guidance * guidance
+
+ # waypoint passing reward
+ reward_waypoint = k_waypoint * wp_passing
+
+ # timeout reward
+ reward_timeout = k_timeout * timeout
+
+ # normalization
+ if enable_normalization:
+ reward_progress /= wp_r_sum
+
+ return (
+ reward_progress,
+ reward_perception,
+ reward_cmd,
+ reward_collision,
+ reward_guidance,
+ reward_waypoint,
+ reward_timeout,
+ dist_to_wp,
+ action,
+ )
diff --git a/isaacgymenvs/tasks/drone_racing/rlgpu.yaml b/isaacgymenvs/tasks/drone_racing/rlgpu.yaml
new file mode 100644
index 000000000..85314a233
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/rlgpu.yaml
@@ -0,0 +1,267 @@
+name: rlgpu
+channels:
+ - conda-forge
+dependencies:
+ - _libgcc_mutex=0.1=conda_forge
+ - _openmp_mutex=4.5=2_gnu
+ - bzip2=1.0.8=h4bc722e_7
+ - ca-certificates=2024.7.4=hbcca054_0
+ - ld_impl_linux-64=2.40=hf3520f5_7
+ - libffi=3.4.2=h7f98852_5
+ - libgcc-ng=14.1.0=h77fa898_0
+ - libgomp=14.1.0=h77fa898_0
+ - libnsl=2.0.1=hd590300_0
+ - libsqlite=3.46.0=hde9e2c9_0
+ - libuuid=2.38.1=h0b41bf4_0
+ - libxcrypt=4.4.36=hd590300_1
+ - libzlib=1.3.1=h4ab18f5_1
+ - ncurses=6.5=h59595ed_0
+ - openssl=3.3.1=h4bc722e_2
+ - pip=24.2=pyhd8ed1ab_0
+ - python=3.8.19=hd12c33a_0_cpython
+ - readline=8.2=h8228510_1
+ - setuptools=71.0.4=pyhd8ed1ab_0
+ - tk=8.6.13=noxft_h4845f30_101
+ - wheel=0.43.0=pyhd8ed1ab_1
+ - xz=5.2.6=h166bdaf_0
+ - pip:
+ - absl-py==2.1.0
+ - addict==2.4.0
+ - antlr4-python3-runtime==4.9.3
+ - anyio==4.4.0
+ - argon2-cffi==23.1.0
+ - argon2-cffi-bindings==21.2.0
+ - arrow==1.3.0
+ - asttokens==2.4.1
+ - async-lru==2.0.4
+ - attrs==23.2.0
+ - babel==2.15.0
+ - backcall==0.2.0
+ - beautifulsoup4==4.12.3
+ - black==24.4.2
+ - bleach==6.1.0
+ - blinker==1.8.2
+ - cachetools==5.4.0
+ - catkin-pkg==1.0.0
+ - certifi==2024.7.4
+ - cffi==1.16.0
+ - charset-normalizer==3.3.2
+ - click==8.1.7
+ - cloudpickle==3.0.0
+ - colorlog==6.8.2
+ - comm==0.2.2
+ - configargparse==1.7
+ - contourpy==1.1.1
+ - cycler==0.12.1
+ - cython==3.0.11
+ - dash==2.18.1
+ - dash-core-components==2.0.0
+ - dash-html-components==2.0.0
+ - dash-table==5.0.0
+ - debugpy==1.8.2
+ - decorator==5.1.1
+ - defusedxml==0.7.1
+ - distro==1.9.0
+ - docker-pycreds==0.4.0
+ - docutils==0.20.1
+ - exceptiongroup==1.2.2
+ - executing==2.0.1
+ - farama-notifications==0.0.4
+ - fast-pytorch-kmeans==0.2.0.1
+ - faster-fifo==1.4.7
+ - fastjsonschema==2.20.0
+ - filelock==3.15.4
+ - flask==3.0.3
+ - fonttools==4.53.1
+ - fqdn==1.5.1
+ - freetype-py==2.4.0
+ - fsspec==2024.6.1
+ - fvcore==0.1.5.post20221221
+ - gitdb==4.0.11
+ - gitpython==3.1.43
+ - google-auth==2.32.0
+ - google-auth-oauthlib==1.0.0
+ - grpcio==1.65.2
+ - gym==0.23.1
+ - gym-notices==0.0.8
+ - gymnasium==0.29.1
+ - h11==0.14.0
+ - httpcore==1.0.5
+ - httpx==0.27.0
+ - huggingface-hub==0.24.6
+ - hydra-core==1.3.2
+ - idna==3.7
+ - imageio==2.34.2
+ - importlib-metadata==8.2.0
+ - importlib-resources==6.4.0
+ - iopath==0.1.10
+ - ipykernel==6.29.5
+ - ipython==8.12.3
+ - ipywidgets==8.1.3
+ - isoduration==20.11.0
+ - itsdangerous==2.2.0
+ - jedi==0.19.1
+ - jinja2==3.1.4
+ - joblib==1.4.2
+ - json5==0.9.25
+ - jsonpointer==3.0.0
+ - jsonschema==4.23.0
+ - jsonschema-specifications==2023.12.1
+ - jupyter==1.0.0
+ - jupyter-client==8.6.2
+ - jupyter-console==6.6.3
+ - jupyter-core==5.7.2
+ - jupyter-events==0.10.0
+ - jupyter-lsp==2.2.5
+ - jupyter-server==2.14.2
+ - jupyter-server-terminals==0.5.3
+ - jupyterlab==4.2.4
+ - jupyterlab-pygments==0.3.0
+ - jupyterlab-server==2.27.3
+ - jupyterlab-urdf==0.4.0
+ - jupyterlab-widgets==3.0.11
+ - kaleido==0.2.1
+ - kiwisolver==1.4.5
+ - lxml==5.2.2
+ - markdown==3.6
+ - markupsafe==2.1.5
+ - matplotlib==3.7.5
+ - matplotlib-inline==0.1.7
+ - mistune==3.0.2
+ - mpmath==1.3.0
+ - mypy-extensions==1.0.0
+ - nbclient==0.10.0
+ - nbconvert==7.16.4
+ - nbformat==5.10.4
+ - nest-asyncio==1.6.0
+ - networkx==2.2
+ - ninja==1.11.1.1
+ - notebook==7.2.1
+ - notebook-shim==0.2.4
+ - numpy==1.23.0
+ - nvidia-cublas-cu12==12.1.3.1
+ - nvidia-cuda-cupti-cu12==12.1.105
+ - nvidia-cuda-nvrtc-cu12==12.1.105
+ - nvidia-cuda-runtime-cu12==12.1.105
+ - nvidia-cudnn-cu12==9.1.0.70
+ - nvidia-cufft-cu12==11.0.2.54
+ - nvidia-curand-cu12==10.3.2.106
+ - nvidia-cusolver-cu12==11.4.5.107
+ - nvidia-cusparse-cu12==12.1.0.106
+ - nvidia-nccl-cu12==2.20.5
+ - nvidia-nvjitlink-cu12==12.5.82
+ - nvidia-nvtx-cu12==12.1.105
+ - oauthlib==3.2.2
+ - omegaconf==2.3.0
+ - onnx==1.17.0
+ - open3d==0.18.0
+ - opencv-python==4.10.0.84
+ - orjson==3.10.6
+ - overrides==7.7.0
+ - packaging==24.1
+ - pandas==2.0.3
+ - pandocfilters==1.5.1
+ - parso==0.8.4
+ - pathspec==0.12.1
+ - pathtools==0.1.2
+ - pexpect==4.9.0
+ - pickleshare==0.7.5
+ - pillow==10.4.0
+ - pkgutil-resolve-name==1.3.10
+ - platformdirs==4.2.2
+ - plotly==5.23.0
+ - portalocker==2.10.1
+ - prometheus-client==0.20.0
+ - promise==2.3
+ - prompt-toolkit==3.0.47
+ - protobuf==3.20.3
+ - psutil==5.9.8
+ - ptyprocess==0.7.0
+ - pure-eval==0.2.3
+ - pyarrow==17.0.0
+ - pyasn1==0.6.0
+ - pyasn1-modules==0.4.0
+ - pycollada==0.6
+ - pycparser==2.22
+ - pygame==2.1.0
+ - pyglet==2.0.16
+ - pygments==2.18.0
+ - pynvml==11.5.3
+ - pyopengl==3.1.0
+ - pyparsing==3.1.2
+ - pyquaternion==0.9.9
+ - pyrender==0.1.45
+ - pysdf==0.1.9
+ - python-dateutil==2.9.0.post0
+ - graphviz==0.20.3
+ - python-json-logger==2.0.7
+ - pytorch3d==0.3.0
+ - pytz==2024.1
+ - pyvirtualdisplay==3.0
+ - pyyaml==6.0.1
+ - pyzmq==26.0.3
+ - qtconsole==5.5.2
+ - qtpy==2.4.1
+ - referencing==0.35.1
+ - requests==2.32.3
+ - requests-oauthlib==2.0.0
+ - rerun-sdk==0.18.2
+ - retrying==1.3.4
+ - rfc3339-validator==0.1.4
+ - rfc3986-validator==0.1.1
+ - rl-games==1.6.1
+ - rospkg==1.5.1
+ - rpds-py==0.19.1
+ - rsa==4.9
+ - sample-factory==2.1.1
+ - scikit-learn==1.3.2
+ - scipy==1.10.1
+ - seaborn==0.13.2
+ - send2trash==1.8.3
+ - sentry-sdk==2.12.0
+ - setproctitle==1.3.3
+ - shortuuid==1.0.13
+ - signal-slot-mp==1.0.5
+ - six==1.16.0
+ - smmap==5.0.1
+ - sniffio==1.3.1
+ - soupsieve==2.5
+ - stack-data==0.6.3
+ - sympy==1.13.1
+ - tabulate==0.9.0
+ - tenacity==9.0.0
+ - tensorboard==2.14.0
+ - tensorboard-data-server==0.7.2
+ - tensorboardx==2.6.2.2
+ - tensordict==0.5.0
+ - termcolor==2.4.0
+ - terminado==0.18.1
+ - threadpoolctl==3.5.0
+ - tinycss2==1.3.0
+ - tomli==2.0.1
+ - torch==2.4.0
+ - torchrl==0.5.0
+ - torchvision==0.19.0
+ - torchviz==0.0.2
+ - tornado==6.4.1
+ - tqdm==4.66.4
+ - traitlets==5.14.3
+ - trimesh==3.23.5
+ - triton==3.0.0
+ - types-python-dateutil==2.9.0.20240316
+ - typing-extensions==4.12.2
+ - tzdata==2024.1
+ - urdfpy==0.0.22
+ - uri-template==1.3.0
+ - urllib3==2.2.2
+ - wandb==0.12.21
+ - warp-lang==1.0.0
+ - wcwidth==0.2.13
+ - webcolors==24.6.0
+ - webencodings==0.5.1
+ - websocket-client==1.8.0
+ - werkzeug==3.0.3
+ - widgetsnbextension==4.0.11
+ - yacs==0.1.8
+ - zipp==3.19.2
+ - zmq==0.0.0
diff --git a/isaacgymenvs/tasks/drone_racing/tasks/__init__.py b/isaacgymenvs/tasks/drone_racing/tasks/__init__.py
new file mode 100644
index 000000000..30bdc32c8
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/tasks/__init__.py
@@ -0,0 +1,2 @@
+from .dr_asset import DRAsset
+from .dr_random import DRRandom
diff --git a/isaacgymenvs/tasks/drone_racing/tasks/dr_asset.py b/isaacgymenvs/tasks/drone_racing/tasks/dr_asset.py
new file mode 100644
index 000000000..73f5bbd34
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/tasks/dr_asset.py
@@ -0,0 +1,246 @@
+from typing import Dict, Any, Optional, List
+
+import torch
+
+from isaacgym import gymapi
+from isaacgym.gymapi import Vec3, Asset, Transform, AssetOptions
+from isaacgymenvs.tasks.drone_racing.assets import (
+ create_drone_quadcopter,
+ DroneQuadcopterOptions,
+ create_track_rmua,
+ create_track_splits,
+ create_track_walls,
+ create_track_multistory,
+ create_track_geom_kebab,
+ create_track_planar_circle,
+ create_track_wavy_eight,
+ create_track_turns,
+ create_track_simple_stick,
+ create_track_sjtu_3dc,
+ create_track_sjtu_ell,
+ create_track_sjtu_str,
+ TrackMultiStoryOptions,
+ TrackSplitsOptions,
+ TrackWallsOptions,
+ TrackRmuaOptions,
+ TrackGeomKebabOptions,
+ TrackPlanarCircleOptions,
+ TrackWavyEightOptions,
+ TrackTurnsOptions,
+ TrackSimpleStickOptions,
+ TrackSjtu3dcOptions,
+ TrackSjtuEllOptions,
+ TrackSjtuStrOptions,
+)
+from isaacgymenvs.tasks.drone_racing.waypoint import (
+ WaypointData,
+ Waypoint,
+)
+from .dr_default_out import DRDefaultOut
+
+
+class DRAsset(DRDefaultOut):
+
+ def __init__(
+ self,
+ cfg: Dict[str, Any],
+ rl_device: str,
+ sim_device: str,
+ graphics_device_id: int,
+ headless: bool,
+ virtual_screen_capture: bool,
+ force_render: bool,
+ ):
+ self.asset_name = cfg["assetName"]
+ is_asset_name_valid = (
+ self.asset_name == "multistory"
+ or self.asset_name == "rmua"
+ or self.asset_name == "splits"
+ or self.asset_name == "walls"
+ or self.asset_name == "geom_kebab"
+ or self.asset_name == "geom_kebab_no_obst"
+ or self.asset_name == "planar_circle"
+ or self.asset_name == "planar_circle_no_obst"
+ or self.asset_name == "wavy_eight"
+ or self.asset_name == "wavy_eight_no_obst"
+ or self.asset_name == "turns"
+ or self.asset_name == "simple_stick"
+ or self.asset_name == "simple_stick_no_obst"
+ or self.asset_name == "sjtu_3dc"
+ or self.asset_name == "sjtu_ell"
+ or self.asset_name == "sjtu_str"
+ )
+ assert is_asset_name_valid
+ self.gnd_offset: float = cfg["env"]["groundOffset"]
+ self.disable_gnd: bool = cfg["env"]["disableGround"]
+ self.appended_wp_dist: float = cfg["env"]["appendWpDist"]
+
+ self.track_wp_data: Optional[WaypointData] = None
+ super().__init__(
+ cfg,
+ rl_device,
+ sim_device,
+ graphics_device_id,
+ headless,
+ virtual_screen_capture,
+ force_render,
+ )
+ assert self.track_wp_data is not None
+ self.waypoint_data = self.track_wp_data
+ if self.viewer and self.enable_debug_viz:
+ self.waypoint_data.visualize(self.gym, self.envs, self.viewer, 1)
+
+ def _create_envs(self):
+ # create track asset
+ track_asset: Optional[Asset] = None
+ track_wp_list: List[Waypoint] = []
+
+ if self.asset_name == "multistory":
+ track_asset, track_wp_list = create_track_multistory(
+ self.gym, self.sim, TrackMultiStoryOptions()
+ )
+ elif self.asset_name == "rmua":
+ track_asset, track_wp_list = create_track_rmua(
+ self.gym, self.sim, TrackRmuaOptions()
+ )
+ elif self.asset_name == "splits":
+ track_asset, track_wp_list = create_track_splits(
+ self.gym, self.sim, TrackSplitsOptions()
+ )
+ elif self.asset_name == "walls":
+ track_asset, track_wp_list = create_track_walls(
+ self.gym, self.sim, TrackWallsOptions()
+ )
+ elif self.asset_name == "geom_kebab":
+ track_asset, track_wp_list = create_track_geom_kebab(
+ self.gym, self.sim, TrackGeomKebabOptions(add_obstacles=True)
+ )
+ elif self.asset_name == "geom_kebab_no_obst":
+ track_asset, track_wp_list = create_track_geom_kebab(
+ self.gym, self.sim, TrackGeomKebabOptions(add_obstacles=False)
+ )
+ elif self.asset_name == "planar_circle":
+ track_asset, track_wp_list = create_track_planar_circle(
+ self.gym, self.sim, TrackPlanarCircleOptions(add_obstacles=True)
+ )
+ elif self.asset_name == "planar_circle_no_obst":
+ track_asset, track_wp_list = create_track_planar_circle(
+ self.gym, self.sim, TrackPlanarCircleOptions(add_obstacles=False)
+ )
+ elif self.asset_name == "wavy_eight":
+ track_asset, track_wp_list = create_track_wavy_eight(
+ self.gym, self.sim, TrackWavyEightOptions(add_obstacles=True)
+ )
+ elif self.asset_name == "wavy_eight_no_obst":
+ track_asset, track_wp_list = create_track_wavy_eight(
+ self.gym, self.sim, TrackWavyEightOptions(add_obstacles=False)
+ )
+ elif self.asset_name == "turns":
+ track_asset, track_wp_list = create_track_turns(
+ self.gym, self.sim, TrackTurnsOptions()
+ )
+ elif self.asset_name == "simple_stick":
+ track_asset, track_wp_list = create_track_simple_stick(
+ self.gym, self.sim, TrackSimpleStickOptions()
+ )
+ elif self.asset_name == "simple_stick":
+ track_asset, track_wp_list = create_track_simple_stick(
+ self.gym, self.sim, TrackSimpleStickOptions(add_obstacles=True)
+ )
+ elif self.asset_name == "simple_stick_no_obst":
+ track_asset, track_wp_list = create_track_simple_stick(
+ self.gym, self.sim, TrackSimpleStickOptions(add_obstacles=False)
+ )
+ elif self.asset_name == "sjtu_3dc":
+ track_asset, track_wp_list = create_track_sjtu_3dc(
+ self.gym,
+ self.sim,
+ TrackSjtu3dcOptions(
+ type_id=self.cfg["sjtu_track"]["type_id"],
+ num_obstacles=self.cfg["sjtu_track"]["num_obstacles"],
+ ),
+ )
+ elif self.asset_name == "sjtu_ell":
+ track_asset, track_wp_list = create_track_sjtu_ell(
+ self.gym,
+ self.sim,
+ TrackSjtuEllOptions(
+ type_id=self.cfg["sjtu_track"]["type_id"],
+ num_obstacles=self.cfg["sjtu_track"]["num_obstacles"],
+ ),
+ )
+ elif self.asset_name == "sjtu_str":
+ track_asset, track_wp_list = create_track_sjtu_str(
+ self.gym,
+ self.sim,
+ TrackSjtuStrOptions(
+ num_obstacles=self.cfg["sjtu_track"]["num_obstacles"]
+ ),
+ )
+
+ self.track_wp_data = WaypointData.from_waypoint_list(
+ self.num_envs, track_wp_list, True, self.appended_wp_dist
+ )
+
+ # drone asset
+ drone_asset = create_drone_quadcopter(
+ self.gym,
+ self.sim,
+ self._param_from_cfg(
+ DroneQuadcopterOptions, self.cfg["droneSim"]["drone_asset_options"]
+ ),
+ )
+
+ # ground asset
+ static_asset_opts: AssetOptions = AssetOptions()
+ static_asset_opts.fix_base_link = True
+ static_asset_opts.disable_gravity = True
+ static_asset_opts.collapse_fixed_joints = True
+ ground_asset = self.gym.create_box(self.sim, 40, 40, 0.3, static_asset_opts)
+
+ # create envs
+ tf = Transform()
+ for i in range(self.num_envs):
+ env = self.gym.create_env(
+ self.sim, Vec3(-20, -20, 0), Vec3(20, 20, 40), int(self.num_envs**0.5)
+ )
+ self.envs.append(env)
+
+ # create drone
+ drone_actor = self.gym.create_actor(env, drone_asset, tf, "drone", i, 0)
+ self.drone_actors.append(drone_actor)
+
+ # create track
+ self.gym.create_actor(env, track_asset, tf, "track", i, 1)
+
+ # create ground
+ if not self.disable_gnd:
+ tf_gnd = Transform()
+ tf_gnd.p.z = -0.15 + self.gnd_offset
+ ground_actor = self.gym.create_actor(
+ env, ground_asset, tf_gnd, "ground", i, 1
+ )
+ self.gym.set_rigid_body_color(
+ env,
+ ground_actor,
+ 0,
+ gymapi.MESH_VISUAL,
+ gymapi.Vec3(0.25, 0.25, 0.25),
+ )
+
+ if not self.disable_gnd:
+ self.num_actors_per_env = 3
+ else:
+ self.num_actors_per_env = 2
+
+ self.drone_actor_id_flat = torch.arange(
+ 0,
+ self.num_envs * self.num_actors_per_env,
+ step=self.num_actors_per_env,
+ device=self.device,
+ )
+ self.num_waypoints_to_track = self.track_wp_data.num_waypoints - 1
+ self.env_size = 40
+
+ def _randomize_racing_tracks(self):
+ pass
diff --git a/isaacgymenvs/tasks/drone_racing/tasks/dr_base.py b/isaacgymenvs/tasks/drone_racing/tasks/dr_base.py
new file mode 100644
index 000000000..abb20a5da
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/tasks/dr_base.py
@@ -0,0 +1,1082 @@
+import abc
+import os
+import sys
+from datetime import datetime
+from os.path import join
+from typing import Dict, Any, Optional, List, Tuple
+
+import numpy as np
+import torch
+from tqdm import tqdm
+
+from isaacgym import gymapi, gymtorch
+from isaacgymenvs.tasks.base.vec_task import VecTask
+from isaacgymenvs.tasks.drone_racing.drone_sim import (
+ SimpleBetaflightParams,
+ SimpleBetaflight,
+ RotorPolyLagParams,
+ RotorPolyLag,
+ PropellerPolyParams,
+ PropellerPoly,
+ BodyDragPolyParams,
+ BodyDragPoly,
+ WrenchSumParams,
+ WrenchSum,
+)
+from isaacgymenvs.tasks.drone_racing.encoders.dce import (
+ VAEImageEncoder as DCEnc,
+ VAEImageEncoderConfig as DCEncConfig,
+)
+from isaacgymenvs.tasks.drone_racing.managers import (
+ CameraManager,
+ RandCameraOptions,
+ DroneManagerParams,
+ DroneManager,
+ RandDroneOptions,
+)
+from isaacgymenvs.tasks.drone_racing.mdp import (
+ ObservationParams,
+ Observation,
+ RewardParams,
+ Reward,
+)
+from isaacgymenvs.tasks.drone_racing.waypoint import (
+ WaypointTrackerParams,
+ WaypointTracker,
+ WaypointData,
+)
+from isaacgymenvs.utils.torch_jit_utils import quat_rotate_inverse
+
+
+class DRBase(VecTask):
+ """
+ Base class for vectorized drone racing task with static number of waypoints per env,
+ and the assumption that drones are always reset to the center of the initial waypoint.
+ """
+
+ def __init__(
+ self,
+ cfg: Dict[str, Any],
+ rl_device: str,
+ sim_device: str,
+ graphics_device_id: int,
+ headless: bool,
+ virtual_screen_capture: bool,
+ force_render: bool,
+ ):
+ # configurations
+ self.cfg = cfg
+
+ self.enable_debug_viz: bool = self.cfg["env"]["enableDebugVis"]
+ self.enable_camera_sensors: bool = self.cfg["env"]["enableCameraSensors"]
+ self.enable_virtual_walls: bool = self.cfg["env"]["enableVirtualWalls"]
+ self.enable_strict_collision: bool = self.cfg["env"]["enableStrictCollision"]
+
+ self.obs_img_mode: str = self.cfg["env"]["obsImgMode"]
+ self.max_episode_length: int = self.cfg["env"]["maxEpisodeLength"]
+ self.camera_width: int = self.cfg["env"]["cameraWidth"]
+ self.camera_height: int = self.cfg["env"]["cameraHeight"]
+ self.camera_hfov: float = self.cfg["env"]["cameraHfov"]
+ self.camera_body_pos: List[float] = self.cfg["env"]["cameraBodyPos"]
+ self.camera_angle_deg: float = self.cfg["env"]["cameraAngleDeg"]
+ self.camera_depth_max: float = self.cfg["env"]["cameraDepthMax"]
+
+ self.enable_logging: bool = self.cfg["env"]["logging"]["enable"]
+ self.log_main_cam: bool = self.cfg["env"]["logging"]["logMainCam"]
+ self.log_extra_cams: bool = self.cfg["env"]["logging"]["logExtraCams"]
+ self.extra_cam_width: int = self.cfg["env"]["logging"]["extraCameraWidth"]
+ self.extra_cam_height: int = self.cfg["env"]["logging"]["extraCameraHeight"]
+ self.extra_cam_hfov: float = self.cfg["env"]["logging"]["extraCameraHfov"]
+ self.max_log_episodes: int = self.cfg["env"]["logging"]["maxNumEpisodes"]
+ self.num_steps_per_log_save: int = self.cfg["env"]["logging"]["numStepsPerSave"]
+ self.log_exp_name: str = self.cfg["env"]["logging"]["experimentName"]
+
+ self.k_vel_lateral_rew: float = self.cfg["mdp"]["extra_reward"]["k_vel_lateral"]
+ self.k_vel_backward_rew: float = self.cfg["mdp"]["extra_reward"][
+ "k_vel_backward"
+ ]
+
+ # create sim and envs
+ self.sim: Optional[gymapi.Sim] = None
+ self.num_actors_per_env: Optional[int] = None
+ self.drone_actor_id_flat: Optional[torch.Tensor] = None
+ self.envs: List[gymapi.Env] = []
+ self.drone_actors: List[int] = []
+ self.num_waypoints_to_track: Optional[int] = None
+ self.env_size: Optional[float] = None
+ self.enable_viewer_sync = True
+ self.viewer = None
+ super().__init__(
+ config=cfg,
+ rl_device=rl_device,
+ sim_device=sim_device,
+ graphics_device_id=graphics_device_id,
+ headless=headless,
+ virtual_screen_capture=virtual_screen_capture,
+ force_render=force_render,
+ )
+
+ # magical warmup for proper collision checking
+ self.gym.simulate(self.sim)
+
+ # create camera sensors on drones and create image buffers
+ self.camera_sensors: List[int] = []
+ self.depth_image_tensors: List[torch.Tensor] = []
+ self.color_image_tensors: List[torch.Tensor] = []
+ self.camera_body_tf: gymapi.Transform = gymapi.Transform()
+ self.camera_body_tf.p = gymapi.Vec3(*self.camera_body_pos)
+ self.camera_body_tf.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 1, 0), -self.camera_angle_deg * torch.pi / 180
+ )
+
+ self.extra_front_cameras: List[int] = []
+ self.extra_back_cameras: List[int] = []
+ self.extra_left_cameras: List[int] = []
+ self.extra_right_cameras: List[int] = []
+ self.extra_up_cameras: List[int] = []
+ self.extra_down_cameras: List[int] = []
+
+ self.extra_front_depth_tensors: List[torch.Tensor] = []
+ self.extra_back_depth_tensors: List[torch.Tensor] = []
+ self.extra_left_depth_tensors: List[torch.Tensor] = []
+ self.extra_right_depth_tensors: List[torch.Tensor] = []
+ self.extra_up_depth_tensors: List[torch.Tensor] = []
+ self.extra_down_depth_tensors: List[torch.Tensor] = []
+
+ if self.enable_camera_sensors:
+ # camera properties
+ cam_props = gymapi.CameraProperties()
+ cam_props.enable_tensors = True
+ cam_props.width = self.camera_width
+ cam_props.height = self.camera_height
+ cam_props.horizontal_fov = self.camera_hfov
+ cam_props.use_collision_geometry = False # True seems to be slower
+
+ # extra camera properties
+ extra_cam_props = gymapi.CameraProperties()
+ extra_cam_props.enable_tensors = True
+ extra_cam_props.width = self.extra_cam_width
+ extra_cam_props.height = self.extra_cam_height
+ extra_cam_props.horizontal_fov = self.extra_cam_hfov
+ extra_cam_props.use_collision_geometry = False
+
+ # create, attach cameras and allocate image buffers
+ for i in tqdm(range(self.num_envs)):
+ env = self.envs[i]
+ drone_actor = self.drone_actors[i]
+
+ cam = self.gym.create_camera_sensor(env, cam_props)
+ self.camera_sensors.append(cam)
+
+ self.gym.attach_camera_to_body(
+ cam, env, drone_actor, self.camera_body_tf, gymapi.FOLLOW_TRANSFORM
+ )
+
+ depth_gym_tensor = self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, cam, gymapi.IMAGE_DEPTH
+ )
+ self.depth_image_tensors.append(gymtorch.wrap_tensor(depth_gym_tensor))
+
+ color_gym_tensor = self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, cam, gymapi.IMAGE_COLOR
+ )
+ self.color_image_tensors.append(gymtorch.wrap_tensor(color_gym_tensor))
+
+ # extra cameras
+ if self.log_extra_cams:
+ disable_drone_visuals = self.cfg["droneSim"]["drone_asset_options"][
+ "disable_visuals"
+ ]
+ assert (
+ self.enable_logging
+ ), "logging extra cams enabled but logging is disabled"
+ assert (
+ disable_drone_visuals
+ ), "logging extra cams requires drone visuals disabled, otherwise extra cams are blocked"
+
+ self._init_extra_cameras(env, drone_actor, extra_cam_props)
+ else:
+ self.dummy_encoded_img = torch.zeros(self.num_envs, 64, device=self.device)
+ self.depth_image_batch = torch.zeros(
+ self.num_envs,
+ self.camera_height,
+ self.camera_width,
+ device=self.device,
+ )
+
+ assert (
+ self.log_extra_cams is False
+ ), "logging extra cams enabled but camera sensors are disabled"
+ assert (
+ self.log_main_cam is False
+ ), "logging the main cam enabled but camera sensors are disabled"
+
+ if self.obs_img_mode == "flat":
+ assert (
+ self.enable_camera_sensors
+ ), "flat images cannot be in observation as camera sensors are disabled"
+
+ # encoder
+ self.dce = None
+ if self.obs_img_mode == "dce":
+ # if no camera enabled we output the dummy DCE vector
+ assert (
+ self.camera_width == 480 and self.camera_height == 270
+ ), "DCE requires 480x270 input"
+ assert (
+ self.num_envs > 1
+ ), "DCE requires the number of envs to be greater than 1, maybe a DCE bug"
+ self.dce = DCEnc(DCEncConfig())
+ elif self.obs_img_mode != "flat" and self.obs_img_mode != "empty":
+ raise ValueError(f"expected DCE, flat, or empty, got {self.obs_img_mode}")
+
+ # contact tensor
+ self.contact_force: torch.Tensor = gymtorch.wrap_tensor(
+ self.gym.acquire_net_contact_force_tensor(self.sim)
+ )
+ self.gym.refresh_net_contact_force_tensor(self.sim)
+
+ # rigid body state buffers
+ self.actor_root_state: torch.Tensor = gymtorch.wrap_tensor(
+ self.gym.acquire_actor_root_state_tensor(self.sim)
+ )
+ self.gym.refresh_actor_root_state_tensor(self.sim)
+
+ # wrench to apply buffer
+ self.force_to_apply = torch.zeros(
+ self.num_envs * self.num_actors_per_env, 3, device=self.device
+ )
+ self.torque_to_apply = torch.zeros(
+ self.num_envs * self.num_actors_per_env, 3, device=self.device
+ )
+
+ # create drone sim modules
+ self.simple_betaflight = SimpleBetaflight(
+ self._param_from_cfg(
+ SimpleBetaflightParams, self.cfg["droneSim"]["simpleBetaflight"]
+ )
+ )
+ self.rotor_poly_lag = RotorPolyLag(
+ self._param_from_cfg(
+ RotorPolyLagParams, self.cfg["droneSim"]["rotorPolyLag"]
+ )
+ )
+ self.propeller_poly = PropellerPoly(
+ self._param_from_cfg(
+ PropellerPolyParams, self.cfg["droneSim"]["propellerPoly"]
+ )
+ )
+ self.body_drag_poly = BodyDragPoly(
+ self._param_from_cfg(
+ BodyDragPolyParams, self.cfg["droneSim"]["bodyDragPoly"]
+ )
+ )
+ self.wrench_sum = WrenchSum(
+ self._param_from_cfg(WrenchSumParams, self.cfg["droneSim"]["wrenchSum"])
+ )
+
+ # create waypoint tracker
+ self.waypoint_tracker = WaypointTracker(
+ WaypointTrackerParams(
+ num_envs=self.num_envs,
+ device=self.device,
+ num_waypoints=self.num_waypoints_to_track,
+ )
+ )
+
+ # create camera and drone manager
+ self.camera_manager = CameraManager(
+ gym=self.gym,
+ cams=self.camera_sensors,
+ envs=self.envs,
+ drones=self.drone_actors,
+ init_cam_pos=self.cfg["env"]["cameraBodyPos"],
+ init_cam_angle=self.cfg["env"]["cameraAngleDeg"],
+ )
+ self.drone_manager = DroneManager(
+ DroneManagerParams(num_envs=self.num_envs, device=self.device)
+ )
+
+ # mdp modules
+ self.mdp_observation = Observation(
+ self._param_from_cfg(ObservationParams, self.cfg["mdp"]["observation"])
+ )
+ self.mdp_reward = Reward(
+ self._param_from_cfg(RewardParams, self.cfg["mdp"]["reward"])
+ )
+
+ # randomization options
+ self.rand_camera_opts = self._param_from_cfg(
+ RandCameraOptions, self.cfg["initRandOpt"]["randCameraOptions"]
+ )
+ self.rand_drone_opts = self._param_from_cfg(
+ RandDroneOptions, self.cfg["initRandOpt"]["randDroneOptions"]
+ )
+
+ # pre-allocated static tensors
+ self.all_env_id = torch.arange(self.num_envs, device=self.device)
+ self.all_env_id_cpu = self.all_env_id.cpu()
+ self.false_1d = torch.zeros(self.num_envs, dtype=torch.bool, device=self.device)
+ self.flu_frd = torch.tensor([[1.0, -1.0, -1.0]], device=self.device)
+
+ # drone sim tensors
+ self.actions: torch.Tensor = torch.zeros(
+ self.num_envs, self.num_actions, device=self.device
+ ) # we need to init it for the first reset_idx
+ self.actions[:, 2] = -1
+ self.drone_state: Optional[torch.Tensor] = None
+ self.drone_root_q: Optional[torch.Tensor] = None
+ self.drone_lin_vel_w: Optional[torch.Tensor] = None
+ self.drone_ang_vel_w: Optional[torch.Tensor] = None
+ self.drone_lin_vel_b_frd: Optional[torch.Tensor] = None
+ self.drone_ang_vel_b_frd: Optional[torch.Tensor] = None
+ self.des_drone_ang_vel_b_frd: Optional[torch.Tensor] = None
+ self.normalized_rotor_cmd: Optional[torch.Tensor] = None
+
+ # waypoint info tensors
+ self.waypoint_data: Optional[WaypointData] = None
+ self.waypoint_passing: Optional[torch.Tensor] = None
+ self.next_waypoint_id: torch.Tensor = torch.ones(
+ self.num_envs, dtype=torch.long, device=self.device
+ ) # also need it for the first reset_idx
+
+ # common observation tensors
+ self.depth_image_batch: Optional[torch.Tensor] = None
+ self.flat_drone_state: Optional[torch.Tensor] = None
+ self.flat_cam_pose: Optional[torch.Tensor] = None
+ self.flat_waypoint_info: Optional[torch.Tensor] = None
+ self.last_action: Optional[torch.Tensor] = None
+
+ # reward
+ self.default_reward: Optional[torch.Tensor] = None
+ self.lin_vel_reward: Optional[torch.Tensor] = None
+
+ # episode termination tensors
+ self.crashed: Optional[torch.Tensor] = None
+ self.finished: Optional[torch.Tensor] = None
+
+ # flags
+ self.initial_reset = False
+
+ # logging
+ self.log_data_dict: Optional[Dict[str, Any]] = None
+ self.num_episodes: torch.Tensor = torch.zeros_like(self.reset_buf)
+ self.phy_ang_vel_des_b_frd_buf: List[torch.Tensor] = []
+ self.phy_rotor_cmd_buf: List[torch.Tensor] = []
+ self.phy_position_w_buf: List[torch.Tensor] = []
+ self.phy_quaternion_w_buf: List[torch.Tensor] = []
+ self.phy_lin_vel_w_buf: List[torch.Tensor] = []
+ self.phy_lin_vel_b_frd_buf: List[torch.Tensor] = []
+ self.phy_ang_vel_b_frd_buf: List[torch.Tensor] = []
+ self.log_dir: str = os.path.join(
+ os.path.dirname(os.path.abspath(sys.modules["__main__"].__file__)),
+ "runs",
+ "DRTask_logs",
+ self.log_exp_name,
+ "{date:%y-%m-%d-%H-%M-%S}".format(date=datetime.now()),
+ )
+ if self.enable_logging:
+ os.makedirs(self.log_dir, exist_ok=True)
+ self._init_log_data_dict()
+ self.log_batch_id: int = 0
+
+ def set_viewer(self):
+ # if running with a viewer, set up keyboard shortcuts and camera
+ if not self.headless:
+ # shortcuts
+ self.viewer = self.gym.create_viewer(self.sim, gymapi.CameraProperties())
+ self.gym.subscribe_viewer_keyboard_event(
+ self.viewer, gymapi.KEY_ESCAPE, "QUIT"
+ )
+ self.gym.subscribe_viewer_keyboard_event(
+ self.viewer, gymapi.KEY_V, "toggle_viewer_sync"
+ )
+ self.gym.subscribe_viewer_keyboard_event(
+ self.viewer, gymapi.KEY_R, "record_frames"
+ )
+
+ # read camera pose from cfg
+ cfg_cam_pos: List[float] = self.cfg["env"]["viewer"]["camPos"]
+ cfg_cam_target: List[float] = self.cfg["env"]["viewer"]["camTarget"]
+
+ sim_params = self.gym.get_sim_params(self.sim)
+ assert sim_params.up_axis == gymapi.UP_AXIS_Z
+
+ self.gym.viewer_camera_look_at(
+ self.viewer,
+ None,
+ gymapi.Vec3(*cfg_cam_pos),
+ gymapi.Vec3(*cfg_cam_target),
+ )
+
+ def create_sim(self): # noqa
+ # create sim
+ self.sim = super().create_sim(
+ self.device_id,
+ self.graphics_device_id,
+ self.physics_engine,
+ self.sim_params,
+ )
+ self._create_envs()
+
+ # check if necessary variables are set
+ assert self.num_actors_per_env is not None
+ assert self.drone_actor_id_flat is not None
+ assert len(self.envs) > 0
+ assert len(self.drone_actors) > 0
+ assert self.num_waypoints_to_track is not None
+ assert self.num_waypoints_to_track > 0
+ assert self.env_size > 0
+
+ def set_train_info(self, env_frames, *args, **kwargs):
+ """
+ Send the information in the direction of from algo to environment.
+ Most common use case: tell the environment how far along we are in the training process.
+ This is useful for implementing curriculums and things such as that.
+
+ Keyword Args:
+ rand_camera_opts: instance of ``RandCameraOptions`` for camera manager.
+ rand_drone_opts: instance of ``RandDroneOptions`` for drone manager.
+ """
+
+ rand_camera_opts = kwargs.get("rand_camera_opts", None)
+ rand_drone_opts = kwargs.get("rand_drone_opts", None)
+
+ if rand_camera_opts is not None:
+ self.rand_camera_opts = rand_camera_opts
+ if rand_drone_opts is not None:
+ self.rand_drone_opts = rand_drone_opts
+
+ def reset(self) -> Dict[str, torch.Tensor]:
+ """
+ Prepare the envs for a new rollout and return the initial observation.
+ Only after calling at least ``reset`` once can ``step`` be called.
+
+ Specifically, track randomization happens here if required.
+ Then common reset is called for all envs.
+ """
+
+ self._randomize_racing_tracks()
+ assert self.waypoint_data is not None, "unable to reset without waypoint data"
+
+ cam_tf_list = self.camera_manager.randomize_camera_tf(self.rand_camera_opts)
+
+ self.waypoint_tracker.set_waypoint_data(self.waypoint_data)
+ self.drone_manager.set_waypoint(self.waypoint_data)
+ self.mdp_observation.set_waypoint_and_cam(self.waypoint_data, cam_tf_list)
+ self.mdp_reward.set_waypoint_and_cam(self.waypoint_data, cam_tf_list)
+
+ self.reset_idx(self.all_env_id)
+ self.gym.step_graphics(self.sim)
+
+ self._update_obs_terms()
+ if self.enable_camera_sensors:
+ self.gym.render_all_camera_sensors(self.sim)
+ self.gym.start_access_image_tensors(self.sim)
+ self.depth_image_batch = (
+ -torch.stack(self.depth_image_tensors) / self.camera_depth_max
+ )
+ self.depth_image_batch.clamp_(max=1)
+ self.gym.end_access_image_tensors(self.sim)
+
+ self._update_obs_dict()
+ self._dict_tensor_to_rl_device(self.obs_dict)
+
+ self.initial_reset = True
+
+ return self.obs_dict
+
+ def reset_idx(self, env_idx: torch.Tensor):
+ # sample init state for reset envs
+ # TODO: handle possible spawn collisions
+ drone_state, action, next_wp_id = self.drone_manager.compute(
+ self.rand_drone_opts, False, env_idx
+ )
+
+ # update actor root state and submit teleportation
+ # if other actors are changed elsewhere, this line will submit those changes too
+ self.actor_root_state[self.drone_actor_id_flat[env_idx]] = drone_state[env_idx]
+ self.gym.set_actor_root_state_tensor(
+ self.sim, gymtorch.unwrap_tensor(self.actor_root_state)
+ )
+ self.gym.fetch_results(self.sim, True)
+
+ # update action and next waypoint id
+ self.actions[env_idx] = action[env_idx]
+ self.next_waypoint_id[env_idx] = next_wp_id[env_idx]
+
+ # reset modules
+ self.simple_betaflight.reset(env_idx)
+ self.rotor_poly_lag.reset(env_idx)
+ self.waypoint_tracker.set_init_drone_state_next_wp(
+ drone_state, next_wp_id, env_idx
+ )
+ self.mdp_observation.set_init_drone_state_action(drone_state, action, env_idx)
+ self.mdp_reward.set_init_drone_state_action(drone_state, action, env_idx)
+
+ # and don't forget to clear the progress counter
+ self.progress_buf[env_idx] = 0
+
+ def step(
+ self, actions: torch.Tensor
+ ) -> Tuple[Dict[str, torch.Tensor], torch.Tensor, torch.Tensor, Dict[str, Any]]:
+ # need to run reset at least once before stepping
+ assert self.initial_reset, "call env reset first"
+
+ # logging
+ if self.enable_logging:
+ should_exit = torch.all(self.num_episodes >= self.max_log_episodes)
+ should_save = should_exit or (
+ self.control_steps % self.num_steps_per_log_save == 0
+ and not self.control_steps == 0
+ )
+ if should_save:
+ torch.save(
+ self.log_data_dict,
+ os.path.join(self.log_dir, str(self.log_batch_id) + ".pt"),
+ )
+ self.log_batch_id += 1
+ self._init_log_data_dict() # clear saved data
+ if should_exit:
+ print("stopping due to maximum episodes reached in logging mode...")
+ print("SH_IO_LOG_DIR:", self.log_dir)
+ self.cfg["env"]["logging"]["numLogFiles"] = self.log_batch_id
+ # also log waypoint data, we assume in logging mode waypoint data doesn't change
+ self.cfg["waypoint_data_p"] = self.waypoint_data.position.cpu()
+ self.cfg["waypoint_data_q"] = self.waypoint_data.quaternion.cpu()
+ self.cfg["waypoint_data_w"] = self.waypoint_data.width.cpu()
+ self.cfg["waypoint_data_h"] = self.waypoint_data.height.cpu()
+ torch.save(
+ self.cfg,
+ os.path.join(self.log_dir, "cfg.pt"),
+ )
+ sys.exit()
+ self._update_log_data_pre_physics()
+ self._clear_log_phy_buffers() # for logging physics data
+
+ # closed-loop control and physics
+ self.actions = actions.clamp(-self.clip_actions, self.clip_actions)
+ self.simple_betaflight.set_command(self.actions)
+ self.crashed = self.false_1d
+ for i in range(self.control_freq_inv):
+ # update drone states
+ self.drone_state = self.actor_root_state[self.drone_actor_id_flat]
+ self.drone_root_q = self.drone_state[:, 3:7] # x, y, z, w
+ self.drone_lin_vel_w = self.drone_state[:, 7:10]
+ self.drone_ang_vel_w = self.drone_state[:, 10:]
+ self.drone_lin_vel_b_frd = self.flu_frd * quat_rotate_inverse(
+ self.drone_root_q, self.drone_lin_vel_w
+ )
+ self.drone_ang_vel_b_frd = self.flu_frd * quat_rotate_inverse(
+ self.drone_root_q, self.drone_ang_vel_w
+ )
+
+ # run drone sim modules
+ self.des_drone_ang_vel_b_frd, self.normalized_rotor_cmd = (
+ self.simple_betaflight.compute(self.drone_ang_vel_b_frd)
+ )
+ rpm, rotor_force, rotor_torque = self.rotor_poly_lag.compute(
+ self.normalized_rotor_cmd
+ )
+ prop_force, prop_torque = self.propeller_poly.compute(rpm)
+ ctrl_force, ctrl_torque = self.wrench_sum.compute(
+ rotor_force + prop_force, rotor_torque + prop_torque
+ )
+ drag_force, drag_torque = self.body_drag_poly.compute(
+ self.drone_lin_vel_b_frd, self.drone_ang_vel_b_frd
+ )
+
+ # apply force and torque
+ self.force_to_apply[self.drone_actor_id_flat] = self.flu_frd * (
+ ctrl_force + drag_force
+ )
+ self.torque_to_apply[self.drone_actor_id_flat] = self.flu_frd * (
+ ctrl_torque + drag_torque
+ )
+ self.gym.apply_rigid_body_force_tensors(
+ self.sim,
+ gymtorch.unwrap_tensor(self.force_to_apply),
+ gymtorch.unwrap_tensor(self.torque_to_apply),
+ gymapi.LOCAL_SPACE,
+ )
+
+ # log physics data
+ if self.enable_logging:
+ self._update_log_phy_buffers()
+
+ # step physics
+ self.gym.simulate(self.sim)
+ self.gym.fetch_results(self.sim, True)
+ self.gym.refresh_actor_root_state_tensor(self.sim)
+ self.gym.refresh_net_contact_force_tensor(self.sim)
+ self.crashed = self.crashed | torch.greater(
+ torch.linalg.norm(self.contact_force[self.drone_actor_id_flat], dim=1),
+ 0.01, # TODO: make it configurable, Aerial Gym uses 0.05
+ )
+
+ # update if drone has crashed using virtual walls
+ if self.enable_virtual_walls:
+ oob = (
+ (self.drone_state[:, 0].abs() > self.env_size / 2)
+ | (self.drone_state[:, 1].abs() > self.env_size / 2)
+ | (self.drone_state[:, 2].abs() > self.env_size)
+ )
+ self.crashed = self.crashed | oob
+
+ # track waypoint
+ self.drone_state = self.actor_root_state[self.drone_actor_id_flat]
+ self.waypoint_passing, self.next_waypoint_id = self.waypoint_tracker.compute(
+ self.drone_state
+ )
+
+ # check dones
+ self.finished = torch.eq(self.next_waypoint_id, 0)
+ self.timeout_buf[:] = self.progress_buf >= self.max_episode_length - 1
+ if self.enable_strict_collision:
+ # be careful that crashes are detected between environment steps
+ # if crashed, finished and timeout should not be true
+ # but if on, this will make training worse
+ # TODO: self.waypoint_passing = self.waypoint_passing & ~self.crashed results in much worse training
+ # TODO: what about timeout?
+ self.finished = self.finished & ~self.crashed
+ self.timeout_buf[:] = self.timeout_buf & ~self.crashed
+ self.reset_buf[:] = self.crashed | self.finished | self.timeout_buf
+ self.progress_buf += 1
+ self.num_episodes += self.reset_buf
+
+ # compute reward
+ self.default_reward = self.mdp_reward.compute(
+ drone_state=self.drone_state,
+ action=self.actions,
+ drone_collision=self.crashed,
+ timeout=self.timeout_buf,
+ wp_passing=self.waypoint_passing,
+ next_wp_id=self.next_waypoint_id,
+ )
+ self._update_rew_buf()
+ self._update_extra_rew_terms()
+
+ # log data after physics
+ if self.enable_logging:
+ self._update_log_data_post_physics()
+
+ # reset envs
+ done_env_ids = self.reset_buf.nonzero().flatten()
+ if len(done_env_ids) > 0:
+ self.reset_idx(done_env_ids)
+
+ # step rendering
+ self.gym.step_graphics(self.sim)
+ if self.enable_camera_sensors:
+ self.gym.render_all_camera_sensors(self.sim)
+ if self.force_render:
+ self.render()
+
+ # calculate useful tensors for observation
+ self._update_obs_terms()
+ if self.enable_camera_sensors:
+ self.gym.start_access_image_tensors(self.sim)
+ self.depth_image_batch = (
+ -torch.stack(self.depth_image_tensors) / self.camera_depth_max
+ )
+ self.depth_image_batch.clamp_(max=1)
+ self.gym.end_access_image_tensors(self.sim)
+ self._update_obs_dict()
+ self._update_extras()
+ self.control_steps += 1
+
+ self._dict_tensor_to_rl_device(self.obs_dict)
+ self._dict_tensor_to_rl_device(self.extras)
+ return (
+ self.obs_dict,
+ self.rew_buf.to(device=self.rl_device),
+ self.reset_buf.to(device=self.rl_device),
+ self.extras,
+ )
+
+ def render(self, mode="rgb_array"):
+ """
+ Overrides the base render function because we have camera running,
+ so ``step_graphics`` need to happen regardless of ``enable_viewer_sync``.
+ """
+
+ if self.viewer:
+ # check for window closed
+ if self.gym.query_viewer_has_closed(self.viewer):
+ print("stopping...")
+ sys.exit()
+
+ # check for keyboard events
+ for evt in self.gym.query_viewer_action_events(self.viewer):
+ if evt.action == "QUIT" and evt.value > 0:
+ sys.exit()
+ elif evt.action == "toggle_viewer_sync" and evt.value > 0:
+ self.enable_viewer_sync = not self.enable_viewer_sync
+ elif evt.action == "record_frames" and evt.value > 0:
+ self.record_frames = not self.record_frames
+
+ # step graphics
+ if self.enable_viewer_sync:
+ self.gym.draw_viewer(self.viewer, self.sim, True)
+ else:
+ self.gym.poll_viewer_events(self.viewer)
+
+ if self.record_frames:
+ if not os.path.isdir(self.record_frames_dir):
+ os.makedirs(self.record_frames_dir, exist_ok=True)
+
+ self.gym.write_viewer_image_to_file(
+ self.viewer,
+ join(self.record_frames_dir, f"frame_{self.control_steps}.png"),
+ )
+
+ if self.virtual_display and mode == "rgb_array":
+ img = self.virtual_display.grab()
+ return np.array(img)
+
+ def reset_done(self):
+ raise NotImplementedError
+
+ def pre_physics_step(self, actions: torch.Tensor):
+ raise NotImplementedError
+
+ def post_physics_step(self):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def _create_envs(self):
+ """
+ Create envs and fill in the following variables.
+
+ - ``self.num_actors_per_env``
+ - ``self.drone_actor_id_flat``
+ - ``self.envs``
+ - ``self.drone_actors``
+ - ``self.num_waypoints_to_track``
+ - ``self.env_size``
+ """
+
+ pass
+
+ @abc.abstractmethod
+ def _randomize_racing_tracks(self):
+ """
+ Randomize racing tracks (waypoints, obstacles...) if necessary.
+ Responsible for making sure that ``self.waypoint_data`` is not ``None``.
+ """
+
+ pass
+
+ @abc.abstractmethod
+ def _update_rew_buf(self):
+ """
+ Update ``self.rew_buf``.
+ """
+
+ pass
+
+ @abc.abstractmethod
+ def _update_extra_rew_terms(self):
+ """
+ Update ``self.extras`` with reward terms.
+ """
+
+ pass
+
+ @abc.abstractmethod
+ def _update_obs_dict(self):
+ """
+ Update ``self.obs_dict``.
+ """
+
+ pass
+
+ @abc.abstractmethod
+ def _update_extras(self):
+ """
+ Update ``self.extras``.
+ """
+
+ pass
+
+ def _init_extra_cameras(self, env, drone_actor, extra_cam_props):
+ extra_front_cam = self.gym.create_camera_sensor(env, extra_cam_props)
+ extra_back_cam = self.gym.create_camera_sensor(env, extra_cam_props)
+ extra_left_cam = self.gym.create_camera_sensor(env, extra_cam_props)
+ extra_right_cam = self.gym.create_camera_sensor(env, extra_cam_props)
+ extra_up_cam = self.gym.create_camera_sensor(env, extra_cam_props)
+ extra_down_cam = self.gym.create_camera_sensor(env, extra_cam_props)
+
+ self.extra_front_cameras.append(extra_front_cam)
+ self.extra_back_cameras.append(extra_back_cam)
+ self.extra_left_cameras.append(extra_left_cam)
+ self.extra_right_cameras.append(extra_right_cam)
+ self.extra_up_cameras.append(extra_up_cam)
+ self.extra_down_cameras.append(extra_down_cam)
+
+ extra_front_cam_body_tf: gymapi.Transform = gymapi.Transform()
+ extra_back_cam_body_tf: gymapi.Transform = gymapi.Transform()
+ extra_left_cam_body_tf: gymapi.Transform = gymapi.Transform()
+ extra_right_cam_body_tf: gymapi.Transform = gymapi.Transform()
+ extra_up_cam_body_tf: gymapi.Transform = gymapi.Transform()
+ extra_down_cam_body_tf: gymapi.Transform = gymapi.Transform()
+
+ extra_back_cam_body_tf.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 0, 1), torch.pi
+ )
+ extra_left_cam_body_tf.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 0, 1), torch.pi / 2
+ )
+ extra_right_cam_body_tf.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 0, 1), -torch.pi / 2
+ )
+ extra_up_cam_body_tf.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 1, 0), -torch.pi / 2
+ )
+ extra_down_cam_body_tf.r = gymapi.Quat.from_axis_angle(
+ gymapi.Vec3(0, 1, 0), torch.pi / 2
+ )
+
+ self.gym.attach_camera_to_body(
+ extra_front_cam,
+ env,
+ drone_actor,
+ extra_front_cam_body_tf,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+ self.gym.attach_camera_to_body(
+ extra_back_cam,
+ env,
+ drone_actor,
+ extra_back_cam_body_tf,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+ self.gym.attach_camera_to_body(
+ extra_left_cam,
+ env,
+ drone_actor,
+ extra_left_cam_body_tf,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+ self.gym.attach_camera_to_body(
+ extra_right_cam,
+ env,
+ drone_actor,
+ extra_right_cam_body_tf,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+ self.gym.attach_camera_to_body(
+ extra_up_cam,
+ env,
+ drone_actor,
+ extra_up_cam_body_tf,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+ self.gym.attach_camera_to_body(
+ extra_down_cam,
+ env,
+ drone_actor,
+ extra_down_cam_body_tf,
+ gymapi.FOLLOW_TRANSFORM,
+ )
+
+ self.extra_front_depth_tensors.append(
+ gymtorch.wrap_tensor(
+ self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, extra_front_cam, gymapi.IMAGE_DEPTH
+ )
+ )
+ )
+ self.extra_back_depth_tensors.append(
+ gymtorch.wrap_tensor(
+ self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, extra_back_cam, gymapi.IMAGE_DEPTH
+ )
+ )
+ )
+ self.extra_left_depth_tensors.append(
+ gymtorch.wrap_tensor(
+ self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, extra_left_cam, gymapi.IMAGE_DEPTH
+ )
+ )
+ )
+ self.extra_right_depth_tensors.append(
+ gymtorch.wrap_tensor(
+ self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, extra_right_cam, gymapi.IMAGE_DEPTH
+ )
+ )
+ )
+ self.extra_up_depth_tensors.append(
+ gymtorch.wrap_tensor(
+ self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, extra_up_cam, gymapi.IMAGE_DEPTH
+ )
+ )
+ )
+ self.extra_down_depth_tensors.append(
+ gymtorch.wrap_tensor(
+ self.gym.get_camera_image_gpu_tensor(
+ self.sim, env, extra_down_cam, gymapi.IMAGE_DEPTH
+ )
+ )
+ )
+
+ def _init_log_data_dict(self):
+ data_keys = [
+ # pre physics
+ "env_step",
+ "episode_id",
+ "episode_progress",
+ "main_depth",
+ "main_color",
+ "extra_depth",
+ "min_dist_to_obstacle",
+ "main_cam_pose",
+ "action",
+ "next_waypoint_p",
+ # inner physics loop data, stacked after physics
+ "ang_vel_des_b_frd",
+ "rotor_cmd",
+ "position_w",
+ "quaternion_w",
+ "lin_vel_w",
+ "lin_vel_b_frd",
+ "ang_vel_b_frd",
+ # reset mode after physics
+ "is_finished",
+ "is_crashed",
+ "is_timeout",
+ ]
+ self.log_data_dict = {
+ **{key: [] for key in data_keys},
+ }
+
+ def _update_log_data_pre_physics(self):
+ self.log_data_dict["env_step"].append(self.control_steps)
+ self.log_data_dict["episode_id"].append(self.num_episodes.clone().cpu())
+ self.log_data_dict["episode_progress"].append(self.progress_buf.clone().cpu())
+ # TODO: self.gym.start_access_image_tensors? it looks fine without it here... Why?
+ if self.log_main_cam:
+ main_depth = (
+ (-torch.stack(self.depth_image_tensors)) / self.camera_depth_max
+ ).nan_to_num_(posinf=0.0)
+ main_depth[main_depth > 1.0] = 0.0
+ self.log_data_dict["main_depth"].append(main_depth.cpu())
+ self.log_data_dict["main_color"].append(
+ torch.stack(self.color_image_tensors).cpu()
+ )
+ if self.log_extra_cams:
+ extra_front_depth = -torch.stack(self.extra_front_depth_tensors)
+ extra_back_depth = -torch.stack(self.extra_back_depth_tensors)
+ extra_left_depth = -torch.stack(self.extra_left_depth_tensors)
+ extra_right_depth = -torch.stack(self.extra_right_depth_tensors)
+ extra_up_depth = -torch.stack(self.extra_up_depth_tensors)
+ extra_down_depth = -torch.stack(self.extra_down_depth_tensors)
+ extra_depth = torch.stack(
+ [
+ extra_front_depth,
+ extra_back_depth,
+ extra_left_depth,
+ extra_right_depth,
+ extra_up_depth,
+ extra_down_depth,
+ ],
+ 1,
+ )
+ min_d_to_obst = torch.min(extra_depth.view(self.num_envs, -1), 1).values
+ self.log_data_dict["extra_depth"].append(
+ extra_depth.nan_to_num_(posinf=0.0).cpu()
+ )
+ self.log_data_dict["min_dist_to_obstacle"].append(min_d_to_obst.cpu())
+ # TODO: self.gym.end_access_image_tensors?
+ self.log_data_dict["main_cam_pose"].append(self.flat_cam_pose.clone().cpu())
+ self.log_data_dict["action"].append(self.actions.clone().cpu())
+ self.log_data_dict["next_waypoint_p"].append(
+ self.waypoint_data.position[
+ self.all_env_id_cpu, self.next_waypoint_id.cpu()
+ ]
+ )
+
+ def _update_log_data_post_physics(self):
+ self.log_data_dict["ang_vel_des_b_frd"].append(
+ torch.stack(self.phy_ang_vel_des_b_frd_buf).cpu()
+ )
+ self.log_data_dict["rotor_cmd"].append(
+ torch.stack(self.phy_rotor_cmd_buf).cpu()
+ )
+ self.log_data_dict["position_w"].append(
+ torch.stack(self.phy_position_w_buf).cpu()
+ )
+ self.log_data_dict["quaternion_w"].append(
+ torch.stack(self.phy_quaternion_w_buf).cpu()
+ )
+ self.log_data_dict["lin_vel_w"].append(
+ torch.stack(self.phy_lin_vel_w_buf).cpu()
+ )
+ self.log_data_dict["lin_vel_b_frd"].append(
+ torch.stack(self.phy_lin_vel_b_frd_buf).cpu()
+ )
+ self.log_data_dict["ang_vel_b_frd"].append(
+ torch.stack(self.phy_ang_vel_b_frd_buf).cpu()
+ )
+
+ is_crashed = self.crashed.clone().cpu()
+ is_timeout = self.timeout_buf.cpu() & ~is_crashed
+ is_finished = self.finished.cpu() & ~is_crashed & ~is_timeout
+ self.log_data_dict["is_finished"].append(is_finished)
+ self.log_data_dict["is_crashed"].append(is_crashed)
+ self.log_data_dict["is_timeout"].append(is_timeout)
+ if (is_finished.int() + is_crashed.int() + is_timeout.int() > 1).any():
+ print(is_crashed.int())
+ print(is_timeout.int())
+ print(is_finished.int())
+ raise ValueError("termination mode is ambiguous")
+
+ def _clear_log_phy_buffers(self):
+ self.phy_ang_vel_des_b_frd_buf.clear()
+ self.phy_rotor_cmd_buf.clear()
+ self.phy_position_w_buf.clear()
+ self.phy_quaternion_w_buf.clear()
+ self.phy_lin_vel_w_buf.clear()
+ self.phy_lin_vel_b_frd_buf.clear()
+ self.phy_ang_vel_b_frd_buf.clear()
+
+ def _update_log_phy_buffers(self):
+ self.phy_ang_vel_des_b_frd_buf.append(
+ self.des_drone_ang_vel_b_frd.clone().cpu()
+ )
+ self.phy_rotor_cmd_buf.append(self.normalized_rotor_cmd.clone())
+ self.phy_position_w_buf.append(self.drone_state[:, :3].clone())
+ self.phy_quaternion_w_buf.append(self.drone_root_q.clone())
+ self.phy_lin_vel_w_buf.append(self.drone_lin_vel_w.clone())
+ self.phy_lin_vel_b_frd_buf.append(self.drone_lin_vel_b_frd.clone())
+ self.phy_ang_vel_b_frd_buf.append(self.drone_ang_vel_b_frd.clone())
+
+ def _param_from_cfg(self, param_class, cfg_dict: dict):
+ p = param_class()
+ for key in cfg_dict.keys():
+ assert hasattr(p, key), f"{p}, {key}"
+ setattr(p, key, cfg_dict[key])
+ if hasattr(p, "device"):
+ p.device = self.device
+ if hasattr(p, "num_envs"):
+ p.num_envs = self.num_envs
+ return p
+
+ def _update_obs_terms(self):
+ (
+ self.flat_drone_state,
+ self.flat_cam_pose,
+ self.flat_waypoint_info,
+ self.last_action,
+ ) = self.mdp_observation.compute(
+ drone_state=self.actor_root_state[self.drone_actor_id_flat],
+ next_wp_id=self.next_waypoint_id,
+ action=self.actions,
+ )
+
+ def _dict_tensor_to_rl_device(self, dict_tensor: Dict[str, torch.Tensor]):
+ for key in dict_tensor:
+ dict_tensor[key] = dict_tensor[key].to(device=self.rl_device)
diff --git a/isaacgymenvs/tasks/drone_racing/tasks/dr_default_out.py b/isaacgymenvs/tasks/drone_racing/tasks/dr_default_out.py
new file mode 100644
index 000000000..21b7b8e50
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/tasks/dr_default_out.py
@@ -0,0 +1,81 @@
+import abc
+
+import torch
+
+from .dr_base import DRBase
+
+
+class DRDefaultOut(DRBase):
+
+ @abc.abstractmethod
+ def _create_envs(self):
+ pass
+
+ @abc.abstractmethod
+ def _randomize_racing_tracks(self):
+ pass
+
+ def _update_rew_buf(self):
+ self.lin_vel_reward = (
+ self.k_vel_lateral_rew * self.drone_lin_vel_b_frd[:, 1] ** 2
+ + self.k_vel_backward_rew * self.drone_lin_vel_b_frd[:, 0].clamp(max=0) ** 2
+ )
+ self.rew_buf[:] = self.default_reward + self.lin_vel_reward
+
+ def _update_extra_rew_terms(self):
+ self.extras["reward_progress"] = self.mdp_reward.reward_progress
+ self.extras["reward_perception"] = self.mdp_reward.reward_perception
+ self.extras["reward_cmd"] = self.mdp_reward.reward_cmd
+ self.extras["reward_collision"] = self.mdp_reward.reward_collision
+ self.extras["reward_guidance"] = self.mdp_reward.reward_guidance
+ self.extras["reward_waypoint"] = self.mdp_reward.reward_waypoint
+ self.extras["reward_timeout"] = self.mdp_reward.reward_timeout
+ self.extras["reward_lin_vel"] = self.lin_vel_reward
+
+ def _update_obs_dict(self):
+ if self.obs_img_mode == "empty":
+ self.obs_dict["obs"] = torch.cat(
+ (
+ self.flat_drone_state,
+ self.flat_waypoint_info,
+ self.last_action,
+ ),
+ 1,
+ )
+ elif self.obs_img_mode == "flat":
+ self.obs_dict["obs"] = torch.cat(
+ (
+ self.depth_image_batch.flatten(1),
+ self.flat_drone_state,
+ self.flat_waypoint_info,
+ self.last_action,
+ ),
+ 1,
+ )
+ elif self.obs_img_mode == "dce":
+ if self.enable_camera_sensors:
+ self.obs_dict["obs"] = torch.cat(
+ (
+ self.dce.encode(self.depth_image_batch),
+ self.flat_drone_state,
+ self.flat_waypoint_info,
+ self.last_action,
+ ),
+ 1,
+ )
+ else:
+ self.obs_dict["obs"] = torch.cat(
+ (
+ self.dummy_encoded_img,
+ self.flat_drone_state,
+ self.flat_waypoint_info,
+ self.last_action,
+ ),
+ 1,
+ )
+
+ def _update_extras(self):
+ self.extras["crashed"] = self.crashed
+ self.extras["finished"] = self.finished
+ self.extras["time_outs"] = self.timeout_buf
+ self.extras["progress"] = self.progress_buf
diff --git a/isaacgymenvs/tasks/drone_racing/tasks/dr_random.py b/isaacgymenvs/tasks/drone_racing/tasks/dr_random.py
new file mode 100644
index 000000000..d17d62ffd
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/tasks/dr_random.py
@@ -0,0 +1,122 @@
+from typing import Dict, Any, Optional
+
+from isaacgymenvs.tasks.drone_racing.env import (
+ EnvCreatorParams,
+ EnvCreator,
+)
+from isaacgymenvs.tasks.drone_racing.managers import (
+ ObstacleManager,
+ RandObstacleOptions,
+)
+from isaacgymenvs.tasks.drone_racing.waypoint import (
+ WaypointGeneratorParams,
+ WaypointGenerator,
+ RandWaypointOptions,
+)
+from .dr_default_out import DRDefaultOut
+
+
+class DRRandom(DRDefaultOut):
+ def __init__(
+ self,
+ cfg: Dict[str, Any],
+ rl_device: str,
+ sim_device: str,
+ graphics_device_id: int,
+ headless: bool,
+ virtual_screen_capture: bool,
+ force_render: bool,
+ ):
+ self.env_creator: Optional[EnvCreator] = None
+ super().__init__(
+ cfg,
+ rl_device,
+ sim_device,
+ graphics_device_id,
+ headless,
+ virtual_screen_capture,
+ force_render,
+ )
+
+ # extra modules to generate random multiple tracks with or without obstacles
+ self.waypoint_generator = WaypointGenerator(
+ self._param_from_cfg(WaypointGeneratorParams, self.cfg["waypointGenerator"])
+ )
+ self.obstacle_manager = ObstacleManager(self.env_creator)
+ self.disable_obstacle_man = self.cfg["disableObstacleManager"]
+
+ # extra random generator options
+ self.rand_waypoint_opts = self._param_from_cfg(
+ RandWaypointOptions, self.cfg["initRandOpt"]["randWaypointOptions"]
+ )
+ self.rand_obstacle_opts = self._param_from_cfg(
+ RandObstacleOptions, self.cfg["initRandOpt"]["randObstacleOptions"]
+ )
+
+ def set_train_info(self, env_frames, *args, **kwargs):
+ rand_waypoint_opts = kwargs.get("rand_waypoint_opts", None)
+ rand_obstacle_opts = kwargs.get("rand_obstacle_opts", None)
+ rand_drone_opts = kwargs.get("rand_drone_opts", None)
+ rand_camera_opts = kwargs.get("rand_camera_opts", None)
+
+ if rand_waypoint_opts is not None:
+ self.rand_waypoint_opts = rand_waypoint_opts
+ if rand_obstacle_opts is not None:
+ self.rand_obstacle_opts = rand_obstacle_opts
+ if rand_drone_opts is not None:
+ self.rand_drone_opts = rand_drone_opts
+ if rand_camera_opts is not None:
+ self.rand_camera_opts = rand_camera_opts
+
+ def _create_envs(self):
+ # create envs
+ self.env_creator = EnvCreator(
+ self.gym, self.sim, self._get_env_creator_params()
+ )
+ self.env_creator.create([0.0, 0.0, self.env_creator.params.env_size / 2])
+
+ # assign required variables
+ self.num_actors_per_env = self.env_creator.num_actors_per_env
+ self.drone_actor_id_flat = self.env_creator.drone_actor_id.flatten().to(
+ device=self.device
+ )
+ self.envs = self.env_creator.envs
+ self.drone_actors = self.env_creator.quad_actors
+ self.num_waypoints_to_track = self.cfg["waypointGenerator"]["num_waypoints"] - 1
+ self.env_size = self.env_creator.params.env_size
+
+ def _randomize_racing_tracks(self):
+ # generate random waypoints for multiple tracks
+ self.waypoint_data = self.waypoint_generator.compute(self.rand_waypoint_opts)
+ if self.viewer and self.enable_debug_viz:
+ self.gym.clear_lines(self.viewer)
+ self.waypoint_data.visualize(self.gym, self.envs, self.viewer, 1)
+
+ # place random obstacles around the waypoints if enabled
+ # sometimes we do not want to compute gate and obstacles at all
+ # e.g. for large amount of envs, state-only drone racing
+ if not self.disable_obstacle_man:
+ obs_actor_pose, obs_actor_id = self.obstacle_manager.compute(
+ waypoint_data=self.waypoint_data, rand_obs_opts=self.rand_obstacle_opts
+ )
+ self.actor_root_state[obs_actor_id, :7] = obs_actor_pose[obs_actor_id].to(
+ self.device
+ )
+
+ def _get_env_creator_params(self) -> EnvCreatorParams:
+ p = EnvCreatorParams()
+ for opt in self.cfg["envCreator"].keys():
+ if opt == "drone_asset_options":
+ for drone_asset_opt in self.cfg["envCreator"][opt].keys():
+ assert hasattr(p.drone_asset_options, drone_asset_opt)
+ setattr(
+ p.drone_asset_options,
+ drone_asset_opt,
+ self.cfg["envCreator"][opt][drone_asset_opt],
+ )
+ else:
+ assert hasattr(p, opt), opt
+ setattr(p, opt, self.cfg["envCreator"][opt])
+ p.num_envs = self.num_envs
+ p.device = self.device
+ return p
diff --git a/isaacgymenvs/tasks/drone_racing/waypoint/__init__.py b/isaacgymenvs/tasks/drone_racing/waypoint/__init__.py
new file mode 100644
index 000000000..b7a876731
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/waypoint/__init__.py
@@ -0,0 +1,12 @@
+"""
+Package for general drone racing environments.
+"""
+
+from .waypoint import Waypoint
+from .waypoint_data import WaypointData
+from .waypoint_generator import (
+ WaypointGeneratorParams,
+ WaypointGenerator,
+ RandWaypointOptions,
+)
+from .waypoint_tracker import WaypointTrackerParams, WaypointTracker
diff --git a/isaacgymenvs/tasks/drone_racing/waypoint/waypoint.py b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint.py
new file mode 100644
index 000000000..49148bc64
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint.py
@@ -0,0 +1,35 @@
+import math
+from typing import List
+
+
+class Waypoint:
+
+ def __init__(
+ self,
+ index: int,
+ xyz: List[float],
+ rpy: List[float],
+ length_y: float,
+ length_z: float,
+ gate: bool,
+ ):
+ self.index = index
+ self.xyz = xyz
+ self.rpy = rpy
+ self.length_y = length_y
+ self.length_z = length_z
+ self.gate = gate
+
+ def rpy_rad(self) -> List[float]:
+ return [
+ math.radians(self.rpy[0]),
+ math.radians(self.rpy[1]),
+ math.radians(self.rpy[2]),
+ ]
+
+ def compact_data(self) -> List[float]:
+ gate = -1.0
+ if self.gate:
+ gate = 1.0
+ data = self.xyz + self.rpy_rad() + [self.length_y, self.length_z, gate]
+ return data
diff --git a/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_data.py b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_data.py
new file mode 100644
index 000000000..b236107e1
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_data.py
@@ -0,0 +1,249 @@
+from typing import List
+
+import torch
+
+from isaacgym import gymutil
+from isaacgym.gymapi import Gym, Vec3, Env, Viewer, Transform, Quat
+from isaacgymenvs.utils.torch_jit_utils import (
+ quat_from_euler_xyz,
+ quat_rotate_inverse,
+ quaternion_to_matrix,
+)
+from .waypoint import Waypoint
+
+
+class WaypointData:
+
+ def __init__(
+ self,
+ position: torch.Tensor,
+ quaternion: torch.Tensor,
+ width: torch.Tensor,
+ height: torch.Tensor,
+ gate_flag: torch.Tensor,
+ gate_x_len_choice: torch.Tensor,
+ gate_weight_choice: torch.Tensor,
+ psi: torch.Tensor,
+ theta: torch.Tensor,
+ gamma: torch.Tensor,
+ r: torch.Tensor,
+ ):
+ """
+ Waypoint data and relative pose for multiple waypoints in parallel environments.
+
+ Args:
+ position: waypoint center position in world frame in (num_envs, num_waypoints, 3).
+ quaternion: waypoint attitude in quaternion in (num_envs, num_waypoints, 4).
+ width: region width (dim in waypoint body frame y) in (num_envs, num_waypoints).
+ height: region height (dim in waypoint body frame z) in (num_envs, num_waypoints).
+ gate_flag: {0.0, 1.0} indicating presence of a gate for waypoints in (num_envs, num_waypoints).
+ gate_x_len_choice: {0.0, 1.0, ...} choice id of gate dim in waypoint body frame x
+ in (num_envs, num_waypoints)
+ gate_weight_choice: {0.0, 1.0, ...} choice id of gate weight (outer and inner dim diff of a hollow cube)
+ in (num_envs, num_waypoints)
+ psi: vector from this to next waypoint, this waypoint xy-plane in (num_envs, num_waypoints - 1)
+ theta: angle between: vector from this to next waypoint, this waypoint x-axis
+ in (num_envs, num_waypoints - 1)
+ gamma: angle between: vector from this to next waypoint, next waypoint x-axis
+ in (num_envs, num_waypoints - 1)
+ r: distance between this and next waypoint in (num_envs, num_waypoints - 1)
+ """
+
+ self.position = position
+ """(num_envs, num_waypoints, 3)"""
+
+ self.quaternion = quaternion
+ """(num_envs, num_waypoints, 4)"""
+
+ self.width = width
+ """(num_envs, num_waypoints)"""
+
+ self.height = height
+ """(num_envs, num_waypoints)"""
+
+ self.gate_flag = gate_flag
+ """(num_envs, num_waypoints)"""
+
+ self.gate_x_len_choice = gate_x_len_choice
+ """(num_envs, num_waypoints)"""
+
+ self.gate_weight_choice = gate_weight_choice
+ """(num_envs, num_waypoints)"""
+
+ self.psi = psi
+ """(num_envs, num_waypoints - 1)"""
+
+ self.theta = theta
+ """(num_envs, num_waypoints - 1)"""
+
+ self.gamma = gamma
+ """(num_envs, num_waypoints - 1)"""
+
+ self.r = r
+ """(num_envs, num_waypoints - 1)"""
+
+ @classmethod
+ def from_waypoint_list(
+ cls,
+ num_envs: int,
+ waypoint_list: List[Waypoint],
+ append_dummy: bool = False,
+ append_dist: float = 10.0,
+ ):
+ waypoint_list = waypoint_list.copy()
+ if append_dummy:
+ last_wp = waypoint_list[-1]
+ last_wp_compact = last_wp.compact_data()
+ pos = torch.tensor(last_wp_compact[:3])
+ roll = torch.tensor(last_wp_compact[3])
+ pitch = torch.tensor(last_wp_compact[4])
+ yaw = torch.tensor(last_wp_compact[5])
+ q = quat_from_euler_xyz(roll, pitch, yaw)
+ mat = quaternion_to_matrix(q.roll(1))
+ mat_x = mat[:, 0]
+ new_pos = pos + mat_x * append_dist
+
+ waypoint_list.append(
+ Waypoint(
+ index=last_wp.index + 1,
+ xyz=new_pos.tolist(),
+ rpy=last_wp.rpy,
+ length_y=last_wp.length_y,
+ length_z=last_wp.length_z,
+ gate=False,
+ )
+ )
+ num_waypoints = len(waypoint_list)
+
+ position = torch.zeros(num_envs, num_waypoints, 3)
+ quaternion = torch.zeros(num_envs, num_waypoints, 4)
+ width = torch.zeros(num_envs, num_waypoints)
+ height = torch.zeros(num_envs, num_waypoints)
+ gate_flag = torch.zeros(num_envs, num_waypoints, dtype=torch.int)
+ gate_x_len_choice = torch.zeros(num_envs, num_waypoints, dtype=torch.int)
+ gate_weight_choice = torch.zeros(num_envs, num_waypoints, dtype=torch.int)
+ psi = torch.zeros(num_envs, num_waypoints - 1)
+ theta = torch.zeros(num_envs, num_waypoints - 1)
+ gamma = torch.zeros(num_envs, num_waypoints - 1)
+ r = torch.zeros(num_envs, num_waypoints - 1)
+
+ for i in range(num_waypoints):
+ # [x, y, z, r, p, y, w, h, gate flag]
+ # [0, 1, 2, 3, 4, 5, 6, 7, 8]
+ data_src = waypoint_list[i].compact_data()
+ position[:, i] = torch.tensor(data_src[:3])
+ roll = torch.tensor([data_src[3]])
+ pitch = torch.tensor([data_src[4]])
+ yaw = torch.tensor([data_src[5]])
+ quaternion[:, i] = quat_from_euler_xyz(roll, pitch, yaw)
+ width[:, i] = data_src[6]
+ height[:, i] = data_src[7]
+ gate_flag[:, i] = int(data_src[8])
+
+ # get psi, theta, gamma, and r
+ if i > 0:
+ # r
+ start_pos = torch.tensor(waypoint_list[i - 1].xyz)
+ end_pos = torch.tensor(waypoint_list[i].xyz)
+ vec_r = end_pos - start_pos
+ dist_r = torch.linalg.norm(vec_r)
+ r[:, i - 1] = dist_r
+
+ # psi, theta
+ # dist_r == 0: psi = theta = 0
+ if dist_r > 0:
+ start_q = quaternion[0, i - 1]
+ vec_r_b = quat_rotate_inverse(
+ start_q.unsqueeze(0), vec_r.unsqueeze(0)
+ ).squeeze()
+ if vec_r_b[0] == 0 and vec_r_b[1] == 0:
+ psi[:, i - 1] = 0
+ theta[:, i - 1] = torch.pi / 2 * torch.sign(vec_r_b[2])
+ else:
+ psi[:, i - 1] = torch.atan2(vec_r_b[1], vec_r_b[0])
+ theta[:, i - 1] = torch.atan2(
+ vec_r_b[2], torch.linalg.norm(vec_r_b[:2])
+ )
+
+ # gamma
+ end_q = quaternion[0, i]
+ end_mat = quaternion_to_matrix(end_q.roll(1))
+ end_x_axis = end_mat[:, 0]
+ gamma[:, i - 1] = torch.acos(torch.sum(end_x_axis * vec_r) / dist_r)
+
+ return cls(
+ position,
+ quaternion,
+ width,
+ height,
+ gate_flag,
+ gate_x_len_choice,
+ gate_weight_choice,
+ psi,
+ theta,
+ gamma,
+ r,
+ )
+
+ @property
+ def num_envs(self):
+ return self.position.shape[0]
+
+ @property
+ def num_waypoints(self):
+ return self.position.shape[1]
+
+ @property
+ def device(self):
+ return self.position.device
+
+ def to(self, device: str):
+ self.position = self.position.to(device=device)
+ self.quaternion = self.quaternion.to(device=device)
+ self.width = self.width.to(device=device)
+ self.height = self.height.to(device=device)
+ self.gate_flag = self.gate_flag.to(device=device)
+ self.gate_x_len_choice = self.gate_x_len_choice.to(device=device)
+ self.gate_weight_choice = self.gate_weight_choice.to(device=device)
+ self.psi = self.psi.to(device=device)
+ self.theta = self.theta.to(device=device)
+ self.gamma = self.gamma.to(device=device)
+ self.r = self.r.to(device=device)
+
+ def visualize(
+ self,
+ gym: Gym,
+ envs: List[Env],
+ viewer: Viewer,
+ axes_len: float,
+ ):
+ axes = gymutil.AxesGeometry(axes_len)
+ num_envs = len(envs)
+ assert num_envs == self.num_envs
+
+ for i in range(num_envs):
+ for j in range(self.num_waypoints):
+ x, y, z = self.position[i, j].tolist()
+ qx, qy, qz, qw = self.quaternion[i, j].tolist()
+ if j == 0:
+ box_color = (1.0, 0.0, 0.0)
+ else:
+ box_color = (0.0, 1.0, 0.0)
+ box = gymutil.WireframeBoxGeometry(
+ 0.1,
+ float(self.width[i, j]),
+ float(self.height[i, j]),
+ color=box_color,
+ )
+
+ tf = Transform()
+ tf.p = Vec3(x, y, z)
+ tf.r = Quat(qx, qy, qz, qw)
+ gymutil.draw_lines(axes, gym, viewer, envs[i], tf)
+ gymutil.draw_lines(box, gym, viewer, envs[i], tf)
+
+ if j < self.num_waypoints - 1:
+ x_next, y_next, z_next = self.position[i, j + 1].tolist()
+ p_next = Vec3(x_next, y_next, z_next)
+ line_color = Vec3(0.0, 1.0, 0.0)
+ gymutil.draw_line(tf.p, p_next, line_color, gym, viewer, envs[i])
diff --git a/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_generator.py b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_generator.py
new file mode 100644
index 000000000..9bf58d67b
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_generator.py
@@ -0,0 +1,207 @@
+from dataclasses import dataclass, field
+from typing import List
+
+import torch
+from torch import pi
+
+from isaacgym import torch_utils
+from .waypoint_data import WaypointData
+
+
+@dataclass
+class WaypointGeneratorParams:
+ num_envs: int = 64
+
+ num_waypoints: int = 4
+
+ num_gate_x_lens: int = 2
+
+ num_gate_weights: int = 2
+
+ gate_weight_max: float = 0.3
+
+ fixed_waypoint_id: int = 1
+
+ fixed_waypoint_position: List[float] = field(
+ default_factory=lambda: [0.0, 0.0, 0.0]
+ )
+
+
+@dataclass
+class RandWaypointOptions:
+
+ wp_size_min: float = 1.0
+
+ wp_size_max: float = 3.0
+
+ init_roll_max: float = pi / 6
+
+ init_pitch_max: float = pi / 6
+
+ init_yaw_max: float = pi / 1
+
+ psi_max: float = pi / 2
+
+ theta_max: float = pi / 4
+
+ alpha_max: float = pi / 1
+
+ gamma_max: float = pi / 6
+
+ r_min: float = 2.0
+
+ r_max: float = 20.0
+
+ # -1: random, 0: force 0, 1: force 1, other values raise error
+ force_gate_flag: int = -1
+
+ # if True, tracks for multiple envs are the same
+ same_track: bool = False
+
+
+class WaypointGenerator:
+
+ def __init__(self, params: WaypointGeneratorParams):
+ self.params = params
+ self.anchor_pos = torch.tensor(params.fixed_waypoint_position)
+
+ def compute(self, options: RandWaypointOptions) -> WaypointData:
+ """
+ Generates an instance of ``WaypointData`` randomly according to options.
+
+ Args:
+ options: An instance of ``RandomWaypointOptions`` containing min and max values for random sampling.
+
+ Returns:
+ - An instance of ``WaypointData``.
+ """
+
+ num_envs = self.params.num_envs
+ if options.same_track:
+ num_envs = 1
+
+ # waypoint width and height
+ wp_size_range = options.wp_size_max - options.wp_size_min
+ width = (
+ torch.rand(num_envs, self.params.num_waypoints) * wp_size_range
+ + options.wp_size_min
+ )
+ height = (
+ torch.rand(num_envs, self.params.num_waypoints) * wp_size_range
+ + options.wp_size_min
+ )
+
+ # associated gate params
+ assert -1 <= options.force_gate_flag <= 1
+ gate_flag = torch.randint(0, 2, (num_envs, self.params.num_waypoints))
+ if not options.force_gate_flag == -1:
+ gate_flag[:] = options.force_gate_flag
+ gate_x_len_id = torch.randint(
+ 0,
+ self.params.num_gate_x_lens,
+ (num_envs, self.params.num_waypoints),
+ )
+ gate_weight_id = torch.randint(
+ 0,
+ self.params.num_gate_weights,
+ (num_envs, self.params.num_waypoints),
+ )
+
+ # initial waypoint attitude
+ init_roll = (
+ torch.rand(num_envs) * 2 * options.init_roll_max - options.init_roll_max
+ )
+ init_pitch = (
+ torch.rand(num_envs) * 2 * options.init_pitch_max - options.init_pitch_max
+ )
+ init_yaw = (
+ torch.rand(num_envs) * 2 * options.init_yaw_max - options.init_yaw_max
+ )
+
+ # waypoint relative pose params
+ psi = (
+ torch.rand(num_envs, self.params.num_waypoints - 1) * 2 * options.psi_max
+ - options.psi_max
+ )
+ theta = (
+ torch.rand(num_envs, self.params.num_waypoints - 1) * 2 * options.theta_max
+ - options.theta_max
+ )
+ alpha = (
+ torch.rand(num_envs, self.params.num_waypoints - 1) * 2 * options.alpha_max
+ - options.alpha_max
+ )
+ gamma = torch.rand(num_envs, self.params.num_waypoints - 1) * options.gamma_max
+
+ r_wp = (
+ width**2 + height**2
+ ) ** 0.5 / 2 + gate_flag * 2**0.5 * self.params.gate_weight_max
+ r_lb = r_wp[:, :-1] + r_wp[:, 1:]
+ r_lb.clamp_(min=options.r_min)
+ r_ub = options.r_max * torch.ones_like(r_lb)
+ r_ub.clamp_(min=r_lb)
+ r_range = r_ub - r_lb
+ r = torch.rand(num_envs, self.params.num_waypoints - 1) * r_range + r_lb
+
+ # calculate pose
+ pos = torch.zeros(num_envs, self.params.num_waypoints, 3)
+ quat = torch.zeros(num_envs, self.params.num_waypoints, 4)
+ for i in range(self.params.num_waypoints):
+ if i == 0:
+ quat[:, i] = torch_utils.quat_from_euler_xyz(
+ init_roll, init_pitch, init_yaw
+ )
+ else:
+ psi_f = psi[:, i - 1]
+ theta_f = theta[:, i - 1]
+ alpha_f = alpha[:, i - 1]
+ gamma_f = gamma[:, i - 1]
+ zeros_f = torch.zeros_like(gamma_f)
+
+ q_psi_theta = torch_utils.quat_from_euler_xyz(zeros_f, -theta_f, psi_f)
+ q_alpha = torch_utils.quat_from_euler_xyz(alpha_f, zeros_f, zeros_f)
+ q_gamma = torch_utils.quat_from_euler_xyz(zeros_f, gamma_f, zeros_f)
+
+ q0 = quat[:, i - 1] # (num_envs, 4)
+ q1 = torch_utils.quat_mul(q0, q_psi_theta)
+ q2 = torch_utils.quat_mul(q1, q_alpha)
+ q3 = torch_utils.quat_mul(q2, q_gamma)
+ quat[:, i] = q3
+
+ r_vec = torch.zeros(num_envs, 3) # body frame
+ r_vec[:, 0] = r[:, i - 1]
+ r_vec_rotated = torch_utils.quat_rotate(q1, r_vec) # world frame
+ pos[:, i] = pos[:, i - 1] + r_vec_rotated
+
+ # anchor waypoints
+ offset = (
+ self.anchor_pos.unsqueeze(0) - pos[:, self.params.fixed_waypoint_id]
+ ) # (num_envs, 3)
+ pos += offset.unsqueeze(1)
+
+ if num_envs == 1:
+ pos = pos.expand(self.params.num_envs, -1, -1)
+ quat = quat.expand(self.params.num_envs, -1, -1)
+ width = width.expand(self.params.num_envs, -1)
+ height = height.expand(self.params.num_envs, -1)
+ gate_flag = gate_flag.expand(self.params.num_envs, -1)
+ gate_x_len_id = gate_x_len_id.expand(self.params.num_envs, -1)
+ gate_weight_id = gate_weight_id.expand(self.params.num_envs, -1)
+ psi = psi.expand(self.params.num_envs, -1)
+ theta = theta.expand(self.params.num_envs, -1)
+ gamma = gamma.expand(self.params.num_envs, -1)
+ r = r.expand(self.params.num_envs, -1)
+
+ return WaypointData(
+ position=pos,
+ quaternion=quat,
+ width=width,
+ height=height,
+ gate_flag=gate_flag,
+ gate_x_len_choice=gate_x_len_id,
+ gate_weight_choice=gate_weight_id,
+ psi=psi,
+ theta=theta,
+ gamma=gamma,
+ r=r,
+ )
diff --git a/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_tracker.py b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_tracker.py
new file mode 100644
index 000000000..0765fb7a7
--- /dev/null
+++ b/isaacgymenvs/tasks/drone_racing/waypoint/waypoint_tracker.py
@@ -0,0 +1,216 @@
+from dataclasses import dataclass
+from typing import Tuple
+
+import torch
+
+from isaacgymenvs.utils.torch_jit_utils import quaternion_to_matrix
+from .waypoint_data import WaypointData
+
+
+@dataclass
+class WaypointTrackerParams:
+ # number of parallel envs
+ num_envs: int = 64
+
+ # device to run tensor
+ device: str = "cuda"
+
+ # number of waypoints to track
+ # with the default observation, this number = total waypoint number - 1
+ # as the observation needs info of two future waypoints
+ # and the episode finishes at waypoint[-2]
+ num_waypoints: int = 3
+
+
+class WaypointTracker:
+
+ def __init__(self, params: WaypointTrackerParams):
+ self.params = params
+ self.all_env_id = torch.arange(self.params.num_envs)
+ self.all_wp_id_un_sq = torch.arange(
+ self.params.num_waypoints, device=params.device
+ ).unsqueeze(0)
+
+ self.wp_pos = torch.zeros(
+ params.num_envs, params.num_waypoints, 3, device=params.device
+ )
+ self.wp_x_axis = torch.zeros(
+ params.num_envs, params.num_waypoints, 3, device=params.device
+ )
+ self.wp_y_axis = torch.zeros(
+ params.num_envs, params.num_waypoints, 3, device=params.device
+ )
+ self.wp_z_axis = torch.zeros(
+ params.num_envs, params.num_waypoints, 3, device=params.device
+ )
+ self.wp_y_dim = torch.zeros(
+ params.num_envs, params.num_waypoints, device=params.device
+ )
+ self.wp_z_dim = torch.zeros(
+ params.num_envs, params.num_waypoints, device=params.device
+ )
+
+ self.is_wp_passed = torch.zeros(
+ params.num_envs,
+ params.num_waypoints,
+ dtype=torch.bool,
+ device=params.device,
+ )
+ self.last_drone_pos = torch.zeros(params.num_envs, 1, 3, device=params.device)
+
+ def set_waypoint_data(self, wp_data: WaypointData):
+ """
+ Extract waypoint information from waypoint data.
+ This should be called before the first call of ``compute``,
+ and whenever waypoint data needs to be updated.
+
+ Args:
+ wp_data: object of ``WaypointData``.
+ """
+
+ assert wp_data.num_waypoints > self.params.num_waypoints
+ assert wp_data.num_envs == self.params.num_envs
+
+ self.wp_pos[:] = wp_data.position[:, : self.params.num_waypoints].to(
+ device=self.params.device
+ )
+
+ wp_q = wp_data.quaternion[:, : self.params.num_waypoints].to(
+ device=self.params.device
+ )
+ wp_mat = quaternion_to_matrix(wp_q.roll(1, dims=2))
+ self.wp_x_axis[:] = wp_mat[:, :, :, 0]
+ self.wp_y_axis[:] = wp_mat[:, :, :, 1]
+ self.wp_z_axis[:] = wp_mat[:, :, :, 2]
+
+ self.wp_y_dim[:] = wp_data.width[:, : self.params.num_waypoints].to(
+ device=self.params.device
+ )
+ self.wp_z_dim[:] = wp_data.height[:, : self.params.num_waypoints].to(
+ device=self.params.device
+ )
+
+ def set_init_drone_state_next_wp(
+ self,
+ drone_state: torch.Tensor,
+ next_wp_id: torch.Tensor,
+ env_id: torch.Tensor = None,
+ ):
+ """
+ Sets initial drone positions and the next waypoint for all or selected envs.
+ This should be called before running ``compute`` for the first time,
+ and whenever drone positions have been reset.
+
+ Args:
+ drone_state: full drone state tensor in (num_envs, 13).
+ next_wp_id: next waypoint id in (num_envs, ).
+ env_id: 1-dim int tensor.
+ """
+
+ # by default all envs are selected
+ if env_id is None:
+ env_id = self.all_env_id
+
+ # set last drone pos as the init drone pos
+ self.last_drone_pos[env_id] = drone_state[env_id, :3].unsqueeze(1)
+
+ # set the waypoint passing flag tensor using next wp id
+ wp_passed = self.all_wp_id_un_sq < next_wp_id[env_id].unsqueeze(1)
+ self.is_wp_passed[env_id] = wp_passed
+
+ def compute(self, drone_state: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Checks waypoint passing and computes the next target waypoint id for all envs,
+ based on the updated drone state and last drone state stored internally.
+ This function is called during rollout.
+ Make sure to call ``set_waypoint_data`` and ``set_init_drone_pos`` properly
+ before running this function.
+
+ Args:
+ drone_state: full drone state tensor in (num_envs, 13).
+
+ Returns:
+ - Waypoint passing flag in (num_envs, ).
+ - Next target waypoint id in (num_envs, ).
+ """
+
+ self.last_drone_pos[:], self.is_wp_passed[:], wp_passing, next_wp_id = (
+ _compute_script(
+ wp_pos=self.wp_pos,
+ wp_x_axis=self.wp_x_axis,
+ wp_y_axis=self.wp_y_axis,
+ wp_z_axis=self.wp_z_axis,
+ wp_y_dim=self.wp_y_dim,
+ wp_z_dim=self.wp_z_dim,
+ is_wp_passed=self.is_wp_passed,
+ last_drone_pos=self.last_drone_pos,
+ drone_state=drone_state,
+ )
+ )
+
+ return wp_passing, next_wp_id
+
+
+@torch.jit.script
+def _compute_script(
+ wp_pos: torch.Tensor,
+ wp_x_axis: torch.Tensor,
+ wp_y_axis: torch.Tensor,
+ wp_z_axis: torch.Tensor,
+ wp_y_dim: torch.Tensor,
+ wp_z_dim: torch.Tensor,
+ is_wp_passed: torch.Tensor,
+ last_drone_pos: torch.Tensor,
+ drone_state: torch.Tensor,
+) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
+ # expand drone position dim and calculate some pos diffs (num_envs, num_waypoints, 3)
+ drone_pos = drone_state[:, :3].unsqueeze(1)
+ drone_pos_diff = drone_pos - last_drone_pos
+ last_drone_pos_to_wp = wp_pos - last_drone_pos
+
+ # calculate intersection point param (num_envs, num_waypoints, 1)
+ intersect_t_num = torch.sum(last_drone_pos_to_wp * wp_x_axis, dim=-1, keepdim=True)
+ intersect_t_den = torch.sum(drone_pos_diff * wp_x_axis, dim=-1, keepdim=True)
+ intersect_t = intersect_t_num / intersect_t_den
+
+ # intersection point positions (num_envs, num_waypoints, 3)
+ intersect_p = last_drone_pos + intersect_t * drone_pos_diff
+
+ # vector from waypoint center to intersection point (num_envs, num_waypoints, 3)
+ wp_to_intersect = intersect_p - wp_pos
+
+ # project wp to intersect to y and z axes (num_envs, num_waypoints)
+ intersect_proj_y = torch.sum(wp_to_intersect * wp_y_axis, dim=-1)
+ intersect_proj_z = torch.sum(wp_to_intersect * wp_z_axis, dim=-1)
+
+ # waypoint passing conditions (num_envs, num_waypoints)
+ cond_dir = intersect_t_den.squeeze() > 0
+
+ intersect_t_sq = intersect_t.squeeze()
+ cont_t_nan = ~torch.isnan(intersect_t_sq)
+ cond_t_lb = intersect_t_sq >= 0
+ cond_t_ub = intersect_t_sq < 1
+
+ cond_y_dim = intersect_proj_y.abs() < wp_y_dim / 2
+ cond_z_dim = intersect_proj_z.abs() < wp_z_dim / 2
+
+ cond_previous = is_wp_passed.roll(1, dims=1)
+ cond_previous[:, 0] = True
+
+ is_wp_passed_new = is_wp_passed | (
+ cond_dir
+ & cont_t_nan
+ & cond_t_lb
+ & cond_t_ub
+ & cond_y_dim
+ & cond_z_dim
+ & cond_previous
+ )
+
+ # calculate wp passing indicator
+ wp_passing = (is_wp_passed != is_wp_passed_new).any(dim=1)
+
+ # calculate next waypoint id (num_envs, )
+ next_wp_id = torch.eq(torch.cumsum(~is_wp_passed_new, dim=1), 1).max(dim=1).indices
+
+ return drone_pos, is_wp_passed_new, wp_passing, next_wp_id
diff --git a/isaacgymenvs/train.py b/isaacgymenvs/train.py
index 80c384414..fed64f74d 100644
--- a/isaacgymenvs/train.py
+++ b/isaacgymenvs/train.py
@@ -97,6 +97,7 @@ def launch_rlg_hydra(cfg: DictConfig):
from isaacgymenvs.learning import amp_players
from isaacgymenvs.learning import amp_models
from isaacgymenvs.learning import amp_network_builder
+ from isaacgymenvs.learning import dr_agent
import isaacgymenvs
@@ -186,6 +187,7 @@ def create_isaacgym_env(**kwargs):
def build_runner(algo_observer):
runner = Runner(algo_observer)
runner.algo_factory.register_builder('amp_continuous', lambda **kwargs : amp_continuous.AMPAgent(**kwargs))
+ runner.algo_factory.register_builder("dr_continuous", lambda **kwargs: dr_agent.DRAgent(**kwargs))
runner.player_factory.register_builder('amp_continuous', lambda **kwargs : amp_players.AMPPlayerContinuous(**kwargs))
model_builder.register_model('continuous_amp', lambda network, **kwargs : amp_models.ModelAMPContinuous(network))
model_builder.register_network('amp', lambda **kwargs : amp_network_builder.AMPBuilder())