Repository: EvolutionGym/evogym
Branch: main
Commit: f63c649c688a
Files: 467
Total size: 6.6 MB
Directory structure:
gitextract_7lcliole/
├── .github/
│ └── workflows/
│ ├── test.yml
│ └── wheels.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── MANIFEST.in
├── README.md
├── environment.yml
├── evogym/
│ ├── __init__.py
│ ├── envs/
│ │ ├── __init__.py
│ │ ├── balance.py
│ │ ├── base.py
│ │ ├── change_shape.py
│ │ ├── climb.py
│ │ ├── flip.py
│ │ ├── jump.py
│ │ ├── manipulate.py
│ │ ├── multi_goal.py
│ │ ├── sim_files/
│ │ │ ├── Balancer-v0.json
│ │ │ ├── Balancer-v1.json
│ │ │ ├── BeamSlider-v0.json
│ │ │ ├── BeamToppler-v0.json
│ │ │ ├── BidirectionalWalker-v0.json
│ │ │ ├── BridgeWalker-v0.json
│ │ │ ├── Carrier-v0.json
│ │ │ ├── Carrier-v1.json
│ │ │ ├── CaveCrawler-v0.json
│ │ │ ├── Climber-v0.json
│ │ │ ├── Climber-v1.json
│ │ │ ├── Climber-v2.json
│ │ │ ├── DownStepper-v0.json
│ │ │ ├── Flipper-v0.json
│ │ │ ├── GapJumper-v0.json
│ │ │ ├── Hurdler-v0.json
│ │ │ ├── Jumper-v0.json
│ │ │ ├── Lifter-v0.json
│ │ │ ├── ObstacleTraverser-v0.json
│ │ │ ├── ObstacleTraverser-v1.json
│ │ │ ├── PlatformJumper-v0.json
│ │ │ ├── Pusher-v0.json
│ │ │ ├── Pusher-v1.json
│ │ │ ├── ShapeChange.json
│ │ │ ├── Thrower-v0.json
│ │ │ ├── Traverser-v0.json
│ │ │ ├── UpStepper-v0.json
│ │ │ ├── Walker-v0.json
│ │ │ ├── package.json
│ │ │ ├── peg.json
│ │ │ ├── rigid_1x1.json
│ │ │ ├── rigid_2x2.json
│ │ │ └── rigid_3x3.json
│ │ ├── traverse.py
│ │ └── walk.py
│ ├── sim.py
│ ├── simulator/
│ │ ├── CMakeLists.txt
│ │ ├── FindGLEW.cmake
│ │ ├── SimulatorCPP/
│ │ │ ├── BBTreeNode.cpp
│ │ │ ├── BBTreeNode.h
│ │ │ ├── Boxel.cpp
│ │ │ ├── Boxel.h
│ │ │ ├── CMakeLists.txt
│ │ │ ├── Camera.cpp
│ │ │ ├── Camera.h
│ │ │ ├── Colors.h
│ │ │ ├── Edge.cpp
│ │ │ ├── Edge.h
│ │ │ ├── Environment.cpp
│ │ │ ├── Environment.h
│ │ │ ├── Interface.cpp
│ │ │ ├── Interface.h
│ │ │ ├── ObjectCreator.cpp
│ │ │ ├── ObjectCreator.h
│ │ │ ├── PhysicsEngine.cpp
│ │ │ ├── PhysicsEngine.h
│ │ │ ├── PythonBindings.cpp
│ │ │ ├── Robot.cpp
│ │ │ ├── Robot.h
│ │ │ ├── Sim.cpp
│ │ │ ├── Sim.h
│ │ │ ├── SimObject.cpp
│ │ │ ├── SimObject.h
│ │ │ ├── Snapshot.cpp
│ │ │ ├── Snapshot.h
│ │ │ ├── main.cpp
│ │ │ └── main.h
│ │ └── externals/
│ │ ├── CMakeLists.txt
│ │ └── eigen/
│ │ └── Eigen/
│ │ ├── Cholesky
│ │ ├── CholmodSupport
│ │ ├── Core
│ │ ├── Dense
│ │ ├── Eigen
│ │ ├── Eigenvalues
│ │ ├── Geometry
│ │ ├── Householder
│ │ ├── IterativeLinearSolvers
│ │ ├── Jacobi
│ │ ├── KLUSupport
│ │ ├── LU
│ │ ├── MetisSupport
│ │ ├── OrderingMethods
│ │ ├── PaStiXSupport
│ │ ├── PardisoSupport
│ │ ├── QR
│ │ ├── QtAlignedMalloc
│ │ ├── SPQRSupport
│ │ ├── SVD
│ │ ├── Sparse
│ │ ├── SparseCholesky
│ │ ├── SparseCore
│ │ ├── SparseLU
│ │ ├── SparseQR
│ │ ├── StdDeque
│ │ ├── StdList
│ │ ├── StdVector
│ │ ├── SuperLUSupport
│ │ ├── UmfPackSupport
│ │ └── src/
│ │ ├── Cholesky/
│ │ │ ├── LDLT.h
│ │ │ ├── LLT.h
│ │ │ └── LLT_LAPACKE.h
│ │ ├── CholmodSupport/
│ │ │ └── CholmodSupport.h
│ │ ├── Core/
│ │ │ ├── ArithmeticSequence.h
│ │ │ ├── Array.h
│ │ │ ├── ArrayBase.h
│ │ │ ├── ArrayWrapper.h
│ │ │ ├── Assign.h
│ │ │ ├── AssignEvaluator.h
│ │ │ ├── Assign_MKL.h
│ │ │ ├── BandMatrix.h
│ │ │ ├── Block.h
│ │ │ ├── BooleanRedux.h
│ │ │ ├── CommaInitializer.h
│ │ │ ├── ConditionEstimator.h
│ │ │ ├── CoreEvaluators.h
│ │ │ ├── CoreIterators.h
│ │ │ ├── CwiseBinaryOp.h
│ │ │ ├── CwiseNullaryOp.h
│ │ │ ├── CwiseTernaryOp.h
│ │ │ ├── CwiseUnaryOp.h
│ │ │ ├── CwiseUnaryView.h
│ │ │ ├── DenseBase.h
│ │ │ ├── DenseCoeffsBase.h
│ │ │ ├── DenseStorage.h
│ │ │ ├── Diagonal.h
│ │ │ ├── DiagonalMatrix.h
│ │ │ ├── DiagonalProduct.h
│ │ │ ├── Dot.h
│ │ │ ├── EigenBase.h
│ │ │ ├── ForceAlignedAccess.h
│ │ │ ├── Fuzzy.h
│ │ │ ├── GeneralProduct.h
│ │ │ ├── GenericPacketMath.h
│ │ │ ├── GlobalFunctions.h
│ │ │ ├── IO.h
│ │ │ ├── IndexedView.h
│ │ │ ├── Inverse.h
│ │ │ ├── Map.h
│ │ │ ├── MapBase.h
│ │ │ ├── MathFunctions.h
│ │ │ ├── MathFunctionsImpl.h
│ │ │ ├── Matrix.h
│ │ │ ├── MatrixBase.h
│ │ │ ├── NestByValue.h
│ │ │ ├── NoAlias.h
│ │ │ ├── NumTraits.h
│ │ │ ├── PartialReduxEvaluator.h
│ │ │ ├── PermutationMatrix.h
│ │ │ ├── PlainObjectBase.h
│ │ │ ├── Product.h
│ │ │ ├── ProductEvaluators.h
│ │ │ ├── Random.h
│ │ │ ├── Redux.h
│ │ │ ├── Ref.h
│ │ │ ├── Replicate.h
│ │ │ ├── Reshaped.h
│ │ │ ├── ReturnByValue.h
│ │ │ ├── Reverse.h
│ │ │ ├── Select.h
│ │ │ ├── SelfAdjointView.h
│ │ │ ├── SelfCwiseBinaryOp.h
│ │ │ ├── Solve.h
│ │ │ ├── SolveTriangular.h
│ │ │ ├── SolverBase.h
│ │ │ ├── StableNorm.h
│ │ │ ├── StlIterators.h
│ │ │ ├── Stride.h
│ │ │ ├── Swap.h
│ │ │ ├── Transpose.h
│ │ │ ├── Transpositions.h
│ │ │ ├── TriangularMatrix.h
│ │ │ ├── VectorBlock.h
│ │ │ ├── VectorwiseOp.h
│ │ │ ├── Visitor.h
│ │ │ ├── arch/
│ │ │ │ ├── AVX/
│ │ │ │ │ ├── Complex.h
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ ├── PacketMath.h
│ │ │ │ │ └── TypeCasting.h
│ │ │ │ ├── AVX512/
│ │ │ │ │ ├── Complex.h
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ ├── PacketMath.h
│ │ │ │ │ └── TypeCasting.h
│ │ │ │ ├── AltiVec/
│ │ │ │ │ ├── Complex.h
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ ├── MatrixProduct.h
│ │ │ │ │ ├── MatrixProductCommon.h
│ │ │ │ │ ├── MatrixProductMMA.h
│ │ │ │ │ └── PacketMath.h
│ │ │ │ ├── CUDA/
│ │ │ │ │ └── Complex.h
│ │ │ │ ├── Default/
│ │ │ │ │ ├── BFloat16.h
│ │ │ │ │ ├── ConjHelper.h
│ │ │ │ │ ├── GenericPacketMathFunctions.h
│ │ │ │ │ ├── GenericPacketMathFunctionsFwd.h
│ │ │ │ │ ├── Half.h
│ │ │ │ │ ├── Settings.h
│ │ │ │ │ └── TypeCasting.h
│ │ │ │ ├── GPU/
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ ├── PacketMath.h
│ │ │ │ │ └── TypeCasting.h
│ │ │ │ ├── HIP/
│ │ │ │ │ └── hcc/
│ │ │ │ │ └── math_constants.h
│ │ │ │ ├── MSA/
│ │ │ │ │ ├── Complex.h
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ └── PacketMath.h
│ │ │ │ ├── NEON/
│ │ │ │ │ ├── Complex.h
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ ├── PacketMath.h
│ │ │ │ │ └── TypeCasting.h
│ │ │ │ ├── SSE/
│ │ │ │ │ ├── Complex.h
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ ├── PacketMath.h
│ │ │ │ │ └── TypeCasting.h
│ │ │ │ ├── SYCL/
│ │ │ │ │ ├── InteropHeaders.h
│ │ │ │ │ ├── MathFunctions.h
│ │ │ │ │ ├── PacketMath.h
│ │ │ │ │ ├── SyclMemoryModel.h
│ │ │ │ │ └── TypeCasting.h
│ │ │ │ └── ZVector/
│ │ │ │ ├── Complex.h
│ │ │ │ ├── MathFunctions.h
│ │ │ │ └── PacketMath.h
│ │ │ ├── functors/
│ │ │ │ ├── AssignmentFunctors.h
│ │ │ │ ├── BinaryFunctors.h
│ │ │ │ ├── NullaryFunctors.h
│ │ │ │ ├── StlFunctors.h
│ │ │ │ ├── TernaryFunctors.h
│ │ │ │ └── UnaryFunctors.h
│ │ │ ├── products/
│ │ │ │ ├── GeneralBlockPanelKernel.h
│ │ │ │ ├── GeneralMatrixMatrix.h
│ │ │ │ ├── GeneralMatrixMatrixTriangular.h
│ │ │ │ ├── GeneralMatrixMatrixTriangular_BLAS.h
│ │ │ │ ├── GeneralMatrixMatrix_BLAS.h
│ │ │ │ ├── GeneralMatrixVector.h
│ │ │ │ ├── GeneralMatrixVector_BLAS.h
│ │ │ │ ├── Parallelizer.h
│ │ │ │ ├── SelfadjointMatrixMatrix.h
│ │ │ │ ├── SelfadjointMatrixMatrix_BLAS.h
│ │ │ │ ├── SelfadjointMatrixVector.h
│ │ │ │ ├── SelfadjointMatrixVector_BLAS.h
│ │ │ │ ├── SelfadjointProduct.h
│ │ │ │ ├── SelfadjointRank2Update.h
│ │ │ │ ├── TriangularMatrixMatrix.h
│ │ │ │ ├── TriangularMatrixMatrix_BLAS.h
│ │ │ │ ├── TriangularMatrixVector.h
│ │ │ │ ├── TriangularMatrixVector_BLAS.h
│ │ │ │ ├── TriangularSolverMatrix.h
│ │ │ │ ├── TriangularSolverMatrix_BLAS.h
│ │ │ │ └── TriangularSolverVector.h
│ │ │ └── util/
│ │ │ ├── BlasUtil.h
│ │ │ ├── ConfigureVectorization.h
│ │ │ ├── Constants.h
│ │ │ ├── DisableStupidWarnings.h
│ │ │ ├── ForwardDeclarations.h
│ │ │ ├── IndexedViewHelper.h
│ │ │ ├── IntegralConstant.h
│ │ │ ├── MKL_support.h
│ │ │ ├── Macros.h
│ │ │ ├── Memory.h
│ │ │ ├── Meta.h
│ │ │ ├── NonMPL2.h
│ │ │ ├── ReenableStupidWarnings.h
│ │ │ ├── ReshapedHelper.h
│ │ │ ├── StaticAssert.h
│ │ │ ├── SymbolicIndex.h
│ │ │ └── XprHelper.h
│ │ ├── Eigenvalues/
│ │ │ ├── ComplexEigenSolver.h
│ │ │ ├── ComplexSchur.h
│ │ │ ├── ComplexSchur_LAPACKE.h
│ │ │ ├── EigenSolver.h
│ │ │ ├── GeneralizedEigenSolver.h
│ │ │ ├── GeneralizedSelfAdjointEigenSolver.h
│ │ │ ├── HessenbergDecomposition.h
│ │ │ ├── MatrixBaseEigenvalues.h
│ │ │ ├── RealQZ.h
│ │ │ ├── RealSchur.h
│ │ │ ├── RealSchur_LAPACKE.h
│ │ │ ├── SelfAdjointEigenSolver.h
│ │ │ ├── SelfAdjointEigenSolver_LAPACKE.h
│ │ │ └── Tridiagonalization.h
│ │ ├── Geometry/
│ │ │ ├── AlignedBox.h
│ │ │ ├── AngleAxis.h
│ │ │ ├── EulerAngles.h
│ │ │ ├── Homogeneous.h
│ │ │ ├── Hyperplane.h
│ │ │ ├── OrthoMethods.h
│ │ │ ├── ParametrizedLine.h
│ │ │ ├── Quaternion.h
│ │ │ ├── Rotation2D.h
│ │ │ ├── RotationBase.h
│ │ │ ├── Scaling.h
│ │ │ ├── Transform.h
│ │ │ ├── Translation.h
│ │ │ ├── Umeyama.h
│ │ │ └── arch/
│ │ │ └── Geometry_SIMD.h
│ │ ├── Householder/
│ │ │ ├── BlockHouseholder.h
│ │ │ ├── Householder.h
│ │ │ └── HouseholderSequence.h
│ │ ├── IterativeLinearSolvers/
│ │ │ ├── BasicPreconditioners.h
│ │ │ ├── BiCGSTAB.h
│ │ │ ├── ConjugateGradient.h
│ │ │ ├── IncompleteCholesky.h
│ │ │ ├── IncompleteLUT.h
│ │ │ ├── IterativeSolverBase.h
│ │ │ ├── LeastSquareConjugateGradient.h
│ │ │ └── SolveWithGuess.h
│ │ ├── Jacobi/
│ │ │ └── Jacobi.h
│ │ ├── KLUSupport/
│ │ │ └── KLUSupport.h
│ │ ├── LU/
│ │ │ ├── Determinant.h
│ │ │ ├── FullPivLU.h
│ │ │ ├── InverseImpl.h
│ │ │ ├── PartialPivLU.h
│ │ │ ├── PartialPivLU_LAPACKE.h
│ │ │ └── arch/
│ │ │ └── InverseSize4.h
│ │ ├── MetisSupport/
│ │ │ └── MetisSupport.h
│ │ ├── OrderingMethods/
│ │ │ ├── Amd.h
│ │ │ ├── Eigen_Colamd.h
│ │ │ └── Ordering.h
│ │ ├── PaStiXSupport/
│ │ │ └── PaStiXSupport.h
│ │ ├── PardisoSupport/
│ │ │ └── PardisoSupport.h
│ │ ├── QR/
│ │ │ ├── ColPivHouseholderQR.h
│ │ │ ├── ColPivHouseholderQR_LAPACKE.h
│ │ │ ├── CompleteOrthogonalDecomposition.h
│ │ │ ├── FullPivHouseholderQR.h
│ │ │ ├── HouseholderQR.h
│ │ │ └── HouseholderQR_LAPACKE.h
│ │ ├── SPQRSupport/
│ │ │ └── SuiteSparseQRSupport.h
│ │ ├── SVD/
│ │ │ ├── BDCSVD.h
│ │ │ ├── JacobiSVD.h
│ │ │ ├── JacobiSVD_LAPACKE.h
│ │ │ ├── SVDBase.h
│ │ │ └── UpperBidiagonalization.h
│ │ ├── SparseCholesky/
│ │ │ ├── SimplicialCholesky.h
│ │ │ └── SimplicialCholesky_impl.h
│ │ ├── SparseCore/
│ │ │ ├── AmbiVector.h
│ │ │ ├── CompressedStorage.h
│ │ │ ├── ConservativeSparseSparseProduct.h
│ │ │ ├── MappedSparseMatrix.h
│ │ │ ├── SparseAssign.h
│ │ │ ├── SparseBlock.h
│ │ │ ├── SparseColEtree.h
│ │ │ ├── SparseCompressedBase.h
│ │ │ ├── SparseCwiseBinaryOp.h
│ │ │ ├── SparseCwiseUnaryOp.h
│ │ │ ├── SparseDenseProduct.h
│ │ │ ├── SparseDiagonalProduct.h
│ │ │ ├── SparseDot.h
│ │ │ ├── SparseFuzzy.h
│ │ │ ├── SparseMap.h
│ │ │ ├── SparseMatrix.h
│ │ │ ├── SparseMatrixBase.h
│ │ │ ├── SparsePermutation.h
│ │ │ ├── SparseProduct.h
│ │ │ ├── SparseRedux.h
│ │ │ ├── SparseRef.h
│ │ │ ├── SparseSelfAdjointView.h
│ │ │ ├── SparseSolverBase.h
│ │ │ ├── SparseSparseProductWithPruning.h
│ │ │ ├── SparseTranspose.h
│ │ │ ├── SparseTriangularView.h
│ │ │ ├── SparseUtil.h
│ │ │ ├── SparseVector.h
│ │ │ ├── SparseView.h
│ │ │ └── TriangularSolver.h
│ │ ├── SparseLU/
│ │ │ ├── SparseLU.h
│ │ │ ├── SparseLUImpl.h
│ │ │ ├── SparseLU_Memory.h
│ │ │ ├── SparseLU_Structs.h
│ │ │ ├── SparseLU_SupernodalMatrix.h
│ │ │ ├── SparseLU_Utils.h
│ │ │ ├── SparseLU_column_bmod.h
│ │ │ ├── SparseLU_column_dfs.h
│ │ │ ├── SparseLU_copy_to_ucol.h
│ │ │ ├── SparseLU_gemm_kernel.h
│ │ │ ├── SparseLU_heap_relax_snode.h
│ │ │ ├── SparseLU_kernel_bmod.h
│ │ │ ├── SparseLU_panel_bmod.h
│ │ │ ├── SparseLU_panel_dfs.h
│ │ │ ├── SparseLU_pivotL.h
│ │ │ ├── SparseLU_pruneL.h
│ │ │ └── SparseLU_relax_snode.h
│ │ ├── SparseQR/
│ │ │ └── SparseQR.h
│ │ ├── StlSupport/
│ │ │ ├── StdDeque.h
│ │ │ ├── StdList.h
│ │ │ ├── StdVector.h
│ │ │ └── details.h
│ │ ├── SuperLUSupport/
│ │ │ └── SuperLUSupport.h
│ │ ├── UmfPackSupport/
│ │ │ └── UmfPackSupport.h
│ │ ├── misc/
│ │ │ ├── Image.h
│ │ │ ├── Kernel.h
│ │ │ ├── RealSvd2x2.h
│ │ │ ├── blas.h
│ │ │ ├── lapack.h
│ │ │ ├── lapacke.h
│ │ │ └── lapacke_mangling.h
│ │ └── plugins/
│ │ ├── ArrayCwiseBinaryOps.h
│ │ ├── ArrayCwiseUnaryOps.h
│ │ ├── BlockMethods.h
│ │ ├── CommonCwiseBinaryOps.h
│ │ ├── CommonCwiseUnaryOps.h
│ │ ├── IndexedViewMethods.h
│ │ ├── MatrixCwiseBinaryOps.h
│ │ ├── MatrixCwiseUnaryOps.h
│ │ └── ReshapedMethods.h
│ ├── utils.py
│ ├── viewer.py
│ └── world.py
├── examples/
│ ├── README.md
│ ├── bo/
│ │ ├── optimizer.py
│ │ └── run.py
│ ├── cppn_neat/
│ │ ├── neat.cfg
│ │ ├── parallel.py
│ │ ├── population.py
│ │ └── run.py
│ ├── ga/
│ │ └── run.py
│ ├── gym_test.py
│ ├── make_gifs.py
│ ├── ppo/
│ │ ├── args.py
│ │ ├── callback.py
│ │ ├── eval.py
│ │ ├── group_ppo.py
│ │ └── run.py
│ ├── run_bo.py
│ ├── run_cppn_neat.py
│ ├── run_ga.py
│ ├── run_group_ppo.py
│ ├── run_ppo.py
│ ├── utils/
│ │ ├── algo_utils.py
│ │ └── mp_group.py
│ ├── visualize.py
│ └── world_data/
│ ├── carry_bot.json
│ ├── simple_evironment.json
│ └── speed_bot.json
├── pyproject.toml
├── requirements-dev.txt
├── requirements.txt
├── setup.py
├── tests/
│ ├── pytest.ini
│ ├── requires_screen/
│ │ └── test_screen_render_modes.py
│ ├── screen_free/
│ │ ├── test_baseline_envs.py
│ │ ├── test_img_render_modes.py
│ │ └── test_utils.py
│ └── utils.py
└── tutorials/
├── README.md
├── basic_api.py
├── envs/
│ ├── __init__.py
│ └── simple_env.py
├── rendering_options.py
├── visualize_simple_env.py
└── world_data/
├── simple_environment.json
├── simple_environment_with_robot.json
└── simple_walker_env.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on: [push]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build_and_test:
strategy:
fail-fast: false
matrix:
os:
- "ubuntu-latest"
python:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
- name: Update deb repository
run: sudo apt-get update
- name: Install deb dependencies
run: sudo apt-get install -y xorg-dev libglu1-mesa-dev libglew-dev xvfb
- name: Install python dependencies
run: pip install -r requirements-dev.txt
- name: Cache python wheel packages
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: wheel-cache-${{ hashFiles('requirements-dev.txt') }}
- name: Install evolution gym
run: pip install -e .
- name: Run test
run: xvfb-run python -m pytest -s -v -n auto -m lite
working-directory: tests
================================================
FILE: .github/workflows/wheels.yml
================================================
name: Build
on: [push]
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Window 64 bit
- os: windows-latest
platform_id: win_amd64
# Linux 64 bit
- os: ubuntu-latest
platform_id: manylinux_x86_64
manylinux_image: manylinux_2_28
# manylinux2014 dosen't work due to an issue in GLEW:
# https://github.com/glfw/glfw/issues/2139
# manylinux_image: manylinux2014
# MacOS x86_64 # Deprecated, github actions no longer support macos-12
# - os: macos-12
# platform_id: macosx_x86_64
# MacOS arm64
- os: macos-14
platform_id: macosx_arm64
steps:
- uses: actions/checkout@v4
with:
submodules: true
# Used to host cibuildwheel
- uses: actions/setup-python@v5
with:
python-version: "3.8"
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.19.0
# Build wheels
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
# to supply options, put them in 'env', like:
# env:
# CIBW_SOME_OPTION: value
# Upload wheels
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
================================================
FILE: .gitignore
================================================
evogym/simulator/.vs/
evogym/simulator/x64/
evogym/simulator/SimulatorCPP/x64/
old/
.vs/
.idea
.idea/
.vscode
*.vcxproj
*.vcxproj.*
*.sln
*.egg-info
dist/
build/
__pycache__/
examples/saved_data
examples/__pycache__
examples/api_planning.txt
evogym/__pycache__
evogym/envs/__pycache__
build_scripts
.DS_Store
exported/
req_ns.txt
backup/
================================================
FILE: .gitmodules
================================================
[submodule "examples/externals/pytorch_a2c_ppo_acktr_gail"]
path = examples/externals/pytorch_a2c_ppo_acktr_gail
url = https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail.git
[submodule "evogym/simulator/externals/pybind11"]
path = evogym/simulator/externals/pybind11
url = https://github.com/pybind/pybind11
[submodule "evogym/simulator/externals/glfw"]
path = evogym/simulator/externals/glfw
url = https://github.com/glfw/glfw
[submodule "evogym/simulator/externals/glew"]
path = evogym/simulator/externals/glew
url = https://github.com/Perlmint/glew-cmake
[submodule "examples/externals/PyTorch-NEAT"]
path = examples/externals/PyTorch-NEAT
url = https://github.com/uber-research/PyTorch-NEAT
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022 jagdeepsb
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
graft evogym/simulator
================================================
FILE: README.md
================================================
# Evolution Gym
[](https://github.com/EvolutionGym/evogym/actions/workflows/wheels.yml)
[](https://github.com/EvolutionGym/evogym/actions/workflows/test.yml)
Evolution Gym is a large-scale benchmark for co-optimizing the design and control of soft robots. It provides a lightweight soft-body simulator wrapped with a gym-like interface for developing learning algorithms. EvoGym also includes a suite of 32 locomotion and manipulation tasks, detailed on our [website](https://evolutiongym.github.io/all-tasks). Task suite evaluations are described in our [NeurIPS 2021 paper](https://arxiv.org/pdf/2201.09863).
)

# Installation
EvoGym supports python `3.7` to `3.10` on most operating systems:
```shell
pip install evogym --upgrade
```
On **Linux** install the following packages (or equivalent):
```shell
sudo apt-get install xorg-dev libglu1-mesa-dev
```
## From Source
If your platform is not supported, you may alternatively build from source:
### Requirements
* Python 3
* Linux, macOS, or Windows with [Visual Studios 2017](https://visualstudio.microsoft.com/vs/older-downloads/) build tools.
* [CMake](https://cmake.org/download/)
Clone the repo and submodules:
```shell
git clone --recurse-submodules https://github.com/EvolutionGym/evogym.git
```
On **Linux only**:
```shell
sudo apt-get install xorg-dev libglu1-mesa-dev
```
Finally, to install `evogym`, run the following in the environment of your choice:
```shell
pip install -e .
```
## Test Installation
If you have the repo cloned, `cd` to the `examples` folder and run the following script:
```shell
python gym_test.py
```
Alternatively, you can run the following snippet:
```python
import gymnasium as gym
import evogym.envs
from evogym import sample_robot
if __name__ == '__main__':
body, connections = sample_robot((5,5))
env = gym.make('Walker-v0', body=body, render_mode='human')
env.reset()
while True:
action = env.action_space.sample()
ob, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
env.reset()
env.close()
```
This script creates a random `5x5` robot in the `Walking-v0` environment. The robot is taking random actions. A window should open with a visualization of the environment -- kill the process from the terminal to close it.
## Known Issues
### Linux and Conda
Error message: `libGL error: MESA-LOADER: failed to open iris: /usr/lib/dri/iris_dri.so`
Fix: `conda install -c conda-forge libstdcxx-ng`
# Usage
In addition to the resources below, you can find API documentation on our [website](https://evolutiongym.github.io/documentation).
## Tutorials
You can find tutorials for getting started with the codebase on our [website](https://evolutiongym.github.io/tutorials). Completed code from all tutorials is also available in the `tutorials` folder, along with a `README`. Tutorials are included for:
- Using the [evogym API](https://evolutiongym.github.io/tutorials/basic-api.html)
- Making a [custom evogym environment](https://evolutiongym.github.io/tutorials/new-env.html)
- Supported [rendering options](https://github.com/EvolutionGym/evogym/blob/main/tutorials/rendering_options.py)
## Examples
To run co-design and control optimization experiments in EvoGym, please see the `examples` folder and its `README`. Included are scripts for:
- Running PPO
- Running a Genetic Algorithm
- Running Bayesian Optimization
- Running CPPN-NEAT
- Visualizing results
- Saving results as gifs
Make sure you clone the repo with submodules:
```shell
git clone --recurse-submodules https://github.com/EvolutionGym/evogym.git
```
Install the necessary python requirements:
```shell
pip install -r requirements.txt
```
## Design Tool
The Design Tool provides a gui for creating Evolution Gym environments. Please see [this repo](https://github.com/EvolutionGym/evogym-design-tool).
[//]: # (
)

## Headless Mode
EvoGym runs in headless mode by default, and avoids initializing rendering libraries until necessary. If using a server without rendering capabilities, ensure that:
```python
# Envs are created with render_mode=None (None by default)
env = gym.make('Walker-v0', body=body, render_mode=None)
```
```python
# If using the low-level api, do not call EvoViewer.render()
world = EvoWorld.from_json(os.path.join('world_data', 'simple_environment.json'))
sim = EvoSim(world)
viewer = EvoViewer(sim)
viewer.render('img') # <-- Rendering libraries are initialized; do not call this
```
# Datasets
We've released two datasets of robot structures and policies from the original EvoGym paper. Instructions for downloading and using these datasets are available in the [evogym-datasets](https://github.com/EvolutionGym/evogym-datasets) repo. All datasets are hosted on [huggingface](https://huggingface.co/EvoGym).
- [EvoGym/robots](https://huggingface.co/datasets/EvoGym/robots): 90k+ annotated robot structures
- [EvoGym/robot-with-policies](https://huggingface.co/datasets/EvoGym/robots-with-policies): 2.5k+ annotated robot structures and policies
# Dev
Install the repo with submodules:
```shell
git clone --recurse-submodules https://github.com/EvolutionGym/evogym.git
```
Install the necessary python requirements. You will additionally need to install the dev requirements:
```shell
pip install -r requirements.txt
pip install -r requirements-dev.txt
```
## Run Tests
From within the `tests` directory run the full test suite:
```shell
cd tests
pytest -s -v -n auto
```
Or the lite test suite:
```shell
cd tests
pytest -s -v -n auto -m lite
```
# Citation
If you find our repository helpful to your research, please cite our paper:
```
@article{bhatia2021evolution,
title={Evolution gym: A large-scale benchmark for evolving soft robots},
author={Bhatia, Jagdeep and Jackson, Holly and Tian, Yunsheng and Xu, Jie and Matusik, Wojciech},
journal={Advances in Neural Information Processing Systems},
volume={34},
year={2021}
}
```
================================================
FILE: environment.yml
================================================
name: evogym
channels:
- defaults
dependencies:
- python=3.7.11
- pip
- pip:
- glfw==2.5.0
- gpy==1.10.0
- git+https://github.com/yunshengtian/neat-python@2762ab630838520ca6c03a866e8a158f592b0370
- gym==0.22.0
- h5py==3.6.0
- imageio==2.14.1
- matplotlib==3.5.1
- git+https://github.com/yunshengtian/GPyOpt@5fc1188ffdefea9a3bc7964a9414d4922603e904
- numpy==1.21.5
- opencv-python==4.5.5.62
- pillow==9.0.0
- pybind11==2.9.0
- pygifsicle==1.0.5
- pyopengl==3.1.5
- pyopengl-accelerate==3.1.5
- torch==1.10.2
- ttkbootstrap==1.5.1
- typing==3.7.4.3
================================================
FILE: evogym/__init__.py
================================================
from evogym.world import EvoWorld, WorldObject
from evogym.sim import EvoSim
from evogym.viewer import EvoViewer
from evogym.utils import *
================================================
FILE: evogym/envs/__init__.py
================================================
from evogym.envs.base import *
from evogym.envs.balance import *
from evogym.envs.manipulate import *
from evogym.envs.climb import *
from evogym.envs.flip import *
from evogym.envs.jump import *
from evogym.envs.multi_goal import *
from evogym.envs.change_shape import *
from evogym.envs.traverse import *
from evogym.envs.walk import *
from gymnasium.envs.registration import register
## SIMPLE ##
register(
id = 'Walker-v0',
entry_point = 'evogym.envs.walk:WalkingFlat',
max_episode_steps=500
)
register(
id = 'BridgeWalker-v0',
entry_point = 'evogym.envs.walk:SoftBridge',
max_episode_steps=500
)
register(
id = 'CaveCrawler-v0',
entry_point = 'evogym.envs.walk:Duck',
max_episode_steps=1000
)
register(
id = 'Jumper-v0',
entry_point = 'evogym.envs.jump:StationaryJump',
max_episode_steps=500
)
register(
id = 'Flipper-v0',
entry_point = 'evogym.envs.flip:Flipping',
max_episode_steps=600
)
register(
id = 'Balancer-v0',
entry_point = 'evogym.envs.balance:Balance',
max_episode_steps=600
)
register(
id = 'Balancer-v1',
entry_point = 'evogym.envs.balance:BalanceJump',
max_episode_steps=600
)
register(
id = 'UpStepper-v0',
entry_point = 'evogym.envs.traverse:StepsUp',
max_episode_steps=600
)
register(
id = 'DownStepper-v0',
entry_point = 'evogym.envs.traverse:StepsDown',
max_episode_steps=500
)
register(
id = 'ObstacleTraverser-v0',
entry_point = 'evogym.envs.traverse:WalkingBumpy',
max_episode_steps=1000
)
register(
id = 'ObstacleTraverser-v1',
entry_point = 'evogym.envs.traverse:WalkingBumpy2',
max_episode_steps=1000
)
register(
id = 'Hurdler-v0',
entry_point = 'evogym.envs.traverse:VerticalBarrier',
max_episode_steps=1000
)
register(
id = 'GapJumper-v0',
entry_point = 'evogym.envs.traverse:Gaps',
max_episode_steps=1000
)
register(
id = 'PlatformJumper-v0',
entry_point = 'evogym.envs.traverse:FloatingPlatform',
max_episode_steps=1000
)
register(
id = 'Traverser-v0',
entry_point = 'evogym.envs.traverse:BlockSoup',
max_episode_steps=600
)
## PACKAGE ##
register(
id = 'Lifter-v0',
entry_point = 'evogym.envs.manipulate:LiftSmallRect',
max_episode_steps=300
)
register(
id = 'Carrier-v0',
entry_point = 'evogym.envs.manipulate:CarrySmallRect',
max_episode_steps=500
)
register(
id = 'Carrier-v1',
entry_point = 'evogym.envs.manipulate:CarrySmallRectToTable',
max_episode_steps=1000
)
register(
id = 'Pusher-v0',
entry_point = 'evogym.envs.manipulate:PushSmallRect',
max_episode_steps=500
)
register(
id = 'Pusher-v1',
entry_point = 'evogym.envs.manipulate:PushSmallRectOnOppositeSide',
max_episode_steps=600
)
register(
id = 'BeamToppler-v0',
entry_point = 'evogym.envs.manipulate:ToppleBeam',
max_episode_steps=1000
)
register(
id = 'BeamSlider-v0',
entry_point = 'evogym.envs.manipulate:SlideBeam',
max_episode_steps=1000
)
register(
id = 'Thrower-v0',
entry_point = 'evogym.envs.manipulate:ThrowSmallRect',
max_episode_steps=300
)
register(
id = 'Catcher-v0',
entry_point = 'evogym.envs.manipulate:CatchSmallRect',
max_episode_steps=400
)
### SHAPE ###
register(
id = 'AreaMaximizer-v0',
entry_point = 'evogym.envs.change_shape:MaximizeShape',
max_episode_steps=600
)
register(
id = 'AreaMinimizer-v0',
entry_point = 'evogym.envs.change_shape:MinimizeShape',
max_episode_steps=600
)
register(
id = 'WingspanMazimizer-v0',
entry_point = 'evogym.envs.change_shape:MaximizeXShape',
max_episode_steps=600
)
register(
id = 'HeightMaximizer-v0',
entry_point = 'evogym.envs.change_shape:MaximizeYShape',
max_episode_steps=500
)
### CLIMB ###
register(
id = 'Climber-v0',
entry_point = 'evogym.envs.climb:Climb0',
max_episode_steps=400
)
register(
id = 'Climber-v1',
entry_point = 'evogym.envs.climb:Climb1',
max_episode_steps=600
)
register(
id = 'Climber-v2',
entry_point = 'evogym.envs.climb:Climb2',
max_episode_steps=1000
)
### MULTI GOAL ###
register(
id = 'BidirectionalWalker-v0',
entry_point = 'evogym.envs.multi_goal:BiWalk',
max_episode_steps=1000
)
================================================
FILE: evogym/envs/balance.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
from typing import Dict, Any, Optional
class Balance(BenchmarkBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Balancer-v0.json'))
self.world.add_from_array('robot', body, 15, 3, connections=connections)
# init sim
BenchmarkBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(1 + num_robot_points,), dtype=float)
def get_obs(self, pos_final):
com_final = np.mean(pos_final, 1)
return np.array([
17*self.VOXEL_SIZE - com_final[0],
5.5*self.VOXEL_SIZE - com_final[1],
])
def get_reward(self, pos_init, pos_final):
com_init = np.mean(pos_init, 1)
com_final = np.mean(pos_final, 1)
reward = abs(17*self.VOXEL_SIZE - com_init[0]) - abs(17*self.VOXEL_SIZE - com_final[0])
reward += (abs(5.0*self.VOXEL_SIZE - com_init[1]) - abs(5.0*self.VOXEL_SIZE - com_final[1]))
return reward
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
ort = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
np.array([ort]),
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward(pos_1, pos_2)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
class BalanceJump(BenchmarkBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Balancer-v1.json'))
self.world.add_from_array('robot', body, 10, 1, connections=connections)
# init sim
BenchmarkBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(1 + num_robot_points,), dtype=float)
def get_obs(self, pos_final):
com_final = np.mean(pos_final, 1)
return np.array([
17.5*self.VOXEL_SIZE - com_final[0],
6*self.VOXEL_SIZE - com_final[1],
])
def get_reward(self, pos_init, pos_final):
com_init = np.mean(pos_init, 1)
com_final = np.mean(pos_final, 1)
reward = abs(17.5*self.VOXEL_SIZE - com_init[0]) - abs(17.5*self.VOXEL_SIZE - com_final[0])
reward += (abs(6*self.VOXEL_SIZE - com_init[1]) - abs(6*self.VOXEL_SIZE - com_final[1]))
return reward
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
ort = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
np.array([ort]),
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward(pos_1, pos_2)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
================================================
FILE: evogym/envs/base.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from typing import Dict, Optional, List, Any
from evogym import *
import random
import math
import pkg_resources
import numpy as np
import os
class EvoGymBase(gym.Env):
"""
Base class for all Evolution Gym environments.
Args:
world (EvoWorld): object specifying the voxel layout of the environment.
render_mode (Optional[str]): values of `screen` and `human` will automatically render to a debug window every `step()`. If set to `img` or `rgb_array`, `render()` will return an image array. No rendering by default (default = None)
render_options (Optional[Dict[str, Any]]): dictionary of rendering options. See EvoGymBase.render() for details (default = None)
"""
metadata = {'render_modes': ['screen', 'human', 'img', 'rgb_array']}
def __init__(
self,
world: EvoWorld,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
) -> None:
# sim
self._sim = EvoSim(world)
self._default_viewer = EvoViewer(self._sim)
# render
self._render_mode = render_mode
self._render_options = render_options
def step(self, action: Dict[str, np.ndarray]) -> bool:
"""
Step the environment by running physics computations.
Args:
action (Dict[str, np.ndarray]): dictionary mapping robot names to actions. Actions are `(n,)` arrays, where `n` is the number of actuators in the target robot.
Returns:
bool: whether or not the simulation has reached an unstable state and cannot be recovered (`True` = unstable).
"""
#step
for robot_name, a in action.items():
a = np.clip(a, 0.6, 1.6)
a[abs(a) < 1e-8] = 0
self._sim.set_action(robot_name, a)
done = self._sim.step()
if self._render_mode == 'human' or self._render_mode == 'screen':
self.render()
return done
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> None:
"""
Reset the simulation to the initial state.
"""
self._sim.reset()
@property
def sim(self,) -> EvoSim:
"""
Returns the environment's simulation.
Returns:
EvoSim: simulation object to return.
"""
return self._sim
@property
def default_viewer(self,) -> EvoViewer:
"""
Returns the environment's default viewer.
Returns:
EvoSim: viewer object to return.
"""
return self._default_viewer
def render(
self,
) -> Optional[np.ndarray]:
"""
Render the simulation according to the `render_mode` and `render_options` specified at initialization.
The following rendering options are available as key-value pairs in the `render_options` dictionary:
- `verbose` (bool): whether or not to print the rendering speed (rps) every second. (default = False)
- `hide_background` (bool): whether or not to render the cream-colored background. If shut off background will be white. (default = False)
- `hide_grid` (bool): whether or not to render the grid. (default = False)
- `hide_edges` (bool): whether or not to render edges around all objects. (default = False)
- `hide_voxels` (bool): whether or not to render voxels. (default = False)
Returns:
Optional[np.ndarray]: if `mode` is set to `img` or `rgb_array`, will return an image array. Otherwise, will return `None`.
"""
mode, render_options = self._render_mode, {} if self._render_options is None else self._render_options
if mode is None:
return None
verbose = render_options.get('verbose', False)
hide_background = render_options.get('hide_background', False)
hide_grid = render_options.get('hide_grid', False)
hide_edges = render_options.get('hide_edges', False)
hide_voxels = render_options.get('hide_voxels', False)
return self.default_viewer.render(mode, verbose, hide_background, hide_grid, hide_edges, hide_voxels)
def close(self) -> None:
"""
Close the simulation.
"""
self.default_viewer.close()
del self._default_viewer
del self._sim
def get_actuator_indices(self, robot_name: str) -> np.ndarray:
"""
Returns the voxel indices a target robot's actuators in the environment's simulation.
Args:
robot_name (str): name of robot.
Returns:
np.ndarray: `(n,)` array of actuator indices, where `n` is the number of actuators.
"""
return self._sim.get_actuator_indices(robot_name)
def get_dim_action_space(self, robot_name: str) -> int:
"""
Returns the number of actuators for a target robot in the environment's simulation.
Args:
robot_name (str): name of robot.
Returns:
int: number of actuators.
"""
return self._sim.get_dim_action_space(robot_name)
def get_time(self, ) -> int:
"""
Returns the current time as defined in the environment's simulator. Time starts at `0` and is incremented each time the environment steps. Time resets to `0` when the environment is reset.
Returns:
int: the current time.
"""
return self._sim.get_time()
def pos_at_time(self, time: int) -> np.ndarray:
"""
Returns positions of all point-masses in the environment's simulation at time `time`. Use `EvoGymBase.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of points in the environment's simulation.
"""
return self._sim.pos_at_time(time)
def vel_at_time(self, time: int) -> np.ndarray:
"""
Returns velocities of all point-masses in the environment's simulation at time `time`. Use `EvoGymBase.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of points in the environment's simulation.
"""
return self._sim.vel_at_time(time)
def object_pos_at_time(self, time: int, object_name: str) -> np.ndarray:
"""
Returns positions of all point-masses in a target object at time `time`. Use `EvoGymBase.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
object_name (str): name of object
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of point-masses in the target object.
"""
return self._sim.object_pos_at_time(time, object_name)
def object_vel_at_time(self, time: int, object_name: str) -> np.ndarray:
"""
Returns velocities of all point-masses in a target object at time `time`. Use `EvoGymBase.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
object_name (str): name of object
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of point-masses in the target object.
"""
return self._sim.object_vel_at_time(time, object_name)
def object_orientation_at_time(self, time: int, object_name: str) -> float:
"""
Returns an estimate of the orientation of an object at time `time`. Use `EvoGymBase.get_time()` to get current measurements.
Args:
time (int): time at which to return measurement.
object_name (str): name of object
Returns:
float: orientation with respect to x-axis in radians (increasing counter-clockwise) from the range [0, 2π].
"""
return self._sim.object_orientation_at_time(time, object_name)
def get_pos_com_obs(self, object_name: str) -> np.ndarray:
"""
Observation helper-function. Computes the position of the center of mass of a target object by averaging the positions of the object's point masses.
Args:
object_name (str): name of object
Returns:
np.ndarray: `(2,)` array of the position of the center of mass.
"""
object_points_pos = self._sim.object_pos_at_time(self.get_time(), object_name)
object_pos_com = np.mean(object_points_pos, axis=1)
return np.array([object_pos_com[0], object_pos_com[1]])
def get_vel_com_obs(self, object_name: str) -> np.ndarray:
"""
Observation helper-function. Computes the velocity of the center of mass of a target object by averaging the velocities of the object's point masses.
Args:
object_name (str): name of object
Returns:
np.ndarray: `(2,)` array of the velocity of the center of mass.
"""
object_points_vel = self._sim.object_vel_at_time(self.get_time(), object_name)
object_vel_com = np.mean(object_points_vel, axis=1)
return np.array([object_vel_com[0], object_vel_com[1]])
def get_relative_pos_obs(self, object_name: str):
"""
Observation helper-function. Computes the positions of a target object's point masses relative to their center of mass.
Args:
object_name (str): name of object
Returns:
np.ndarray: `(2n,)` array of positions, where `n` is the number of point masses.
"""
object_points_pos = self._sim.object_pos_at_time(self.get_time(), object_name)
object_pos_com = np.mean(object_points_pos, axis=1)
return (object_points_pos-np.array([object_pos_com]).T).flatten()
def get_ort_obs(self, object_name: str):
"""
Observation helper-function. Returns the orientation of a target object.
Args:
object_name (str): name of object
Returns:
np.ndarray: `(1,)` array of the object's orientation.
"""
return np.array([self.object_orientation_at_time(self.get_time(), object_name)])
def get_floor_obs(
self,
object_name: str,
terrain_list: List[str],
sight_dist: int,
sight_range: float = 5) -> np.ndarray:
"""
Observation helper-function. Computes an observation describing the shape of the terrain below the target object. Specifically, for each voxel to the left and right of the target object's center of mass (along with the voxel containing the center of mass), the following observation is computed: min(y-distance in voxels to the nearest terrain object below the target object's center of mass, `sight_range`). Results are returned in a 1D numpy array.
Args:
object_name (str): name of target object.
terrain_list (List[str]): names of objects to be considered terrain in the computation.
sight_dist (int): number of voxels to the left and right of the target object's center of mass for which an observation should be returned.
sight_range (float): the max number of voxels below the object that can be seen. (default = 5)
Returns:
np.ndarray: `(2 * sight_range + 1, )` array of distance observations.
"""
object_points_pos = self._sim.object_pos_at_time(self.get_time(), object_name)
object_pos_com = np.mean(object_points_pos, axis=1)
if len(terrain_list) == 0:
return None
terrain_pos = self._sim.object_pos_at_time(self.get_time(), terrain_list[0])
for i in range(1, len(terrain_list)):
terrain_pos = np.concatenate((terrain_pos, self._sim.object_pos_at_time(self.get_time(), terrain_list[i])), axis = 1)
right_mask = terrain_pos[0, :] > (object_pos_com[0] - (sight_dist+0.5))
terrain_pos = terrain_pos[:, right_mask]
left_mask = terrain_pos[0, :] < (object_pos_com[0] + (sight_dist+0.5))
terrain_pos = terrain_pos[:, left_mask]
bot_mask = terrain_pos[1, :] < (object_pos_com[1])
terrain_pos = terrain_pos[:, bot_mask]
elevations = np.zeros((sight_dist*2+1)) - sight_range + object_pos_com[1]
for i in range(-sight_dist, sight_dist+1):
less_than_mask = terrain_pos[0, :] > (object_pos_com[0] + (i-0.5))
greater_than_mask = terrain_pos[0, :] < (object_pos_com[0] + (i+0.5))
try:
max_elevation = np.max(terrain_pos[1, (less_than_mask & greater_than_mask)])
elevations[i+sight_dist] = max_elevation
except:
pass
elevations = object_pos_com[1] - elevations
elevations = np.clip(elevations, 0, sight_range)
return elevations
def get_ceil_obs(
self,
object_name: str,
terrain_list: List[str],
sight_dist: int,
sight_range: float = 5) -> np.ndarray:
"""
Observation helper-function. Computes an observation describing the shape of the terrain above the target object. Specifically, for each voxel to the left and right of the target object's center of mass (along with the voxel containing the center of mass), the following observation is computed: min(y-distance in voxels to the nearest terrain object above the target object's center of mass, `sight_range`). Results are returned in a 1D numpy array.
Args:
object_name (str): name of target object.
terrain_list (List[str]): names of objects to be considered terrain in the computation.
sight_dist (int): number of voxels to the left and right of the target object's center of mass for which an observation should be returned.
sight_range (float): the max number of voxels above the object that can be seen. (default = 5)
Returns:
np.ndarray: `(2 * sight_range + 1, )` array of distance observations.
"""
object_points_pos = self._sim.object_pos_at_time(self.get_time(), object_name)
object_pos_com = np.mean(object_points_pos, axis=1)
if len(terrain_list) == 0:
return None
terrain_pos = self._sim.object_pos_at_time(self.get_time(), terrain_list[0])
for i in range(1, len(terrain_list)):
terrain_pos = np.concatenate((terrain_pos, self._sim.object_pos_at_time(self.get_time(), terrain_list[i])), axis = 1)
right_mask = terrain_pos[0, :] > (object_pos_com[0] - (sight_dist+0.5))
terrain_pos = terrain_pos[:, right_mask]
left_mask = terrain_pos[0, :] < (object_pos_com[0] + (sight_dist+0.5))
terrain_pos = terrain_pos[:, left_mask]
bot_mask = terrain_pos[1, :] > (object_pos_com[1])
terrain_pos = terrain_pos[:, bot_mask]
elevations = np.zeros((sight_dist*2+1)) + sight_range + object_pos_com[1]
for i in range(-sight_dist, sight_dist+1):
less_than_mask = terrain_pos[0, :] > (object_pos_com[0] + (i-0.5))
greater_than_mask = terrain_pos[0, :] < (object_pos_com[0] + (i+0.5))
try:
max_elevation = np.min(terrain_pos[1, (less_than_mask & greater_than_mask)])
elevations[i+sight_dist] = max_elevation
except:
pass
elevations = elevations - object_pos_com[1]
elevations = np.clip(elevations, 0, sight_range)
return elevations
class BenchmarkBase(EvoGymBase):
DATA_PATH = pkg_resources.resource_filename('evogym.envs', os.path.join('sim_files'))
VOXEL_SIZE = 0.1
def __init__(
self,
world: EvoWorld,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
EvoGymBase.__init__(self, world=world, render_mode=render_mode, render_options=render_options)
self.default_viewer.track_objects('robot')
def pos_at_time(self, time):
return super().pos_at_time(time)*self.VOXEL_SIZE
def vel_at_time(self, time):
return super().vel_at_time(time)*self.VOXEL_SIZE
def object_pos_at_time(self, time, object_name):
return super().object_pos_at_time(time, object_name)*self.VOXEL_SIZE
def object_vel_at_time(self, time, object_name):
return super().object_vel_at_time(time, object_name)*self.VOXEL_SIZE
def get_pos_com_obs(self, object_name):
return super().get_pos_com_obs(object_name)*self.VOXEL_SIZE
def get_vel_com_obs(self, object_name):
temp = super().get_vel_com_obs(object_name)*self.VOXEL_SIZE
# print(f'child says super vel obs: {super().get_vel_com_obs(object_name)}\n')
# print(f'vel obs: {temp}\n\n')
return temp
def get_relative_pos_obs(self, object_name):
return super().get_relative_pos_obs(object_name)*self.VOXEL_SIZE
def get_floor_obs(self, object_name, terrain_list, sight_dist, sight_range = 5):
return super().get_floor_obs(object_name, terrain_list, sight_dist, sight_range)*self.VOXEL_SIZE
def get_ceil_obs(self, object_name, terrain_list, sight_dist, sight_range = 5):
return super().get_ceil_obs(object_name, terrain_list, sight_dist, sight_range)*self.VOXEL_SIZE
================================================
FILE: evogym/envs/change_shape.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
from math import *
import numpy as np
import os
from typing import Dict, Any, Optional
class ShapeBase(BenchmarkBase):
def __init__(
self,
world: EvoWorld,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
super().__init__(world=world, render_mode=render_mode, render_options=render_options)
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_relative_pos_obs("robot"),
))
return obs, {}
### ----------------------------------------------------------------------
# This section of code is modified from the following author
# from https://github.com/RodolfoFerro/ConvexHull
# Author: Rodolfo Ferro
# Mail: ferro@cimat.mx
# Script: Compute the Convex Hull of a set of points using the Graham Scan
# Function to know if we have a CCW turn
def CCW(self, p1, p2, p3):
if (p3[1]-p1[1])*(p2[0]-p1[0]) >= (p2[1]-p1[1])*(p3[0]-p1[0]):
return True
return False
# Main function:
def jarvis_march(self, S):
n = len(S)
P = [None] * n
l = np.where(S[:,0] == np.min(S[:,0]))
pointOnHull = S[l[0][0]]
i = 0
while True:
P[i] = pointOnHull
endpoint = S[0]
for j in range(1,n):
if (endpoint[0] == pointOnHull[0] and endpoint[1] == pointOnHull[1]) or not self.CCW(S[j],P[i],endpoint):
endpoint = S[j]
i = i + 1
pointOnHull = endpoint
if endpoint[0] == P[0][0] and endpoint[1] == P[0][1]:
break
for i in range(n):
if P[-1] is None:
del P[-1]
return np.array(P)
### ----------------------------------------------------------------------
def convex_poly_area(self, pts_cw):
area = 0
for i in range(len(pts_cw)):
i_1 = i + 1
if i_1 >= len(pts_cw):
i_1 = 0
area += (pts_cw[i,0] * pts_cw[i_1,1] - pts_cw[i_1,0] * pts_cw[i,1])
return 0.5 * area
class MaximizeShape(ShapeBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'ShapeChange.json'))
self.world.add_from_array('robot', body, 7, 1, connections=connections)
# init sim
ShapeBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def get_reward(self, robot_pos_init, robot_pos_final):
# find convex hull of initial state
convex_hull_init = self.jarvis_march(np.transpose(robot_pos_init))
area_init = self.convex_poly_area(convex_hull_init)
# find convex of final state
convex_hull_final = self.jarvis_march(np.transpose(robot_pos_final))
area_final = self.convex_poly_area(convex_hull_final)
reward = (area_final - area_init) * 10
return reward
class MinimizeShape(ShapeBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'ShapeChange.json'))
self.world.add_from_array('robot', body, 7, 1, connections=connections)
# init sim
ShapeBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def get_reward(self, robot_pos_init, robot_pos_final):
# find convex hull of initial state
convex_hull_init = self.jarvis_march(np.transpose(robot_pos_init))
area_init = self.convex_poly_area(convex_hull_init)
# find convex of final state
convex_hull_final = self.jarvis_march(np.transpose(robot_pos_final))
area_final = self.convex_poly_area(convex_hull_final)
reward = (area_init - area_final) * 10
return reward
class MaximizeXShape(ShapeBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'ShapeChange.json'))
self.world.add_from_array('robot', body, 7, 1, connections=connections)
# init sim
ShapeBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def get_reward(self, robot_pos_init, robot_pos_final):
robot_min_pos_init = np.min(robot_pos_init, axis=1)
robot_max_pos_init = np.max(robot_pos_init, axis=1)
robot_min_pos_final = np.min(robot_pos_final, axis=1)
robot_max_pos_final = np.max(robot_pos_final, axis=1)
span_final = (robot_max_pos_final[0] - robot_min_pos_final[0])
span_initial = (robot_max_pos_init[0] - robot_min_pos_init[0])
reward = (span_final - span_initial)
return reward
class MaximizeYShape(ShapeBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'ShapeChange.json'))
self.world.add_from_array('robot', body, 7, 1, connections=connections)
# init sim
ShapeBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def get_reward(self, robot_pos_init, robot_pos_final):
robot_min_pos_init = np.min(robot_pos_init, axis=1)
robot_max_pos_init = np.max(robot_pos_init, axis=1)
robot_min_pos_final = np.min(robot_pos_final, axis=1)
robot_max_pos_final = np.max(robot_pos_final, axis=1)
span_final = (robot_max_pos_final[1] - robot_min_pos_final[1])
span_initial = (robot_max_pos_init[1] - robot_min_pos_init[1])
reward = (span_final - span_initial)
return reward
================================================
FILE: evogym/envs/climb.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
from typing import Dict, Any, Optional
class ClimbBase(BenchmarkBase):
def __init__(
self,
world: EvoWorld,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
super().__init__(world=world, render_mode=render_mode, render_options=render_options)
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
class Climb0(ClimbBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Climber-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
ClimbBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(2 + num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
))
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (com_2[1] - com_1[1])
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check termination condition
if com_2[1] > (86)*self.VOXEL_SIZE:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class Climb1(ClimbBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Climber-v1.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
ClimbBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(2 + num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
))
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (com_2[1] - com_1[1])
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check termination condition
if com_2[1] > (65)*self.VOXEL_SIZE:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class Climb2(ClimbBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Climber-v2.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
ClimbBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 3
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_ceil_obs("robot", ["pipe"], self.sight_dist),
))
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (com_2[1] - com_1[1]) + (com_2[0] - com_1[0])*0.2
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_ceil_obs("robot", ["pipe"], self.sight_dist),
))
return obs, {}
================================================
FILE: evogym/envs/flip.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
from typing import Dict, Any, Optional
class Flipping(BenchmarkBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Flipper-v0.json'))
self.world.add_from_array('robot', body, 60, 1, connections=connections)
# init sim
BenchmarkBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(1 + num_robot_points,), dtype=float)
# reward
self.num_flips = 0
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
ort_1 = self.object_orientation_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
ort_2 = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
np.array([ort_2]),
self.get_relative_pos_obs("robot"),
))
# update flips
flattened_ort_1 = self.num_flips * 2 * math.pi + ort_1
if ort_1 < math.pi/3 and ort_2 > 5*math.pi/3:
self.num_flips -= 1
if ort_1 > 5*math.pi/3 and ort_2 < math.pi/3:
self.num_flips += 1
flattened_ort_2 = self.num_flips * 2 * math.pi + ort_2
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (flattened_ort_2 - flattened_ort_1)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check goal met
if com_2[0] < (1)*self.VOXEL_SIZE:
done = True
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
self.num_flips = 0
# observation
obs = np.concatenate((
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
================================================
FILE: evogym/envs/jump.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
from typing import Dict, Any, Optional
class StationaryJump(BenchmarkBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Jumper-v0.json'))
self.world.add_from_array('robot', body, 32, 1, connections=connections)
# init sim
BenchmarkBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 2
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(2 + num_robot_points + (self.sight_dist*2 +1),), dtype=float)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (com_2[1] - com_1[1])*10 - abs(com_2[0] - com_1[0])*5
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
return obs, {}
================================================
FILE: evogym/envs/manipulate.py
================================================
from evogym.envs.base import EvoGymBase
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
from typing import Dict, Any, Optional
class PackageBase(BenchmarkBase):
def __init__(
self,
world: EvoWorld,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
super().__init__(world=world, render_mode=render_mode, render_options=render_options)
self.default_viewer.track_objects('robot', 'package')
def get_obs(self, robot_pos_final, robot_vel_final, package_pos_final, package_vel_final) -> np.ndarray:
robot_com_pos = np.mean(robot_pos_final, axis=1)
robot_com_vel = np.mean(robot_vel_final, axis=1)
box_com_pos = np.mean(package_pos_final, axis=1)
box_com_vel = np.mean(package_vel_final, axis=1)
obs = np.array([
robot_com_vel[0], robot_com_vel[1],
box_com_pos[0]-robot_com_pos[0], box_com_pos[1]-robot_com_pos[1],
box_com_vel[0], box_com_vel[1]
])
return obs
def get_reward(self, package_pos_init, package_pos_final, robot_pos_init, robot_pos_final):
package_com_pos_init = np.mean(package_pos_init, axis=1)
package_com_pos_final = np.mean(package_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
# positive reward for moving forward
reward = (package_com_pos_final[0] - package_com_pos_init[0])*0.75
reward += (robot_com_pos_final[0] - robot_com_pos_init[0])*0.5
# negative reward for robot/block separating
reward += abs(robot_com_pos_init[0] - package_com_pos_init[0]) - abs(robot_com_pos_final[0] - package_com_pos_final[0])
# negative reward for block going below thresh height
if package_com_pos_final[1] < self.thresh_height:
reward += 10 * (package_com_pos_final[1] - package_com_pos_init[1])
return reward
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
obs = self.get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_relative_pos_obs("robot"),
))
return obs, {}
class CarrySmallRect(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Carrier-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(6 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 3.0*self.VOXEL_SIZE
def get_reward_carry(self, package_pos_init, package_pos_final, robot_pos_init, robot_pos_final):
package_com_pos_init = np.mean(package_pos_init, axis=1)
package_com_pos_final = np.mean(package_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
# positive reward for moving forward
reward = (package_com_pos_final[0] - package_com_pos_init[0])*0.5
reward += (robot_com_pos_final[0] - robot_com_pos_init[0])*0.5
# negative reward for block going below thresh height
if package_com_pos_final[1] < self.thresh_height:
reward += 10 * (package_com_pos_final[1] - package_com_pos_init[1])
return reward
def step(self, action):
# collect pre step information
package_pos_init = self.object_pos_at_time(self.get_time(), "package")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
# observation
obs = super().get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward_carry(package_pos_init, package_pos_final, robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check goal met
com_2 = np.mean(robot_pos_final, 1)
if com_2[0] > (99)*self.VOXEL_SIZE:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class CarrySmallRectToTable(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Carrier-v1.json'))
self.world.add_from_array('robot', body, 1, 4, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(6 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 6.0*self.VOXEL_SIZE
def get_reward_carry(self, package_pos_init, package_pos_final, robot_pos_init, robot_pos_final):
package_com_pos_init = np.mean(package_pos_init, axis=1)
package_com_pos_final = np.mean(package_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
# positive reward for moving block/robot to goal
reward = 2*(abs(48.5*self.VOXEL_SIZE - package_com_pos_init[0]) - abs(48.5*self.VOXEL_SIZE - package_com_pos_final[0]))
reward = (abs(40*self.VOXEL_SIZE - robot_com_pos_init[0]) - abs(40*self.VOXEL_SIZE - robot_com_pos_final[0]))
self.thresh_height = 6.0*self.VOXEL_SIZE
if package_com_pos_final[0] > 20 * self.VOXEL_SIZE:
self.thresh_height = 4.0*self.VOXEL_SIZE
# negative reward for block going below thresh height
if package_com_pos_final[1] < self.thresh_height:
reward += 10 * (package_com_pos_final[1] - package_com_pos_init[1])
return reward
def step(self, action):
# collect pre step information
package_pos_init = self.object_pos_at_time(self.get_time(), "package")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
# observation
obs = super().get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward_carry(package_pos_init, package_pos_final, robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class PushSmallRect(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Pusher-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(6 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 0.0*self.VOXEL_SIZE
def step(self, action):
# collect pre step information
package_pos_init = self.object_pos_at_time(self.get_time(), "package")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
# observation
obs = super().get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = super().get_reward(package_pos_init, package_pos_final, robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check goal met
com_2 = np.mean(robot_pos_final, 1)
if com_2[0] > (99)*0.1:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class PushSmallRectOnOppositeSide(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Pusher-v1.json'))
self.world.add_from_array('robot', body, 13, 1, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(6 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 0.0*self.VOXEL_SIZE
def step(self, action):
# collect pre step information
package_pos_init = self.object_pos_at_time(self.get_time(), "package")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
# observation
obs = super().get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = super().get_reward(package_pos_init, package_pos_final, robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check goal met
com_2 = np.mean(robot_pos_final, 1)
if com_2[0] > (69)*self.VOXEL_SIZE:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class ThrowSmallRect(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Thrower-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(6 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 0.0*self.VOXEL_SIZE
def get_reward_throw(self, robot_pos_init, robot_pos_final, package_pos_init, package_pos_final):
package_com_pos_init = np.mean(package_pos_init, axis=1)
package_com_pos_final = np.mean(package_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
motion_penalty = (robot_com_pos_init[0] - robot_com_pos_final[0])*0.25
if robot_com_pos_final[0] < 0:
motion_penalty *= -1
reward = package_com_pos_final[0] - package_com_pos_init[0] + motion_penalty
return reward
def step(self, action):
# collect pre step information
package_pos_init = self.object_pos_at_time(self.get_time(), "package")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
# observation
obs = super().get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward_throw(robot_pos_init, robot_pos_final, package_pos_init, package_pos_final)
#error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class CatchSmallRect(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
self.robot_body = body
self.robot_connections = connections
self.render_mode = render_mode
self.render_options = render_options
self.random_init()
def random_init(self):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Walker-v0.json'))
self.world.add_from_array('robot', self.robot_body, 22, 1, connections=self.robot_connections)
self.offsetx = random.randint(-6, 4)
self.offsety = random.randint(0, 5)
package = WorldObject.from_json(os.path.join(self.DATA_PATH, 'package.json'))
package.set_pos(21+self.offsetx, 41+self.offsety)
package.rename('package')
self.world.add_object(package)
peg1 = WorldObject.from_json(os.path.join(self.DATA_PATH, 'peg.json'))
peg1.set_pos(17+self.offsetx, 39+self.offsety)
peg1.rename('peg1')
self.world.add_object(peg1)
peg2 = WorldObject.from_json(os.path.join(self.DATA_PATH, 'peg.json'))
peg2.set_pos(19+self.offsetx, 25+self.offsety)
peg2.rename('peg2')
self.world.add_object(peg2)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=self.render_mode, render_options=self.render_options)
self.default_viewer.track_objects('robot', 'package')
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(7 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 5.0*self.VOXEL_SIZE
def get_obs_catch(self, robot_pos_final, package_pos_final) -> np.ndarray:
robot_com_pos = np.mean(robot_pos_final, axis=1)
package_com_pos = np.mean(package_pos_final, axis=1)
obs = np.array([
package_com_pos[0]-robot_com_pos[0], package_com_pos[1]-robot_com_pos[1],
])
return obs
def get_reward_catch(self, robot_pos_init, robot_pos_final, package_pos_init, package_pos_final):
package_com_pos_init = np.mean(package_pos_init, axis=1)
package_com_pos_final = np.mean(package_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
# negative reward for robot/block separating in X
reward = abs(robot_com_pos_init[0] - package_com_pos_init[0]) - abs(robot_com_pos_final[0] - package_com_pos_final[0])
# negative reward for block going below thresh height
if package_com_pos_final[1] < self.thresh_height:
reward += 10 * (package_com_pos_final[1] - package_com_pos_init[1])
return reward
def step(self, action):
# collect pre step information
package_pos_init = self.object_pos_at_time(self.get_time(), "package")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
# observation
obs = self.get_obs_catch(robot_pos_final, package_pos_final)
obs = np.concatenate((
obs,
self.get_vel_com_obs("robot"),
self.get_vel_com_obs("package"),
self.get_ort_obs("package"),
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward_catch(robot_pos_init, robot_pos_final, package_pos_init, package_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
EvoGymBase.reset(self, seed=seed, options=options)
self.default_viewer.hide_debug_window()
self.random_init()
# self.translate_object(-self.offsetx*self.VOXEL_SIZE, -self.offsety*self.VOXEL_SIZE, "package")
# self.translate_object(-self.offsetx*self.VOXEL_SIZE, -self.offsety*self.VOXEL_SIZE, "peg1")
# self.translate_object(-self.offsetx*self.VOXEL_SIZE, -self.offsety*self.VOXEL_SIZE, "peg2")
# self.offsetx = random.randint(-6, 4)
# self.offsety = random.randint(0, 5)
# self.translate_object(self.offsetx*self.VOXEL_SIZE, self.offsety*self.VOXEL_SIZE, "package")
# self.translate_object(self.offsetx*self.VOXEL_SIZE, self.offsety*self.VOXEL_SIZE, "peg1")
# self.translate_object(self.offsetx*self.VOXEL_SIZE, self.offsety*self.VOXEL_SIZE, "peg2")
# observation
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
obs = self.get_obs_catch(robot_pos_final, package_pos_final)
obs = np.concatenate((
obs,
self.get_vel_com_obs("robot"),
self.get_vel_com_obs("package"),
self.get_ort_obs("package"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
class ToppleBeam(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'BeamToppler-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(7 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 0.0*self.VOXEL_SIZE
#tracking
self.default_viewer.track_objects('robot', 'beam')
def get_obs_topple(self, robot_pos_final, beam_pos_final):
beam_com_pos_final = np.mean(beam_pos_final, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
diff = beam_com_pos_final - robot_com_pos_final
return np.array([diff[0], diff[1]])
def get_reward_topple(self, robot_pos_init, robot_pos_final, beam_pos_init, beam_pos_final):
beam_com_pos_init = np.mean(beam_pos_init, axis=1)
beam_com_pos_final = np.mean(beam_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
# rewarded for moving to beam
reward = abs(beam_com_pos_init[0] - robot_com_pos_init[0]) - abs(beam_com_pos_final[0] - robot_com_pos_final[0])
# reward for moving beam
reward += abs(beam_com_pos_final[0] - beam_com_pos_init[0])*1.0
reward += abs(beam_com_pos_final[1] - beam_com_pos_init[1])*3.0
# reward for making beam fall
reward += (beam_com_pos_init[1] - beam_com_pos_final[1])*10
task_complete = False
if beam_com_pos_final[0] < 2 * self.VOXEL_SIZE:
task_complete = True
return reward, task_complete
def step(self, action):
# collect pre step information
beam_pos_init = self.object_pos_at_time(self.get_time(), "beam")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
beam_pos_final = self.object_pos_at_time(self.get_time(), "beam")
# observation
obs = self.get_obs_topple(robot_pos_final, beam_pos_final)
obs = np.concatenate((
obs,
self.get_vel_com_obs("robot"),
self.get_vel_com_obs("beam"),
self.get_ort_obs("beam"),
self.get_relative_pos_obs("robot"),
))
# compute reward
reward, task_complete = self.get_reward_topple(robot_pos_init, robot_pos_final, beam_pos_init, beam_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
if task_complete:
reward += 1.0
done = True
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
EvoGymBase.reset(self, seed=seed, options=options)
# observation
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
beam_pos_final = self.object_pos_at_time(self.get_time(), "beam")
obs = self.get_obs_topple(robot_pos_final, beam_pos_final)
obs = np.concatenate((
obs,
self.get_vel_com_obs("robot"),
self.get_vel_com_obs("beam"),
self.get_ort_obs("beam"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
class SlideBeam(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'BeamSlider-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(7 + num_robot_points,), dtype=float)
# threshhold height
self.thresh_height = 0.0*self.VOXEL_SIZE
# tracking
self.default_viewer.track_objects('robot', 'beam')
def get_obs_topple(self, robot_pos_final, beam_pos_final):
beam_com_pos_final = np.mean(beam_pos_final, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
diff = beam_com_pos_final - robot_com_pos_final
return np.array([diff[0], diff[1]])
def get_reward_topple(self, robot_pos_init, robot_pos_final, beam_pos_init, beam_pos_final):
beam_com_pos_init = np.mean(beam_pos_init, axis=1)
beam_com_pos_final = np.mean(beam_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
# rewarded for moving to beam
reward = abs(beam_com_pos_init[0] - robot_com_pos_init[0]) - abs(beam_com_pos_final[0] - robot_com_pos_final[0])
# reward for moving beam (in positive x)
reward += (beam_com_pos_final[0] - beam_com_pos_init[0])*1.0
task_complete = False
if beam_com_pos_final[0] < 2 * self.VOXEL_SIZE:
task_complete = True
return reward, task_complete
def step(self, action):
# collect pre step information
beam_pos_init = self.object_pos_at_time(self.get_time(), "beam")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
beam_pos_final = self.object_pos_at_time(self.get_time(), "beam")
# observation
obs = self.get_obs_topple(robot_pos_final, beam_pos_final)
obs = np.concatenate((
obs,
self.get_vel_com_obs("robot"),
self.get_vel_com_obs("beam"),
self.get_ort_obs("beam"),
self.get_relative_pos_obs("robot"),
))
# compute reward
reward, task_complete = self.get_reward_topple(robot_pos_init, robot_pos_final, beam_pos_init, beam_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
if task_complete:
reward += 1.0
done = True
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
EvoGymBase.reset(self, seed=seed, options=options)
# observation
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
beam_pos_final = self.object_pos_at_time(self.get_time(), "beam")
obs = self.get_obs_topple(robot_pos_final, beam_pos_final)
obs = np.concatenate((
obs,
self.get_vel_com_obs("robot"),
self.get_vel_com_obs("beam"),
self.get_ort_obs("beam"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
class LiftSmallRect(PackageBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Lifter-v0.json'))
self.world.add_from_array('robot', body, 2, 3, connections=connections)
# init sim
PackageBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(7 + num_robot_points,), dtype=float)
def get_reward_lift(self, robot_pos_init, robot_pos_final, package_pos_init, package_pos_final):
package_com_pos_init = np.mean(package_pos_init, axis=1)
package_com_pos_final = np.mean(package_pos_final, axis=1)
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
reward = (package_com_pos_final[1] - package_com_pos_init[1])*10
# penalize x movement
goal = 5.5 * self.VOXEL_SIZE
reward += (abs(goal-package_com_pos_init[0]) - abs(goal-package_com_pos_final[0]))*10
# penalize robot falling below certain y com
thresh = 3
if robot_com_pos_final[1] < thresh*self.VOXEL_SIZE:
reward += 20 * (robot_com_pos_final[1] - robot_com_pos_init[1])
return reward
def step(self, action):
# collect pre step information
package_pos_init = self.object_pos_at_time(self.get_time(), "package")
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
# observation
obs = super().get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_ort_obs("package"),
self.get_relative_pos_obs("robot"),
))
# compute reward
reward = self.get_reward_lift(robot_pos_init, robot_pos_final, package_pos_init, package_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
EvoGymBase.reset(self, seed=seed, options=options)
# observation
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_vel_final = self.object_vel_at_time(self.get_time(), "robot")
package_pos_final = self.object_pos_at_time(self.get_time(), "package")
package_vel_final = self.object_vel_at_time(self.get_time(), "package")
obs = self.get_obs(robot_pos_final, robot_vel_final, package_pos_final, package_vel_final)
obs = np.concatenate((
obs,
self.get_ort_obs("package"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
================================================
FILE: evogym/envs/multi_goal.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
from typing import Dict, Any, Optional
class Goal():
def __init__(self, name, requirements = None):
self.name = name
self.requirements = requirements if requirements is not None else []
def evaluate_reward(self, args):
raise NotImplementedError("Your goal must implement an evaluate function which returns (reward, has_terminated).")
class GoalBase(BenchmarkBase):
def __init__(
self,
world: EvoWorld,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
super().__init__(world=world, render_mode=render_mode, render_options=render_options)
def init_reward_goals(self, goals):
if goals is None or len(goals) == 0:
raise ValueError("Cannot create env with no goals")
self.goals = goals
self.requirements = {}
self.current_goal = 0
for goal in goals:
for req in goal.requirements:
if req not in self.requirements:
self.requirements[req] = []
self.requirements[req].append(goal.name)
def get_reward(self, args):
for req, dependents in self.requirements.items():
if args[req] is None:
raise ValueError(f'Args is missing requirement \'{req}\' for {dependents}')
has_terminated = True
reward = 0
while (has_terminated and self.current_goal != len(self.goals)):
reward, has_terminated = self.goals[self.current_goal].evaluate(args)
if has_terminated:
self.current_goal += 1
done = False
if self.current_goal == len(self.goals):
done = True
return reward, done
def get_obs(self, args):
return self.goals[self.current_goal].get_obs(args)
class WalkToX(Goal):
def __init__(self, x_goal):
super().__init__(f'Walk to x = {x_goal}', requirements = [
'robot_com_pos_initial',
'robot_com_pos_final',
])
self.x_goal = x_goal
def evaluate(self, args):
com_init = np.mean(args['robot_com_pos_initial'], axis=1)
com_final = np.mean(args['robot_com_pos_final'], axis=1)
dist_init = abs(self.x_goal*0.1 - com_init[0])
dist_final = abs(self.x_goal*0.1 - com_final[0])
reward = dist_init - dist_final
has_terminated = True if dist_final < 2*0.1 else False #2 blocks away
#print(self.x_goal, com_final[0])
return reward, has_terminated
def get_obs(self, args):
com_final = np.mean(args['robot_com_pos_final'], axis=1)
return np.array([self.x_goal*0.1, self.x_goal*0.1 - com_final[0]])
class BiWalk(GoalBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'BidirectionalWalker-v0.json'))
self.world.add_from_array('robot', body, 33, 1, connections=connections)
# init sim
GoalBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(5 + num_robot_points,), dtype=float)
self.set_random_goals(20, 50, 100)
# super().init_reward_goals([
# WalkToX(40),
# WalkToX(10),
# WalkToX(40),
# WalkToX(10)
# ])
def set_random_goals(self, lower_bound, upper_bound, goal_dist):
curr_pos = 35
dist = 0
goals = []
while dist < goal_dist:
next_pos = random.randrange(lower_bound, upper_bound)
dist += abs(curr_pos-next_pos)
curr_pos = next_pos
goals.append(WalkToX(next_pos))
#print(f'Goal: {next_pos}')
super().init_reward_goals(goals)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
vel_2 = self.object_vel_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
np.array([self.current_goal]),
))
obs = np.concatenate((obs,
super().get_obs(args = {
'robot_com_pos_initial': pos_1,
'robot_com_pos_final': pos_2
})
))
# compute reward
reward, goals_done = super().get_reward(args = {
'robot_com_pos_initial': pos_1,
'robot_com_pos_final': pos_2
})
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
if goals_done:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
self.current_goal = 0
self.set_random_goals(20, 50, 100)
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
np.array([self.current_goal]),
))
obs = np.concatenate((obs,
super().get_obs(args = {
'robot_com_pos_final': pos_2
})
))
return obs, {}
================================================
FILE: evogym/envs/sim_files/Balancer-v0.json
================================================
{
"grid_width": 30,
"grid_height": 5,
"objects": {
"ground": {
"indices": [
120,
149,
90,
119,
60,
77,
89,
30,
47,
59,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"120": [
90
],
"149": [
119
],
"90": [
120,
60
],
"119": [
149,
89
],
"60": [
90,
30
],
"77": [
47
],
"89": [
119,
59
],
"30": [
60,
0
],
"47": [
17,
77
],
"59": [
89,
29
],
"0": [
1,
30
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18,
47
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
59
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Balancer-v1.json
================================================
{
"grid_width": 30,
"grid_height": 5,
"objects": {
"ground": {
"indices": [
120,
149,
90,
107,
119,
60,
77,
89,
30,
47,
59,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"120": [
90
],
"149": [
119
],
"90": [
120,
60
],
"107": [
77
],
"119": [
149,
89
],
"60": [
90,
30
],
"77": [
47,
107
],
"89": [
119,
59
],
"30": [
60,
0
],
"47": [
17,
77
],
"59": [
89,
29
],
"0": [
1,
30
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18,
47
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
59
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/BeamSlider-v0.json
================================================
{
"grid_width": 70,
"grid_height": 7,
"objects": {
"beam": {
"indices": [
442,
443,
444,
445,
446,
447,
448,
449,
450,
451,
372,
373,
374,
375,
376,
377,
378,
379,
380,
381
],
"types": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"neighbors": {
"442": [
443,
372
],
"443": [
444,
373,
442
],
"444": [
445,
374,
443
],
"445": [
446,
375,
444
],
"446": [
447,
376,
445
],
"447": [
448,
377,
446
],
"448": [
449,
378,
447
],
"449": [
379,
450,
448
],
"450": [
449,
380,
451
],
"451": [
450,
381
],
"372": [
373,
442
],
"373": [
443,
372,
374
],
"374": [
375,
444,
373
],
"375": [
376,
445,
374
],
"376": [
377,
446,
375
],
"377": [
378,
447,
376
],
"378": [
379,
448,
377
],
"379": [
380,
449,
378
],
"380": [
379,
381,
450
],
"381": [
380,
451
]
}
},
"peg1": {
"indices": [
300,
301,
302,
303,
304
],
"types": [
5,
5,
5,
5,
5
],
"neighbors": {
"300": [
301
],
"301": [
302,
300
],
"302": [
303,
301
],
"303": [
304,
302
],
"304": [
303
]
}
},
"peg2": {
"indices": [
309,
310,
311
],
"types": [
5,
5,
5
],
"neighbors": {
"309": [
310
],
"310": [
309,
311
],
"311": [
310
]
}
},
"peg3": {
"indices": [
315,
316,
317
],
"types": [
5,
5,
5
],
"neighbors": {
"315": [
316
],
"316": [
315,
317
],
"317": [
316
]
}
},
"peg4": {
"indices": [
321,
322,
323
],
"types": [
5,
5,
5
],
"neighbors": {
"321": [
322
],
"322": [
321,
323
],
"323": [
322
]
}
},
"peg5": {
"indices": [
329,
330,
331
],
"types": [
5,
5,
5
],
"neighbors": {
"329": [
330
],
"330": [
329,
331
],
"331": [
330
]
}
},
"ground": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
6,
4
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
15,
13
],
"15": [
16,
14
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
29,
27
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
46,
48
],
"48": [
47,
49
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
50,
52
],
"52": [
51,
53
],
"53": [
52,
54
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/BeamToppler-v0.json
================================================
{
"grid_width": 70,
"grid_height": 7,
"objects": {
"beam": {
"indices": [
449,
450,
451,
452,
453,
454,
455,
456,
457,
458,
379,
380,
381,
382,
383,
384,
385,
386,
387,
388
],
"types": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"neighbors": {
"449": [
379,
450
],
"450": [
449,
380,
451
],
"451": [
450,
381,
452
],
"452": [
451,
382,
453
],
"453": [
452,
383,
454
],
"454": [
453,
384,
455
],
"455": [
454,
385,
456
],
"456": [
455,
386,
457
],
"457": [
456,
387,
458
],
"458": [
457,
388
],
"379": [
380,
449
],
"380": [
379,
381,
450
],
"381": [
380,
382,
451
],
"382": [
381,
383,
452
],
"383": [
382,
384,
453
],
"384": [
383,
385,
454
],
"385": [
384,
386,
455
],
"386": [
385,
387,
456
],
"387": [
386,
388,
457
],
"388": [
387,
458
]
}
},
"peg1": {
"indices": [
307,
308,
309,
310,
311
],
"types": [
5,
5,
5,
5,
5
],
"neighbors": {
"307": [
308
],
"308": [
307,
309
],
"309": [
308,
310
],
"310": [
309,
311
],
"311": [
310
]
}
},
"peg2": {
"indices": [
316,
317,
318,
319,
320
],
"types": [
5,
5,
5,
5,
5
],
"neighbors": {
"316": [
317
],
"317": [
316,
318
],
"318": [
317,
319
],
"319": [
318,
320
],
"320": [
319
]
}
},
"ground": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
6,
4
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
15,
13
],
"15": [
16,
14
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
29,
27
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
46,
48
],
"48": [
47,
49
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
50,
52
],
"52": [
51,
53
],
"53": [
52,
54
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/BidirectionalWalker-v0.json
================================================
{
"grid_width": 70,
"grid_height": 1,
"objects": {
"new_object_1": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
4,
2
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
23,
21
],
"23": [
24,
22
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
39,
37
],
"39": [
40,
38
],
"40": [
41,
39
],
"41": [
42,
40
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
46,
48
],
"48": [
49,
47
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
50,
52
],
"52": [
51,
53
],
"53": [
52,
54
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/BridgeWalker-v0.json
================================================
{
"grid_width": 60,
"grid_height": 5,
"objects": {
"new_object_2": {
"indices": [
240,
241,
242,
243,
244,
245,
246,
247,
248,
249,
250,
251,
252,
253,
254,
255,
256,
257,
258,
259,
260,
261,
262,
263,
264,
265,
266,
267,
268,
269,
270,
271,
272,
273,
274,
275,
276,
277,
278,
279,
280,
281,
282,
283,
284,
285,
286,
287,
288,
289,
290,
291,
292,
293,
294,
295,
296,
297,
298,
299,
180,
181,
182,
183,
184,
185,
186,
187,
188,
189,
190,
191,
192,
193,
194,
195,
196,
197,
198,
199,
200,
201,
202,
203,
204,
205,
206,
207,
208,
209,
210,
211,
212,
213,
214,
215,
216,
217,
218,
219,
220,
221,
222,
223,
224,
225,
226,
227,
228,
229,
230,
231,
232,
233,
234,
235,
236,
237,
238,
239,
120,
125,
130,
138,
149,
166,
178,
179,
60,
65,
70,
78,
89,
106,
118,
119,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59
],
"types": [
5,
2,
2,
2,
2,
5,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
5,
5,
2,
2,
2,
2,
5,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"240": [
180,
241
],
"241": [
240,
242,
181
],
"242": [
243,
241,
182
],
"243": [
242,
244,
183
],
"244": [
243,
245,
184
],
"245": [
185,
246,
244
],
"246": [
245,
247,
186
],
"247": [
248,
187,
246
],
"248": [
247,
249,
188
],
"249": [
248,
250,
189
],
"250": [
190,
251,
249
],
"251": [
250,
252,
191
],
"252": [
251,
253,
192
],
"253": [
252,
254,
193
],
"254": [
253,
255,
194
],
"255": [
254,
256,
195
],
"256": [
255,
257,
196
],
"257": [
256,
258,
197
],
"258": [
198,
259,
257
],
"259": [
258,
260,
199
],
"260": [
259,
261,
200
],
"261": [
260,
262,
201
],
"262": [
261,
263,
202
],
"263": [
262,
264,
203
],
"264": [
263,
265,
204
],
"265": [
264,
266,
205
],
"266": [
265,
267,
206
],
"267": [
266,
268,
207
],
"268": [
267,
269,
208
],
"269": [
209,
270,
268
],
"270": [
269,
271,
210
],
"271": [
270,
272,
211
],
"272": [
271,
273,
212
],
"273": [
272,
274,
213
],
"274": [
273,
275,
214
],
"275": [
274,
276,
215
],
"276": [
275,
277,
216
],
"277": [
276,
278,
217
],
"278": [
277,
279,
218
],
"279": [
278,
280,
219
],
"280": [
279,
281,
220
],
"281": [
280,
282,
221
],
"282": [
281,
283,
222
],
"283": [
282,
284,
223
],
"284": [
283,
285,
224
],
"285": [
284,
286,
225
],
"286": [
226,
287,
285
],
"287": [
286,
288,
227
],
"288": [
287,
289,
228
],
"289": [
288,
290,
229
],
"290": [
289,
291,
230
],
"291": [
290,
292,
231
],
"292": [
293,
291,
232
],
"293": [
294,
292,
233
],
"294": [
295,
293,
234
],
"295": [
294,
296,
235
],
"296": [
295,
297,
236
],
"297": [
296,
298,
237
],
"298": [
238,
299,
297
],
"299": [
298,
239
],
"180": [
240,
120,
181
],
"181": [
180,
182,
241
],
"182": [
183,
242,
181
],
"183": [
184,
243,
182
],
"184": [
185,
244,
183
],
"185": [
245,
125,
186,
184
],
"186": [
185,
187,
246
],
"187": [
188,
247,
186
],
"188": [
189,
248,
187
],
"189": [
190,
249,
188
],
"190": [
250,
130,
191,
189
],
"191": [
190,
192,
251
],
"192": [
193,
252,
191
],
"193": [
194,
253,
192
],
"194": [
195,
254,
193
],
"195": [
196,
255,
194
],
"196": [
197,
256,
195
],
"197": [
198,
257,
196
],
"198": [
258,
138,
199,
197
],
"199": [
198,
200,
259
],
"200": [
201,
260,
199
],
"201": [
202,
261,
200
],
"202": [
203,
262,
201
],
"203": [
204,
263,
202
],
"204": [
205,
264,
203
],
"205": [
206,
265,
204
],
"206": [
266,
205,
207
],
"207": [
206,
208,
267
],
"208": [
209,
268,
207
],
"209": [
269,
149,
210,
208
],
"210": [
209,
211,
270
],
"211": [
212,
271,
210
],
"212": [
213,
272,
211
],
"213": [
214,
273,
212
],
"214": [
215,
274,
213
],
"215": [
216,
275,
214
],
"216": [
276,
215,
217
],
"217": [
216,
218,
277
],
"218": [
219,
278,
217
],
"219": [
220,
279,
218
],
"220": [
221,
280,
219
],
"221": [
222,
281,
220
],
"222": [
223,
282,
221
],
"223": [
224,
283,
222
],
"224": [
225,
284,
223
],
"225": [
226,
285,
224
],
"226": [
286,
166,
227,
225
],
"227": [
226,
228,
287
],
"228": [
229,
288,
227
],
"229": [
289,
228,
230
],
"230": [
229,
290,
231
],
"231": [
230,
291,
232
],
"232": [
231,
292,
233
],
"233": [
232,
293,
234
],
"234": [
233,
294,
235
],
"235": [
234,
295,
236
],
"236": [
235,
296,
237
],
"237": [
236,
238,
297
],
"238": [
298,
178,
239,
237
],
"239": [
238,
179,
299
],
"120": [
180,
60
],
"125": [
185,
65
],
"130": [
190,
70
],
"138": [
198,
78
],
"149": [
209,
89
],
"166": [
226,
106
],
"178": [
238,
118,
179
],
"179": [
178,
119,
239
],
"60": [
120,
0
],
"65": [
125,
5
],
"70": [
130,
10
],
"78": [
138,
18
],
"89": [
149,
29
],
"106": [
166,
46
],
"118": [
178,
58,
119
],
"119": [
118,
59,
179
],
"0": [
1,
60
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6,
65
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11,
70
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19,
78
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30,
89
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47,
106
],
"47": [
48,
46
],
"48": [
49,
47
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
52,
50
],
"52": [
53,
51
],
"53": [
54,
52
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59,
118
],
"59": [
58,
119
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Carrier-v0.json
================================================
{
"grid_width": 100,
"grid_height": 8,
"objects": {
"package": {
"indices": [
703,
704,
705,
603,
604,
605
],
"types": [
2,
2,
2,
2,
2,
2
],
"neighbors": {
"703": [
704,
603
],
"704": [
705,
604,
703
],
"705": [
605,
704
],
"603": [
604,
703
],
"604": [
603,
605,
704
],
"605": [
604,
705
]
}
},
"ground": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
48,
46
],
"48": [
49,
47
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
52,
50
],
"52": [
53,
51
],
"53": [
54,
52
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
70
],
"70": [
69,
71
],
"71": [
70,
72
],
"72": [
71,
73
],
"73": [
72,
74
],
"74": [
73,
75
],
"75": [
74,
76
],
"76": [
75,
77
],
"77": [
76,
78
],
"78": [
77,
79
],
"79": [
78,
80
],
"80": [
79,
81
],
"81": [
80,
82
],
"82": [
81,
83
],
"83": [
82,
84
],
"84": [
83,
85
],
"85": [
84,
86
],
"86": [
85,
87
],
"87": [
86,
88
],
"88": [
87,
89
],
"89": [
90,
88
],
"90": [
91,
89
],
"91": [
92,
90
],
"92": [
93,
91
],
"93": [
94,
92
],
"94": [
95,
93
],
"95": [
96,
94
],
"96": [
97,
95
],
"97": [
98,
96
],
"98": [
99,
97
],
"99": [
98
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Carrier-v1.json
================================================
{
"grid_width": 60,
"grid_height": 12,
"objects": {
"package": {
"indices": [
663,
664,
665,
603,
604,
605
],
"types": [
1,
1,
1,
1,
1,
1
],
"neighbors": {
"663": [
603,
664
],
"664": [
663,
665,
604
],
"665": [
664,
605
],
"603": [
663,
604
],
"604": [
603,
664,
605
],
"605": [
604,
665
]
}
},
"ground": {
"indices": [
288,
289,
180,
181,
182,
183,
184,
185,
186,
187,
188,
189,
190,
191,
192,
193,
194,
195,
196,
197,
198,
199,
200,
201,
202,
203,
228,
229,
143,
144,
145,
146,
168,
169,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116,
117,
118,
119
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"288": [
289,
228
],
"289": [
229,
288
],
"180": [
181
],
"181": [
180,
182
],
"182": [
181,
183
],
"183": [
182,
184
],
"184": [
183,
185
],
"185": [
184,
186
],
"186": [
185,
187
],
"187": [
186,
188
],
"188": [
187,
189
],
"189": [
188,
190
],
"190": [
189,
191
],
"191": [
190,
192
],
"192": [
191,
193
],
"193": [
192,
194
],
"194": [
193,
195
],
"195": [
194,
196
],
"196": [
195,
197
],
"197": [
196,
198
],
"198": [
197,
199
],
"199": [
198,
200
],
"200": [
199,
201
],
"201": [
200,
202
],
"202": [
201,
203
],
"203": [
202,
143
],
"228": [
168,
229,
288
],
"229": [
228,
169,
289
],
"143": [
203,
144
],
"144": [
143,
145
],
"145": [
144,
146
],
"146": [
145,
86
],
"168": [
169,
108,
228
],
"169": [
109,
168,
229
],
"86": [
146,
87
],
"87": [
86,
88
],
"88": [
87,
89
],
"89": [
88,
90
],
"90": [
89,
91
],
"91": [
90,
92
],
"92": [
91,
93
],
"93": [
92,
94
],
"94": [
93,
95
],
"95": [
94,
96
],
"96": [
95,
97
],
"97": [
96,
98
],
"98": [
97,
99
],
"99": [
98,
100
],
"100": [
99,
101
],
"101": [
100,
102
],
"102": [
101,
103
],
"103": [
102,
104
],
"104": [
103,
105
],
"105": [
104,
106
],
"106": [
105,
107
],
"107": [
106,
108
],
"108": [
107,
109,
168
],
"109": [
108,
110,
169
],
"110": [
109,
111
],
"111": [
110,
112
],
"112": [
111,
113
],
"113": [
112,
114
],
"114": [
113,
115
],
"115": [
114,
116
],
"116": [
115,
117
],
"117": [
116,
118
],
"118": [
117,
119
],
"119": [
118
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/CaveCrawler-v0.json
================================================
{
"grid_width": 70,
"grid_height": 14,
"objects": {
"terrain": {
"indices": [
930,
860,
790,
720,
650,
699,
580,
629,
510,
511,
524,
525,
526,
527,
528,
529,
530,
531,
532,
533,
534,
535,
536,
537,
538,
539,
540,
541,
542,
543,
544,
545,
546,
547,
548,
549,
550,
551,
552,
553,
554,
555,
556,
557,
558,
559,
441,
442,
443,
444,
445,
446,
447,
448,
449,
450,
451,
452,
453,
454,
459,
460,
461,
462,
463,
464,
465,
466,
467,
468,
469,
470,
471,
472,
473,
478,
479,
480,
489,
373,
374,
375,
376,
377,
378,
379,
380,
381,
382,
392,
393,
394,
395,
396,
397,
398,
399,
400,
401,
409,
410,
419,
305,
306,
307,
308,
309,
310,
339,
349,
279,
209,
116,
117,
118,
119,
120,
139,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
5,
5,
5,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
5,
5,
5,
2,
2,
2,
2,
2,
2,
5,
5,
5,
5,
2,
2,
2,
2,
2,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"930": [
860
],
"860": [
930,
790
],
"790": [
860,
720
],
"720": [
790,
650
],
"650": [
720,
580
],
"699": [
629
],
"580": [
510,
650
],
"629": [
559,
699
],
"510": [
580,
511
],
"511": [
510,
441
],
"524": [
454,
525
],
"525": [
524,
526
],
"526": [
525,
527
],
"527": [
526,
528
],
"528": [
527,
529
],
"529": [
528,
530,
459
],
"530": [
529,
531,
460
],
"531": [
530,
532,
461
],
"532": [
531,
533,
462
],
"533": [
532,
534,
463
],
"534": [
533,
535,
464
],
"535": [
534,
536,
465
],
"536": [
535,
537,
466
],
"537": [
536,
538,
467
],
"538": [
537,
539,
468
],
"539": [
538,
540,
469
],
"540": [
539,
541,
470
],
"541": [
540,
542,
471
],
"542": [
541,
543,
472
],
"543": [
542,
544,
473
],
"544": [
543,
545
],
"545": [
544,
546
],
"546": [
545,
547
],
"547": [
546,
548
],
"548": [
547,
549,
478
],
"549": [
548,
550,
479
],
"550": [
549,
551,
480
],
"551": [
550,
552
],
"552": [
551,
553
],
"553": [
552,
554
],
"554": [
553,
555
],
"555": [
554,
556
],
"556": [
555,
557
],
"557": [
556,
558
],
"558": [
557,
559
],
"559": [
558,
629,
489
],
"441": [
511,
442
],
"442": [
441,
443
],
"443": [
442,
444,
373
],
"444": [
443,
445,
374
],
"445": [
444,
446,
375
],
"446": [
445,
447,
376
],
"447": [
446,
448,
377
],
"448": [
447,
449,
378
],
"449": [
448,
450,
379
],
"450": [
449,
451,
380
],
"451": [
450,
452,
381
],
"452": [
451,
453,
382
],
"453": [
452,
454
],
"454": [
453,
524
],
"459": [
529,
460
],
"460": [
459,
530,
461
],
"461": [
460,
531,
462
],
"462": [
461,
532,
463,
392
],
"463": [
462,
533,
464,
393
],
"464": [
463,
534,
465,
394
],
"465": [
464,
535,
466,
395
],
"466": [
465,
536,
467,
396
],
"467": [
466,
537,
468,
397
],
"468": [
467,
538,
469,
398
],
"469": [
468,
539,
470,
399
],
"470": [
469,
540,
471,
400
],
"471": [
470,
541,
472,
401
],
"472": [
471,
473,
542
],
"473": [
543,
472
],
"478": [
479,
548
],
"479": [
480,
549,
478,
409
],
"480": [
550,
479,
410
],
"489": [
559,
419
],
"373": [
443,
374
],
"374": [
373,
444,
375
],
"375": [
374,
445,
376,
305
],
"376": [
375,
446,
377,
306
],
"377": [
376,
447,
378,
307
],
"378": [
377,
448,
379,
308
],
"379": [
378,
449,
380,
309
],
"380": [
379,
450,
381,
310
],
"381": [
380,
451,
382
],
"382": [
381,
452
],
"392": [
462,
393
],
"393": [
392,
463,
394
],
"394": [
393,
464,
395
],
"395": [
394,
465,
396
],
"396": [
395,
466,
397
],
"397": [
396,
467,
398
],
"398": [
397,
468,
399
],
"399": [
398,
469,
400
],
"400": [
399,
470,
401
],
"401": [
400,
471
],
"409": [
479,
410,
339
],
"410": [
409,
480
],
"419": [
489,
349
],
"305": [
375,
306
],
"306": [
305,
376,
307
],
"307": [
306,
377,
308
],
"308": [
307,
378,
309
],
"309": [
308,
379,
310
],
"310": [
309,
380
],
"339": [
409
],
"349": [
419,
279
],
"279": [
349,
209
],
"209": [
279,
139
],
"116": [
117,
46
],
"117": [
118,
47,
116
],
"118": [
119,
48,
117
],
"119": [
120,
49,
118
],
"120": [
50,
119
],
"139": [
209,
69
],
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47,
116
],
"47": [
48,
46,
117
],
"48": [
49,
47,
118
],
"49": [
48,
50,
119
],
"50": [
49,
51,
120
],
"51": [
52,
50
],
"52": [
53,
51
],
"53": [
54,
52
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
139
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Climber-v0.json
================================================
{
"grid_width": 7,
"grid_height": 90,
"objects": {
"pipe": {
"indices": [
623,
624,
625,
626,
627,
628,
629,
616,
622,
609,
615,
602,
608,
595,
601,
588,
594,
581,
587,
574,
580,
567,
573,
560,
566,
553,
559,
546,
552,
539,
545,
532,
538,
525,
531,
518,
524,
511,
517,
504,
510,
497,
503,
490,
496,
483,
489,
476,
482,
469,
475,
462,
468,
455,
461,
448,
454,
441,
447,
434,
440,
427,
433,
420,
426,
413,
419,
406,
412,
399,
405,
392,
398,
385,
391,
378,
384,
371,
377,
364,
370,
357,
363,
350,
356,
343,
349,
336,
342,
329,
335,
322,
328,
315,
321,
308,
314,
301,
307,
294,
300,
287,
293,
280,
286,
273,
279,
266,
272,
259,
265,
252,
258,
245,
251,
238,
244,
231,
237,
224,
230,
217,
223,
210,
216,
203,
209,
196,
202,
189,
195,
182,
188,
175,
181,
168,
174,
161,
167,
154,
160,
147,
153,
140,
146,
133,
139,
126,
132,
119,
125,
112,
118,
105,
111,
98,
104,
91,
97,
84,
90,
77,
83,
70,
76,
63,
69,
56,
62,
49,
55,
42,
48,
35,
41,
28,
34,
21,
27,
14,
20,
7,
13,
0,
1,
2,
3,
4,
5,
6
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"623": [
616,
624
],
"624": [
623,
625
],
"625": [
624,
626
],
"626": [
625,
627
],
"627": [
626,
628
],
"628": [
627,
629
],
"629": [
628,
622
],
"616": [
609,
623
],
"622": [
629,
615
],
"609": [
602,
616
],
"615": [
622,
608
],
"602": [
595,
609
],
"608": [
601,
615
],
"595": [
588,
602
],
"601": [
608,
594
],
"588": [
581,
595
],
"594": [
601,
587
],
"581": [
574,
588
],
"587": [
594,
580
],
"574": [
567,
581
],
"580": [
587,
573
],
"567": [
560,
574
],
"573": [
580,
566
],
"560": [
553,
567
],
"566": [
573,
559
],
"553": [
546,
560
],
"559": [
566,
552
],
"546": [
539,
553
],
"552": [
559,
545
],
"539": [
532,
546
],
"545": [
552,
538
],
"532": [
525,
539
],
"538": [
545,
531
],
"525": [
518,
532
],
"531": [
538,
524
],
"518": [
511,
525
],
"524": [
531,
517
],
"511": [
504,
518
],
"517": [
524,
510
],
"504": [
497,
511
],
"510": [
517,
503
],
"497": [
490,
504
],
"503": [
510,
496
],
"490": [
483,
497
],
"496": [
503,
489
],
"483": [
476,
490
],
"489": [
496,
482
],
"476": [
469,
483
],
"482": [
489,
475
],
"469": [
462,
476
],
"475": [
482,
468
],
"462": [
455,
469
],
"468": [
475,
461
],
"455": [
448,
462
],
"461": [
468,
454
],
"448": [
441,
455
],
"454": [
461,
447
],
"441": [
434,
448
],
"447": [
454,
440
],
"434": [
427,
441
],
"440": [
447,
433
],
"427": [
420,
434
],
"433": [
440,
426
],
"420": [
413,
427
],
"426": [
433,
419
],
"413": [
406,
420
],
"419": [
426,
412
],
"406": [
399,
413
],
"412": [
419,
405
],
"399": [
392,
406
],
"405": [
412,
398
],
"392": [
385,
399
],
"398": [
405,
391
],
"385": [
378,
392
],
"391": [
398,
384
],
"378": [
371,
385
],
"384": [
391,
377
],
"371": [
364,
378
],
"377": [
384,
370
],
"364": [
357,
371
],
"370": [
377,
363
],
"357": [
350,
364
],
"363": [
370,
356
],
"350": [
343,
357
],
"356": [
363,
349
],
"343": [
336,
350
],
"349": [
356,
342
],
"336": [
329,
343
],
"342": [
349,
335
],
"329": [
322,
336
],
"335": [
342,
328
],
"322": [
315,
329
],
"328": [
335,
321
],
"315": [
308,
322
],
"321": [
328,
314
],
"308": [
301,
315
],
"314": [
321,
307
],
"301": [
294,
308
],
"307": [
314,
300
],
"294": [
287,
301
],
"300": [
307,
293
],
"287": [
280,
294
],
"293": [
300,
286
],
"280": [
273,
287
],
"286": [
293,
279
],
"273": [
266,
280
],
"279": [
286,
272
],
"266": [
259,
273
],
"272": [
279,
265
],
"259": [
252,
266
],
"265": [
272,
258
],
"252": [
245,
259
],
"258": [
265,
251
],
"245": [
238,
252
],
"251": [
258,
244
],
"238": [
231,
245
],
"244": [
251,
237
],
"231": [
224,
238
],
"237": [
244,
230
],
"224": [
217,
231
],
"230": [
237,
223
],
"217": [
210,
224
],
"223": [
230,
216
],
"210": [
203,
217
],
"216": [
223,
209
],
"203": [
210,
196
],
"209": [
216,
202
],
"196": [
203,
189
],
"202": [
209,
195
],
"189": [
196,
182
],
"195": [
202,
188
],
"182": [
189,
175
],
"188": [
195,
181
],
"175": [
168,
182
],
"181": [
188,
174
],
"168": [
161,
175
],
"174": [
181,
167
],
"161": [
154,
168
],
"167": [
174,
160
],
"154": [
147,
161
],
"160": [
167,
153
],
"147": [
140,
154
],
"153": [
160,
146
],
"140": [
133,
147
],
"146": [
153,
139
],
"133": [
126,
140
],
"139": [
146,
132
],
"126": [
119,
133
],
"132": [
139,
125
],
"119": [
112,
126
],
"125": [
132,
118
],
"112": [
105,
119
],
"118": [
125,
111
],
"105": [
98,
112
],
"111": [
118,
104
],
"98": [
91,
105
],
"104": [
111,
97
],
"91": [
84,
98
],
"97": [
104,
90
],
"84": [
77,
91
],
"90": [
97,
83
],
"77": [
70,
84
],
"83": [
90,
76
],
"70": [
63,
77
],
"76": [
83,
69
],
"63": [
56,
70
],
"69": [
76,
62
],
"56": [
49,
63
],
"62": [
69,
55
],
"49": [
42,
56
],
"55": [
48,
62
],
"42": [
49,
35
],
"48": [
41,
55
],
"35": [
28,
42
],
"41": [
34,
48
],
"28": [
21,
35
],
"34": [
41,
27
],
"21": [
28,
14
],
"27": [
34,
20
],
"14": [
21,
7
],
"20": [
13,
27
],
"7": [
14,
0
],
"13": [
20,
6
],
"0": [
1,
7
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
13
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Climber-v1.json
================================================
{
"grid_width": 7,
"grid_height": 70,
"objects": {
"pipe": {
"indices": [
483,
484,
485,
486,
487,
488,
489,
476,
482,
469,
475,
462,
468,
455,
461,
448,
454,
441,
447,
434,
440,
427,
433,
420,
426,
413,
419,
406,
412,
399,
405,
392,
398,
385,
391,
378,
384,
371,
377,
364,
370,
357,
363,
350,
356,
343,
349,
336,
342,
329,
335,
322,
328,
315,
321,
308,
314,
301,
307,
294,
300,
287,
293,
280,
286,
273,
279,
266,
272,
259,
265,
252,
258,
245,
251,
238,
244,
231,
237,
224,
230,
217,
223,
210,
216,
203,
209,
196,
202,
189,
195,
182,
188,
175,
181,
168,
174,
161,
167,
154,
160,
147,
153,
140,
146,
133,
139,
126,
132,
119,
125,
112,
118,
105,
111,
98,
104,
91,
97,
84,
90,
77,
83,
70,
76,
63,
69,
56,
62,
49,
55,
42,
48,
35,
41,
28,
34,
21,
27,
14,
20,
7,
13,
0,
1,
2,
3,
4,
5,
6
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
2,
5,
2,
5,
2,
5,
2,
5,
2,
5,
5,
2,
5,
2,
5,
2,
5,
2,
5,
5,
5,
5,
2,
2,
2,
2,
2,
2,
5,
5,
5,
5,
5,
5,
5,
5,
2,
2,
2,
2,
5,
5,
5,
5,
5,
5,
2,
5,
2,
5,
2,
5,
5,
5,
5,
2,
5,
2,
2,
2,
5,
5,
5,
5,
2,
5,
2,
5,
5,
5,
5,
2,
2,
2,
2,
5,
5,
5,
5,
5,
5,
2,
5,
2,
2,
5,
2,
5,
5,
5,
5,
5,
5,
5,
5,
2,
5,
2,
5,
2,
5,
5,
5,
5,
2,
5,
2,
5,
5,
5,
5,
5,
5,
2,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"483": [
476,
484
],
"484": [
483,
485
],
"485": [
484,
486
],
"486": [
485,
487
],
"487": [
486,
488
],
"488": [
487,
489
],
"489": [
482,
488
],
"476": [
469,
483
],
"482": [
489,
475
],
"469": [
462,
476
],
"475": [
482,
468
],
"462": [
455,
469
],
"468": [
475,
461
],
"455": [
448,
462
],
"461": [
468,
454
],
"448": [
441,
455
],
"454": [
461,
447
],
"441": [
434,
448
],
"447": [
454,
440
],
"434": [
427,
441
],
"440": [
447,
433
],
"427": [
420,
434
],
"433": [
440,
426
],
"420": [
413,
427
],
"426": [
433,
419
],
"413": [
406,
420
],
"419": [
426,
412
],
"406": [
399,
413
],
"412": [
419,
405
],
"399": [
392,
406
],
"405": [
412,
398
],
"392": [
385,
399
],
"398": [
405,
391
],
"385": [
378,
392
],
"391": [
398,
384
],
"378": [
371,
385
],
"384": [
391,
377
],
"371": [
364,
378
],
"377": [
384,
370
],
"364": [
357,
371
],
"370": [
377,
363
],
"357": [
350,
364
],
"363": [
370,
356
],
"350": [
343,
357
],
"356": [
363,
349
],
"343": [
336,
350
],
"349": [
356,
342
],
"336": [
329,
343
],
"342": [
349,
335
],
"329": [
322,
336
],
"335": [
342,
328
],
"322": [
315,
329
],
"328": [
335,
321
],
"315": [
308,
322
],
"321": [
328,
314
],
"308": [
301,
315
],
"314": [
321,
307
],
"301": [
294,
308
],
"307": [
314,
300
],
"294": [
287,
301
],
"300": [
307,
293
],
"287": [
280,
294
],
"293": [
300,
286
],
"280": [
273,
287
],
"286": [
293,
279
],
"273": [
266,
280
],
"279": [
286,
272
],
"266": [
259,
273
],
"272": [
279,
265
],
"259": [
266,
252
],
"265": [
272,
258
],
"252": [
259,
245
],
"258": [
265,
251
],
"245": [
238,
252
],
"251": [
258,
244
],
"238": [
231,
245
],
"244": [
251,
237
],
"231": [
224,
238
],
"237": [
244,
230
],
"224": [
217,
231
],
"230": [
237,
223
],
"217": [
210,
224
],
"223": [
230,
216
],
"210": [
203,
217
],
"216": [
223,
209
],
"203": [
210,
196
],
"209": [
216,
202
],
"196": [
203,
189
],
"202": [
209,
195
],
"189": [
196,
182
],
"195": [
202,
188
],
"182": [
189,
175
],
"188": [
195,
181
],
"175": [
168,
182
],
"181": [
188,
174
],
"168": [
161,
175
],
"174": [
181,
167
],
"161": [
154,
168
],
"167": [
174,
160
],
"154": [
147,
161
],
"160": [
167,
153
],
"147": [
140,
154
],
"153": [
160,
146
],
"140": [
133,
147
],
"146": [
153,
139
],
"133": [
126,
140
],
"139": [
146,
132
],
"126": [
119,
133
],
"132": [
139,
125
],
"119": [
112,
126
],
"125": [
132,
118
],
"112": [
105,
119
],
"118": [
125,
111
],
"105": [
98,
112
],
"111": [
118,
104
],
"98": [
91,
105
],
"104": [
111,
97
],
"91": [
84,
98
],
"97": [
104,
90
],
"84": [
77,
91
],
"90": [
97,
83
],
"77": [
70,
84
],
"83": [
90,
76
],
"70": [
63,
77
],
"76": [
83,
69
],
"63": [
56,
70
],
"69": [
76,
62
],
"56": [
49,
63
],
"62": [
69,
55
],
"49": [
42,
56
],
"55": [
48,
62
],
"42": [
49,
35
],
"48": [
41,
55
],
"35": [
28,
42
],
"41": [
34,
48
],
"28": [
21,
35
],
"34": [
41,
27
],
"21": [
28,
14
],
"27": [
34,
20
],
"14": [
21,
7
],
"20": [
13,
27
],
"7": [
14,
0
],
"13": [
20,
6
],
"0": [
1,
7
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
13
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Climber-v2.json
================================================
{
"grid_width": 27,
"grid_height": 42,
"objects": {
"pipe": {
"indices": [
1114,
1115,
1116,
1117,
1118,
1119,
1120,
1121,
1122,
1123,
1124,
1125,
1126,
1127,
1128,
1129,
1130,
1131,
1132,
1133,
1086,
1087,
1106,
1058,
1059,
1079,
1030,
1031,
1052,
1002,
1003,
1025,
975,
998,
948,
956,
957,
958,
959,
960,
961,
962,
963,
964,
965,
966,
967,
968,
969,
970,
971,
920,
921,
928,
929,
893,
900,
901,
866,
872,
873,
839,
845,
811,
812,
818,
784,
791,
757,
764,
730,
736,
737,
703,
709,
676,
682,
649,
655,
621,
622,
628,
594,
601,
567,
574,
540,
547,
513,
519,
520,
486,
492,
459,
465,
432,
438,
405,
411,
378,
384,
351,
357,
324,
330,
297,
303,
270,
276,
243,
249,
216,
222,
189,
195,
162,
168,
135,
141,
108,
114,
81,
87,
54,
60,
27,
33,
0,
1,
2,
3,
4,
5,
6
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"1114": [
1087,
1115
],
"1115": [
1114,
1116
],
"1116": [
1115,
1117
],
"1117": [
1116,
1118
],
"1118": [
1117,
1119
],
"1119": [
1118,
1120
],
"1120": [
1119,
1121
],
"1121": [
1120,
1122
],
"1122": [
1121,
1123
],
"1123": [
1122,
1124
],
"1124": [
1123,
1125
],
"1125": [
1124,
1126
],
"1126": [
1125,
1127
],
"1127": [
1126,
1128
],
"1128": [
1127,
1129
],
"1129": [
1128,
1130
],
"1130": [
1129,
1131
],
"1131": [
1130,
1132
],
"1132": [
1131,
1133
],
"1133": [
1132,
1106
],
"1086": [
1059,
1087
],
"1087": [
1086,
1114
],
"1106": [
1133,
1079
],
"1058": [
1031,
1059
],
"1059": [
1058,
1086
],
"1079": [
1106,
1052
],
"1030": [
1003,
1031
],
"1031": [
1030,
1058
],
"1052": [
1079,
1025
],
"1002": [
975,
1003
],
"1003": [
1002,
1030
],
"1025": [
1052,
998
],
"975": [
948,
1002
],
"998": [
1025,
971
],
"948": [
921,
975
],
"956": [
929,
957
],
"957": [
956,
958
],
"958": [
957,
959
],
"959": [
958,
960
],
"960": [
959,
961
],
"961": [
960,
962
],
"962": [
961,
963
],
"963": [
962,
964
],
"964": [
963,
965
],
"965": [
964,
966
],
"966": [
965,
967
],
"967": [
966,
968
],
"968": [
967,
969
],
"969": [
968,
970
],
"970": [
969,
971
],
"971": [
998,
970
],
"920": [
893,
921
],
"921": [
920,
948
],
"928": [
901,
929
],
"929": [
928,
956
],
"893": [
866,
920
],
"900": [
873,
901
],
"901": [
900,
928
],
"866": [
839,
893
],
"872": [
845,
873
],
"873": [
872,
900
],
"839": [
812,
866
],
"845": [
818,
872
],
"811": [
784,
812
],
"812": [
811,
839
],
"818": [
791,
845
],
"784": [
757,
811
],
"791": [
764,
818
],
"757": [
730,
784
],
"764": [
737,
791
],
"730": [
703,
757
],
"736": [
709,
737
],
"737": [
736,
764
],
"703": [
676,
730
],
"709": [
682,
736
],
"676": [
649,
703
],
"682": [
655,
709
],
"649": [
622,
676
],
"655": [
628,
682
],
"621": [
594,
622
],
"622": [
621,
649
],
"628": [
601,
655
],
"594": [
567,
621
],
"601": [
574,
628
],
"567": [
540,
594
],
"574": [
547,
601
],
"540": [
513,
567
],
"547": [
520,
574
],
"513": [
486,
540
],
"519": [
492,
520
],
"520": [
519,
547
],
"486": [
459,
513
],
"492": [
465,
519
],
"459": [
432,
486
],
"465": [
438,
492
],
"432": [
405,
459
],
"438": [
411,
465
],
"405": [
378,
432
],
"411": [
384,
438
],
"378": [
351,
405
],
"384": [
357,
411
],
"351": [
324,
378
],
"357": [
330,
384
],
"324": [
297,
351
],
"330": [
303,
357
],
"297": [
270,
324
],
"303": [
276,
330
],
"270": [
243,
297
],
"276": [
249,
303
],
"243": [
216,
270
],
"249": [
222,
276
],
"216": [
189,
243
],
"222": [
195,
249
],
"189": [
162,
216
],
"195": [
168,
222
],
"162": [
135,
189
],
"168": [
141,
195
],
"135": [
108,
162
],
"141": [
114,
168
],
"108": [
81,
135
],
"114": [
87,
141
],
"81": [
54,
108
],
"87": [
60,
114
],
"54": [
27,
81
],
"60": [
33,
87
],
"27": [
0,
54
],
"33": [
6,
60
],
"0": [
1,
27
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
33
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/DownStepper-v0.json
================================================
{
"grid_width": 75,
"grid_height": 10,
"objects": {
"ground": {
"indices": [
675,
676,
677,
678,
679,
680,
681,
682,
683,
684,
685,
686,
687,
688,
689,
690,
691,
692,
693,
694,
695,
620,
621,
622,
623,
624,
625,
626,
627,
628,
553,
554,
555,
556,
557,
558,
559,
560,
485,
486,
487,
488,
489,
490,
491,
416,
417,
418,
419,
420,
421,
422,
347,
348,
349,
350,
351,
352,
277,
278,
279,
280,
281,
282,
207,
208,
209,
210,
211,
136,
137,
138,
139,
140,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"675": [
676
],
"676": [
675,
677
],
"677": [
676,
678
],
"678": [
677,
679
],
"679": [
678,
680
],
"680": [
679,
681
],
"681": [
680,
682
],
"682": [
681,
683
],
"683": [
682,
684
],
"684": [
683,
685
],
"685": [
684,
686
],
"686": [
685,
687
],
"687": [
686,
688
],
"688": [
687,
689
],
"689": [
688,
690
],
"690": [
689,
691
],
"691": [
690,
692
],
"692": [
691,
693
],
"693": [
692,
694
],
"694": [
693,
695
],
"695": [
694,
620
],
"620": [
695,
621
],
"621": [
620,
622
],
"622": [
621,
623
],
"623": [
622,
624
],
"624": [
623,
625
],
"625": [
624,
626
],
"626": [
625,
627
],
"627": [
626,
628
],
"628": [
627,
553
],
"553": [
628,
554
],
"554": [
553,
555
],
"555": [
554,
556
],
"556": [
555,
557
],
"557": [
556,
558
],
"558": [
557,
559
],
"559": [
558,
560
],
"560": [
559,
485
],
"485": [
560,
486
],
"486": [
485,
487
],
"487": [
486,
488
],
"488": [
487,
489
],
"489": [
488,
490
],
"490": [
489,
491
],
"491": [
490,
416
],
"416": [
491,
417
],
"417": [
416,
418
],
"418": [
417,
419
],
"419": [
418,
420
],
"420": [
419,
421
],
"421": [
420,
422
],
"422": [
421,
347
],
"347": [
422,
348
],
"348": [
347,
349
],
"349": [
348,
350
],
"350": [
349,
351
],
"351": [
350,
352
],
"352": [
351,
277
],
"277": [
352,
278
],
"278": [
277,
279
],
"279": [
278,
280
],
"280": [
279,
281
],
"281": [
280,
282
],
"282": [
281,
207
],
"207": [
282,
208
],
"208": [
207,
209
],
"209": [
208,
210
],
"210": [
209,
211
],
"211": [
210,
136
],
"136": [
211,
137
],
"137": [
136,
138
],
"138": [
137,
139
],
"139": [
138,
140
],
"140": [
139,
65
],
"65": [
140,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
70
],
"70": [
69,
71
],
"71": [
70,
72
],
"72": [
71,
73
],
"73": [
72,
74
],
"74": [
73
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Flipper-v0.json
================================================
{
"grid_width": 70,
"grid_height": 1,
"objects": {
"new_object_1": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
4,
2
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
23,
21
],
"23": [
24,
22
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
39,
37
],
"39": [
40,
38
],
"40": [
41,
39
],
"41": [
42,
40
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
46,
48
],
"48": [
49,
47
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
50,
52
],
"52": [
51,
53
],
"53": [
52,
54
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/GapJumper-v0.json
================================================
{
"grid_width": 80,
"grid_height": 6,
"objects": {
"platform_1": {
"indices": [
400,
401,
402,
403,
404,
405,
406,
407,
408,
409,
410,
411,
412,
413,
414,
415,
416,
417,
418,
419
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"400": [
401
],
"401": [
400,
402
],
"402": [
401,
403
],
"403": [
402,
404
],
"404": [
403,
405
],
"405": [
404,
406
],
"406": [
405,
407
],
"407": [
406,
408
],
"408": [
407,
409
],
"409": [
408,
410
],
"410": [
409,
411
],
"411": [
410,
412
],
"412": [
411,
413
],
"413": [
412,
414
],
"414": [
413,
415
],
"415": [
414,
416
],
"416": [
415,
417
],
"417": [
416,
418
],
"418": [
417,
419
],
"419": [
418
]
}
},
"platform_2": {
"indices": [
425,
426,
427,
428,
429,
430,
431,
432,
433,
434
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"425": [
426
],
"426": [
425,
427
],
"427": [
426,
428
],
"428": [
427,
429
],
"429": [
428,
430
],
"430": [
429,
431
],
"431": [
430,
432
],
"432": [
431,
433
],
"433": [
432,
434
],
"434": [
433
]
}
},
"platform_3": {
"indices": [
440,
441,
442,
443,
444,
445,
446,
447,
448,
449
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"440": [
441
],
"441": [
440,
442
],
"442": [
441,
443
],
"443": [
442,
444
],
"444": [
443,
445
],
"445": [
444,
446
],
"446": [
445,
447
],
"447": [
446,
448
],
"448": [
447,
449
],
"449": [
448
]
}
},
"platform_4": {
"indices": [
455,
456,
457,
458,
459,
460,
461,
462,
463,
464
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"455": [
456
],
"456": [
455,
457
],
"457": [
456,
458
],
"458": [
457,
459
],
"459": [
458,
460
],
"460": [
459,
461
],
"461": [
460,
462
],
"462": [
461,
463
],
"463": [
462,
464
],
"464": [
463
]
}
},
"platform_5": {
"indices": [
470,
471,
472,
473,
474,
475,
476,
477,
478,
479
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"470": [
471
],
"471": [
470,
472
],
"472": [
471,
473
],
"473": [
472,
474
],
"474": [
473,
475
],
"475": [
474,
476
],
"476": [
475,
477
],
"477": [
476,
478
],
"478": [
477,
479
],
"479": [
478
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Hurdler-v0.json
================================================
{
"grid_width": 70,
"grid_height": 6,
"objects": {
"ground": {
"indices": [
419,
349,
279,
160,
176,
177,
192,
198,
209,
82,
90,
98,
106,
107,
115,
122,
128,
139,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"419": [
349
],
"349": [
279,
419
],
"279": [
349,
209
],
"160": [
90
],
"176": [
106,
177
],
"177": [
176,
107
],
"192": [
122
],
"198": [
128
],
"209": [
139,
279
],
"82": [
12
],
"90": [
20,
160
],
"98": [
28
],
"106": [
176,
36,
107
],
"107": [
106,
37,
177
],
"115": [
45
],
"122": [
52,
192
],
"128": [
58,
198
],
"139": [
69,
209
],
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13,
82
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21,
90
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29,
98
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37,
106
],
"37": [
36,
38,
107
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46,
115
],
"46": [
45,
47
],
"47": [
46,
48
],
"48": [
47,
49
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
50,
52
],
"52": [
51,
53,
122
],
"53": [
52,
54
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59,
128
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
139
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Jumper-v0.json
================================================
{
"grid_width": 60,
"grid_height": 8,
"objects": {
"ground": {
"indices": [
420,
479,
360,
419,
300,
359,
240,
299,
180,
239,
120,
179,
60,
119,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"420": [
360
],
"479": [
419
],
"360": [
420,
300
],
"419": [
359,
479
],
"300": [
360,
240
],
"359": [
419,
299
],
"240": [
300,
180
],
"299": [
359,
239
],
"180": [
240,
120
],
"239": [
179,
299
],
"120": [
180,
60
],
"179": [
119,
239
],
"60": [
120,
0
],
"119": [
59,
179
],
"0": [
60,
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
46,
44
],
"46": [
45,
47
],
"47": [
48,
46
],
"48": [
49,
47
],
"49": [
50,
48
],
"50": [
49,
51
],
"51": [
50,
52
],
"52": [
51,
53
],
"53": [
52,
54
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
119
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Lifter-v0.json
================================================
{
"grid_width": 11,
"grid_height": 5,
"objects": {
"ground": {
"indices": [
44,
54,
33,
43,
22,
23,
24,
25,
29,
30,
31,
32,
14,
18,
3,
4,
5,
6,
7
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"44": [
33
],
"54": [
43
],
"33": [
44,
22
],
"43": [
54,
32
],
"22": [
33,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
14
],
"29": [
30,
18
],
"30": [
31,
29
],
"31": [
32,
30
],
"32": [
43,
31
],
"14": [
25,
3
],
"18": [
29,
7
],
"3": [
14,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
6,
18
]
}
},
"package": {
"indices": [
27,
16
],
"types": [
1,
1
],
"neighbors": {
"27": [
16
],
"16": [
27
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/ObstacleTraverser-v0.json
================================================
{
"grid_width": 80,
"grid_height": 3,
"objects": {
"ground": {
"indices": [
215,
220,
224,
102,
108,
113,
114,
119,
122,
123,
125,
127,
130,
131,
134,
135,
136,
137,
139,
140,
142,
143,
144,
145,
147,
148,
152,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"215": [
135
],
"220": [
140
],
"224": [
144
],
"102": [
22
],
"108": [
28
],
"113": [
33,
114
],
"114": [
113,
34
],
"119": [
39
],
"122": [
42,
123
],
"123": [
122,
43
],
"125": [
45
],
"127": [
47
],
"130": [
50,
131
],
"131": [
130,
51
],
"134": [
54,
135
],
"135": [
134,
55,
136,
215
],
"136": [
135,
56,
137
],
"137": [
136,
57
],
"139": [
59,
140
],
"140": [
139,
60,
220
],
"142": [
62,
143
],
"143": [
142,
63,
144
],
"144": [
143,
145,
64,
224
],
"145": [
65,
144
],
"147": [
67,
148
],
"148": [
147,
68
],
"152": [
72
],
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23,
102
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29,
108
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34,
113
],
"34": [
33,
35,
114
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40,
119
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43,
122
],
"43": [
42,
44,
123
],
"44": [
43,
45
],
"45": [
44,
46,
125
],
"46": [
45,
47
],
"47": [
46,
48,
127
],
"48": [
47,
49
],
"49": [
48,
50
],
"50": [
49,
51,
130
],
"51": [
50,
52,
131
],
"52": [
51,
53
],
"53": [
52,
54
],
"54": [
53,
55,
134
],
"55": [
54,
56,
135
],
"56": [
55,
57,
136
],
"57": [
56,
58,
137
],
"58": [
57,
59
],
"59": [
58,
60,
139
],
"60": [
59,
61,
140
],
"61": [
60,
62
],
"62": [
61,
63,
142
],
"63": [
62,
64,
143
],
"64": [
63,
65,
144
],
"65": [
64,
66,
145
],
"66": [
65,
67
],
"67": [
66,
68,
147
],
"68": [
67,
69,
148
],
"69": [
68,
70
],
"70": [
69,
71
],
"71": [
70,
72
],
"72": [
71,
73,
152
],
"73": [
72,
74
],
"74": [
73,
75
],
"75": [
74,
76
],
"76": [
75,
77
],
"77": [
76,
78
],
"78": [
77,
79
],
"79": [
78
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/ObstacleTraverser-v1.json
================================================
{
"grid_width": 60,
"grid_height": 10,
"objects": {
"ground": {
"indices": [
598,
599,
538,
539,
478,
479,
418,
419,
358,
359,
284,
298,
299,
182,
184,
198,
203,
212,
213,
216,
218,
219,
220,
223,
224,
225,
227,
229,
234,
238,
239,
120,
121,
122,
123,
124,
125,
126,
127,
129,
132,
133,
137,
138,
139,
141,
142,
143,
144,
146,
148,
149,
151,
152,
153,
155,
156,
157,
158,
159,
160,
162,
163,
164,
165,
166,
167,
168,
169,
170,
173,
174,
175,
177,
178,
179,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116,
117,
118,
119,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"598": [
538,
599
],
"599": [
598,
539
],
"538": [
598,
478,
539
],
"539": [
538,
479,
599
],
"478": [
538,
418,
479
],
"479": [
478,
419,
539
],
"418": [
478,
358,
419
],
"419": [
418,
359,
479
],
"358": [
418,
298,
359
],
"359": [
358,
299,
419
],
"284": [
224
],
"298": [
358,
238,
299
],
"299": [
298,
239,
359
],
"182": [
122
],
"184": [
124
],
"198": [
138
],
"203": [
143
],
"212": [
152,
213
],
"213": [
212,
153
],
"216": [
156
],
"218": [
158,
219
],
"219": [
218,
159,
220
],
"220": [
219,
160
],
"223": [
163,
224
],
"224": [
223,
164,
225,
284
],
"225": [
224,
165
],
"227": [
167
],
"229": [
169
],
"234": [
174
],
"238": [
298,
178,
239
],
"239": [
238,
179,
299
],
"120": [
121,
60
],
"121": [
122,
61,
120
],
"122": [
123,
62,
121,
182
],
"123": [
124,
63,
122
],
"124": [
125,
64,
123,
184
],
"125": [
126,
65,
124
],
"126": [
127,
66,
125
],
"127": [
67,
126
],
"129": [
69
],
"132": [
133,
72
],
"133": [
73,
132
],
"137": [
138,
77
],
"138": [
139,
78,
137,
198
],
"139": [
79,
138
],
"141": [
142,
81
],
"142": [
143,
82,
141
],
"143": [
144,
83,
142,
203
],
"144": [
84,
143
],
"146": [
86
],
"148": [
149,
88
],
"149": [
89,
148
],
"151": [
152,
91
],
"152": [
153,
92,
151,
212
],
"153": [
93,
152,
213
],
"155": [
156,
95
],
"156": [
96,
155,
157,
216
],
"157": [
156,
158,
97
],
"158": [
159,
98,
157,
218
],
"159": [
160,
99,
158,
219
],
"160": [
100,
159,
220
],
"162": [
163,
102
],
"163": [
164,
103,
162,
223
],
"164": [
165,
104,
163,
224
],
"165": [
166,
105,
164,
225
],
"166": [
167,
106,
165
],
"167": [
107,
168,
166,
227
],
"168": [
167,
169,
108
],
"169": [
168,
170,
109,
229
],
"170": [
169,
110
],
"173": [
174,
113
],
"174": [
175,
114,
173,
234
],
"175": [
115,
174
],
"177": [
178,
117
],
"178": [
179,
118,
177,
238
],
"179": [
119,
178,
239
],
"60": [
0,
61,
120
],
"61": [
60,
1,
62,
121
],
"62": [
61,
2,
63,
122
],
"63": [
62,
3,
64,
123
],
"64": [
63,
4,
65,
124
],
"65": [
64,
5,
66,
125
],
"66": [
65,
6,
67,
126
],
"67": [
66,
7,
68,
127
],
"68": [
67,
8,
69
],
"69": [
68,
9,
70,
129
],
"70": [
69,
10,
71
],
"71": [
70,
11,
72
],
"72": [
71,
12,
73,
132
],
"73": [
72,
13,
74,
133
],
"74": [
73,
14,
75
],
"75": [
74,
15
],
"77": [
17,
78,
137
],
"78": [
77,
18,
79,
138
],
"79": [
78,
19,
80,
139
],
"80": [
79,
20,
81
],
"81": [
80,
82,
21,
141
],
"82": [
22,
81,
83,
142
],
"83": [
82,
23,
84,
143
],
"84": [
83,
24,
85,
144
],
"85": [
84,
25,
86
],
"86": [
85,
26,
87,
146
],
"87": [
86,
88,
27
],
"88": [
28,
87,
89,
148
],
"89": [
88,
29,
90,
149
],
"90": [
89,
30,
91
],
"91": [
90,
31,
92,
151
],
"92": [
91,
93,
32,
152
],
"93": [
33,
94,
92,
153
],
"94": [
93,
34,
95
],
"95": [
94,
35,
96,
155
],
"96": [
95,
36,
97,
156
],
"97": [
96,
37,
98,
157
],
"98": [
97,
99,
38,
158
],
"99": [
39,
98,
100,
159
],
"100": [
99,
40,
101,
160
],
"101": [
100,
102,
41
],
"102": [
42,
103,
101,
162
],
"103": [
102,
43,
104,
163
],
"104": [
103,
105,
44,
164
],
"105": [
45,
104,
106,
165
],
"106": [
105,
107,
46,
166
],
"107": [
47,
106,
167,
108
],
"108": [
107,
109,
168,
48
],
"109": [
110,
169,
49,
108
],
"110": [
50,
111,
170,
109
],
"111": [
110,
51,
112
],
"112": [
111,
52,
113
],
"113": [
112,
114,
53,
173
],
"114": [
54,
115,
113,
174
],
"115": [
114,
55,
116,
175
],
"116": [
115,
56,
117
],
"117": [
116,
57,
118,
177
],
"118": [
117,
119,
58,
178
],
"119": [
59,
118,
179
],
"0": [
1,
60
],
"1": [
0,
2,
61
],
"2": [
1,
3,
62
],
"3": [
2,
4,
63
],
"4": [
3,
5,
64
],
"5": [
4,
6,
65
],
"6": [
5,
7,
66
],
"7": [
6,
8,
67
],
"8": [
7,
9,
68
],
"9": [
8,
10,
69
],
"10": [
9,
11,
70
],
"11": [
10,
12,
71
],
"12": [
11,
13,
72
],
"13": [
12,
14,
73
],
"14": [
13,
15,
74
],
"15": [
14,
16,
75
],
"16": [
15,
17
],
"17": [
16,
18,
77
],
"18": [
17,
19,
78
],
"19": [
18,
20,
79
],
"20": [
19,
21,
80
],
"21": [
20,
22,
81
],
"22": [
21,
23,
82
],
"23": [
22,
24,
83
],
"24": [
23,
25,
84
],
"25": [
24,
26,
85
],
"26": [
25,
27,
86
],
"27": [
26,
28,
87
],
"28": [
27,
29,
88
],
"29": [
28,
30,
89
],
"30": [
29,
31,
90
],
"31": [
30,
32,
91
],
"32": [
31,
33,
92
],
"33": [
32,
34,
93
],
"34": [
33,
35,
94
],
"35": [
34,
36,
95
],
"36": [
35,
37,
96
],
"37": [
36,
38,
97
],
"38": [
37,
39,
98
],
"39": [
38,
40,
99
],
"40": [
39,
41,
100
],
"41": [
40,
42,
101
],
"42": [
41,
43,
102
],
"43": [
42,
44,
103
],
"44": [
43,
45,
104
],
"45": [
44,
46,
105
],
"46": [
45,
47,
106
],
"47": [
46,
48,
107
],
"48": [
47,
49,
108
],
"49": [
48,
50,
109
],
"50": [
49,
51,
110
],
"51": [
50,
52,
111
],
"52": [
51,
53,
112
],
"53": [
52,
54,
113
],
"54": [
53,
55,
114
],
"55": [
54,
56,
115
],
"56": [
55,
57,
116
],
"57": [
56,
58,
117
],
"58": [
57,
59,
118
],
"59": [
58,
119
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/PlatformJumper-v0.json
================================================
{
"grid_width": 91,
"grid_height": 9,
"objects": {
"platform_3": {
"indices": [
761,
762,
763,
764,
765,
766,
767,
768,
769,
770
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"761": [
762
],
"762": [
761,
763
],
"763": [
762,
764
],
"764": [
763,
765
],
"765": [
764,
766
],
"766": [
765,
767
],
"767": [
766,
768
],
"768": [
767,
769
],
"769": [
768,
770
],
"770": [
769
]
}
},
"platform_2": {
"indices": [
658,
659,
660,
661,
662,
663,
664,
665,
666,
667
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"658": [
659
],
"659": [
658,
660
],
"660": [
659,
661
],
"661": [
660,
662
],
"662": [
661,
663
],
"663": [
662,
664
],
"664": [
663,
665
],
"665": [
664,
666
],
"666": [
665,
667
],
"667": [
666
]
}
},
"platform_4": {
"indices": [
592,
593,
594,
595,
596,
597,
598,
599,
600,
601
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"592": [
593
],
"593": [
592,
594
],
"594": [
593,
595
],
"595": [
594,
596
],
"596": [
595,
597
],
"597": [
596,
598
],
"598": [
597,
599
],
"599": [
598,
600
],
"600": [
599,
601
],
"601": [
600
]
}
},
"platform_6": {
"indices": [
616,
617,
618,
619,
620,
621,
622,
623,
624,
625
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"616": [
617
],
"617": [
616,
618
],
"618": [
617,
619
],
"619": [
618,
620
],
"620": [
619,
621
],
"621": [
620,
622
],
"622": [
621,
623
],
"623": [
622,
624
],
"624": [
623,
625
],
"625": [
624
]
}
},
"platform_1": {
"indices": [
455,
456,
457,
458,
459,
460,
461,
462,
463,
464,
465,
466,
467,
468,
469,
470,
471,
472,
473,
474
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"455": [
456
],
"456": [
455,
457
],
"457": [
456,
458
],
"458": [
457,
459
],
"459": [
458,
460
],
"460": [
459,
461
],
"461": [
460,
462
],
"462": [
461,
463
],
"463": [
462,
464
],
"464": [
463,
465
],
"465": [
464,
466
],
"466": [
465,
467
],
"467": [
466,
468
],
"468": [
467,
469
],
"469": [
468,
470
],
"470": [
469,
471
],
"471": [
470,
472
],
"472": [
471,
473
],
"473": [
472,
474
],
"474": [
473
]
}
},
"platform_5": {
"indices": [
512,
513,
514,
515,
516,
517,
518,
519,
520,
521
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"512": [
513
],
"513": [
512,
514
],
"514": [
513,
515
],
"515": [
514,
516
],
"516": [
515,
517
],
"517": [
516,
518
],
"518": [
517,
519
],
"519": [
518,
520
],
"520": [
519,
521
],
"521": [
520
]
}
},
"platform_7": {
"indices": [
354,
355,
356,
357,
358,
359,
360,
361,
362,
363
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"354": [
355
],
"355": [
354,
356
],
"356": [
355,
357
],
"357": [
356,
358
],
"358": [
357,
359
],
"359": [
358,
360
],
"360": [
359,
361
],
"361": [
360,
362
],
"362": [
361,
363
],
"363": [
362
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Pusher-v0.json
================================================
{
"grid_width": 100,
"grid_height": 3,
"objects": {
"package": {
"indices": [
208,
209,
210,
108,
109,
110
],
"types": [
2,
2,
2,
2,
2,
2
],
"neighbors": {
"208": [
209,
108
],
"209": [
210,
109,
208
],
"210": [
110,
209
],
"108": [
109,
208
],
"109": [
108,
110,
209
],
"110": [
109,
210
]
}
},
"ground": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
48,
46
],
"48": [
49,
47
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
52,
50
],
"52": [
53,
51
],
"53": [
54,
52
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
70
],
"70": [
69,
71
],
"71": [
70,
72
],
"72": [
71,
73
],
"73": [
72,
74
],
"74": [
73,
75
],
"75": [
74,
76
],
"76": [
75,
77
],
"77": [
76,
78
],
"78": [
77,
79
],
"79": [
78,
80
],
"80": [
79,
81
],
"81": [
80,
82
],
"82": [
81,
83
],
"83": [
82,
84
],
"84": [
83,
85
],
"85": [
84,
86
],
"86": [
85,
87
],
"87": [
86,
88
],
"88": [
87,
89
],
"89": [
90,
88
],
"90": [
91,
89
],
"91": [
92,
90
],
"92": [
93,
91
],
"93": [
94,
92
],
"94": [
95,
93
],
"95": [
96,
94
],
"96": [
97,
95
],
"97": [
98,
96
],
"98": [
99,
97
],
"99": [
98
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Pusher-v1.json
================================================
{
"grid_width": 100,
"grid_height": 3,
"objects": {
"package": {
"indices": [
208,
209,
210,
108,
109,
110
],
"types": [
1,
1,
1,
1,
1,
1
],
"neighbors": {
"208": [
209,
108
],
"209": [
210,
109,
208
],
"210": [
110,
209
],
"108": [
109,
208
],
"109": [
108,
110,
209
],
"110": [
109,
210
]
}
},
"ground": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
48,
46
],
"48": [
49,
47
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
52,
50
],
"52": [
53,
51
],
"53": [
54,
52
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
70
],
"70": [
69,
71
],
"71": [
70,
72
],
"72": [
71,
73
],
"73": [
72,
74
],
"74": [
73,
75
],
"75": [
74,
76
],
"76": [
75,
77
],
"77": [
76,
78
],
"78": [
77,
79
],
"79": [
78,
80
],
"80": [
79,
81
],
"81": [
80,
82
],
"82": [
81,
83
],
"83": [
82,
84
],
"84": [
83,
85
],
"85": [
84,
86
],
"86": [
85,
87
],
"87": [
86,
88
],
"88": [
87,
89
],
"89": [
90,
88
],
"90": [
91,
89
],
"91": [
92,
90
],
"92": [
93,
91
],
"93": [
94,
92
],
"94": [
95,
93
],
"95": [
96,
94
],
"96": [
97,
95
],
"97": [
98,
96
],
"98": [
99,
97
],
"99": [
98
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/ShapeChange.json
================================================
{
"grid_width": 20,
"grid_height": 10,
"objects": {
"new_object_4": {
"indices": [
180,
181,
198,
199,
160,
161,
178,
179,
140,
141,
158,
159,
120,
121,
138,
139,
100,
101,
118,
119,
80,
81,
98,
99,
60,
61,
78,
79,
40,
41,
58,
59,
20,
21,
38,
39,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"180": [
160,
181
],
"181": [
180,
161
],
"198": [
199,
178
],
"199": [
179,
198
],
"160": [
180,
140,
161
],
"161": [
160,
181,
141
],
"178": [
179,
158,
198
],
"179": [
199,
159,
178
],
"140": [
160,
120,
141
],
"141": [
140,
161,
121
],
"158": [
159,
138,
178
],
"159": [
179,
139,
158
],
"120": [
140,
100,
121
],
"121": [
120,
141,
101
],
"138": [
139,
118,
158
],
"139": [
159,
119,
138
],
"100": [
80,
120,
101
],
"101": [
100,
121,
81
],
"118": [
119,
98,
138
],
"119": [
139,
99,
118
],
"80": [
60,
100,
81
],
"81": [
80,
101,
61
],
"98": [
99,
78,
118
],
"99": [
119,
79,
98
],
"60": [
80,
40,
61
],
"61": [
60,
81,
41
],
"78": [
79,
58,
98
],
"79": [
99,
59,
78
],
"40": [
60,
20,
41
],
"41": [
40,
61,
21
],
"58": [
59,
38,
78
],
"59": [
79,
39,
58
],
"20": [
40,
0,
21
],
"21": [
20,
41,
1
],
"38": [
39,
18,
58
],
"39": [
59,
19,
38
],
"0": [
1,
20
],
"1": [
0,
2,
21
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19,
38
],
"19": [
18,
39
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Thrower-v0.json
================================================
{
"grid_width": 70,
"grid_height": 10,
"objects": {
"ground": {
"indices": [
669,
699,
599,
629,
518,
529,
559,
443,
448,
459,
489,
373,
378,
389,
419,
298,
303,
308,
319,
349,
224,
228,
233,
238,
249,
279,
150,
154,
158,
163,
168,
179,
209,
80,
84,
88,
93,
98,
109,
139,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"669": [
599
],
"699": [
629
],
"599": [
529,
669
],
"629": [
699,
559
],
"518": [
448
],
"529": [
459,
599
],
"559": [
629,
489
],
"443": [
373
],
"448": [
378,
518
],
"459": [
389,
529
],
"489": [
559,
419
],
"373": [
303,
443
],
"378": [
308,
448
],
"389": [
319,
459
],
"419": [
489,
349
],
"298": [
228
],
"303": [
233,
373
],
"308": [
238,
378
],
"319": [
249,
389
],
"349": [
419,
279
],
"224": [
154
],
"228": [
158,
298
],
"233": [
163,
303
],
"238": [
168,
308
],
"249": [
179,
319
],
"279": [
349,
209
],
"150": [
80
],
"154": [
84,
224
],
"158": [
88,
228
],
"163": [
93,
233
],
"168": [
98,
238
],
"179": [
109,
249
],
"209": [
279,
139
],
"80": [
10,
150
],
"84": [
14,
154
],
"88": [
18,
158
],
"93": [
23,
163
],
"98": [
28,
168
],
"109": [
39,
179
],
"139": [
209,
69
],
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
9,
7
],
"9": [
10,
8
],
"10": [
11,
9,
80
],
"11": [
12,
10
],
"12": [
13,
11
],
"13": [
14,
12
],
"14": [
15,
13,
84
],
"15": [
16,
14
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
19,
17,
88
],
"19": [
20,
18
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24,
93
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29,
98
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
36,
34
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40,
109
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
46,
48
],
"48": [
47,
49
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
50,
52
],
"52": [
51,
53
],
"53": [
52,
54
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
139
]
}
},
"package": {
"indices": [
563,
564,
565,
493,
494,
495
],
"types": [
2,
2,
2,
2,
2,
2
],
"neighbors": {
"563": [
564,
493
],
"564": [
565,
494,
563
],
"565": [
495,
564
],
"493": [
494,
563
],
"494": [
493,
495,
564
],
"495": [
494,
565
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Traverser-v0.json
================================================
{
"grid_width": 60,
"grid_height": 9,
"objects": {
"ground": {
"indices": [
480,
481,
482,
483,
484,
485,
486,
487,
488,
489,
490,
491,
492,
493,
494,
495,
496,
497,
498,
499,
439,
379,
409,
410,
411,
412,
413,
414,
415,
416,
417,
418,
419,
319,
349,
259,
289,
199,
229,
139,
169,
79,
109,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"480": [
481
],
"481": [
480,
482
],
"482": [
481,
483
],
"483": [
482,
484
],
"484": [
483,
485
],
"485": [
484,
486
],
"486": [
485,
487
],
"487": [
486,
488
],
"488": [
487,
489
],
"489": [
488,
490
],
"490": [
489,
491
],
"491": [
490,
492
],
"492": [
491,
493
],
"493": [
492,
494
],
"494": [
493,
495
],
"495": [
494,
496
],
"496": [
495,
497
],
"497": [
496,
498
],
"498": [
497,
499
],
"499": [
498,
439
],
"439": [
499,
379
],
"379": [
439,
319
],
"409": [
349,
410
],
"410": [
409,
411
],
"411": [
410,
412
],
"412": [
411,
413
],
"413": [
412,
414
],
"414": [
413,
415
],
"415": [
414,
416
],
"416": [
415,
417
],
"417": [
416,
418
],
"418": [
417,
419
],
"419": [
418
],
"319": [
379,
259
],
"349": [
289,
409
],
"259": [
319,
199
],
"289": [
229,
349
],
"199": [
259,
139
],
"229": [
169,
289
],
"139": [
199,
79
],
"169": [
109,
229
],
"79": [
139,
19
],
"109": [
49,
169
],
"19": [
79,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
46,
48
],
"48": [
47,
49
],
"49": [
48,
109
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/UpStepper-v0.json
================================================
{
"grid_width": 70,
"grid_height": 9,
"objects": {
"ground": {
"indices": [
621,
622,
623,
624,
625,
626,
627,
628,
629,
545,
546,
547,
548,
549,
550,
551,
471,
472,
473,
474,
475,
397,
398,
399,
400,
401,
322,
323,
324,
325,
326,
327,
246,
247,
248,
249,
250,
251,
252,
169,
170,
171,
172,
173,
174,
175,
176,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"621": [
551,
622
],
"622": [
621,
623
],
"623": [
622,
624
],
"624": [
623,
625
],
"625": [
624,
626
],
"626": [
625,
627
],
"627": [
626,
628
],
"628": [
627,
629
],
"629": [
628
],
"545": [
475,
546
],
"546": [
545,
547
],
"547": [
546,
548
],
"548": [
547,
549
],
"549": [
548,
550
],
"550": [
549,
551
],
"551": [
550,
621
],
"471": [
401,
472
],
"472": [
471,
473
],
"473": [
472,
474
],
"474": [
473,
475
],
"475": [
474,
545
],
"397": [
327,
398
],
"398": [
397,
399
],
"399": [
398,
400
],
"400": [
399,
401
],
"401": [
400,
471
],
"322": [
252,
323
],
"323": [
322,
324
],
"324": [
323,
325
],
"325": [
324,
326
],
"326": [
325,
327
],
"327": [
326,
397
],
"246": [
176,
247
],
"247": [
246,
248
],
"248": [
247,
249
],
"249": [
248,
250
],
"250": [
249,
251
],
"251": [
250,
252
],
"252": [
251,
322
],
"169": [
99,
170
],
"170": [
169,
171
],
"171": [
170,
172
],
"172": [
171,
173
],
"173": [
172,
174
],
"174": [
173,
175
],
"175": [
174,
176
],
"176": [
175,
246
],
"90": [
20,
91
],
"91": [
90,
92
],
"92": [
91,
93
],
"93": [
92,
94
],
"94": [
93,
95
],
"95": [
94,
96
],
"96": [
95,
97
],
"97": [
96,
98
],
"98": [
97,
99
],
"99": [
98,
169
],
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
6,
8
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
90
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/Walker-v0.json
================================================
{
"grid_width": 100,
"grid_height": 1,
"objects": {
"ground": {
"indices": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99
],
"types": [
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3,
5
],
"5": [
4,
6
],
"6": [
5,
7
],
"7": [
8,
6
],
"8": [
7,
9
],
"9": [
8,
10
],
"10": [
9,
11
],
"11": [
10,
12
],
"12": [
11,
13
],
"13": [
12,
14
],
"14": [
13,
15
],
"15": [
14,
16
],
"16": [
15,
17
],
"17": [
16,
18
],
"18": [
17,
19
],
"19": [
18,
20
],
"20": [
19,
21
],
"21": [
20,
22
],
"22": [
21,
23
],
"23": [
22,
24
],
"24": [
23,
25
],
"25": [
24,
26
],
"26": [
25,
27
],
"27": [
26,
28
],
"28": [
27,
29
],
"29": [
28,
30
],
"30": [
29,
31
],
"31": [
30,
32
],
"32": [
31,
33
],
"33": [
32,
34
],
"34": [
33,
35
],
"35": [
34,
36
],
"36": [
35,
37
],
"37": [
36,
38
],
"38": [
37,
39
],
"39": [
38,
40
],
"40": [
39,
41
],
"41": [
40,
42
],
"42": [
41,
43
],
"43": [
42,
44
],
"44": [
43,
45
],
"45": [
44,
46
],
"46": [
45,
47
],
"47": [
48,
46
],
"48": [
49,
47
],
"49": [
48,
50
],
"50": [
49,
51
],
"51": [
52,
50
],
"52": [
53,
51
],
"53": [
54,
52
],
"54": [
53,
55
],
"55": [
54,
56
],
"56": [
55,
57
],
"57": [
56,
58
],
"58": [
57,
59
],
"59": [
58,
60
],
"60": [
59,
61
],
"61": [
60,
62
],
"62": [
61,
63
],
"63": [
62,
64
],
"64": [
63,
65
],
"65": [
64,
66
],
"66": [
65,
67
],
"67": [
66,
68
],
"68": [
67,
69
],
"69": [
68,
70
],
"70": [
69,
71
],
"71": [
70,
72
],
"72": [
71,
73
],
"73": [
72,
74
],
"74": [
73,
75
],
"75": [
74,
76
],
"76": [
75,
77
],
"77": [
76,
78
],
"78": [
77,
79
],
"79": [
78,
80
],
"80": [
79,
81
],
"81": [
80,
82
],
"82": [
81,
83
],
"83": [
82,
84
],
"84": [
83,
85
],
"85": [
84,
86
],
"86": [
85,
87
],
"87": [
86,
88
],
"88": [
87,
89
],
"89": [
90,
88
],
"90": [
91,
89
],
"91": [
92,
90
],
"92": [
93,
91
],
"93": [
94,
92
],
"94": [
95,
93
],
"95": [
96,
94
],
"96": [
97,
95
],
"97": [
98,
96
],
"98": [
99,
97
],
"99": [
98
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/package.json
================================================
{
"grid_width": 3,
"grid_height": 2,
"objects": {
"peg": {
"indices": [
3,
4,
5,
0,
1,
2
],
"types": [
2,
2,
2,
2,
2,
2
],
"neighbors": {
"3": [
0,
4
],
"4": [
3,
1,
5
],
"5": [
4,
2
],
"0": [
1,
3
],
"1": [
0,
2,
4
],
"2": [
1,
5
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/peg.json
================================================
{
"grid_width": 5,
"grid_height": 1,
"objects": {
"peg": {
"indices": [
0,
1,
2,
3,
4
],
"types": [
5,
5,
5,
5,
5
],
"neighbors": {
"0": [
1
],
"1": [
0,
2
],
"2": [
1,
3
],
"3": [
2,
4
],
"4": [
3
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/rigid_1x1.json
================================================
{
"grid_width": 1,
"grid_height": 1,
"objects": {
"new_object_1": {
"indices": [
0
],
"types": [
1
],
"neighbors": {
"0": []
}
}
}
}
================================================
FILE: evogym/envs/sim_files/rigid_2x2.json
================================================
{
"grid_width": 2,
"grid_height": 2,
"objects": {
"new_object_2": {
"indices": [
2,
3,
0,
1
],
"types": [
1,
1,
1,
1
],
"neighbors": {
"2": [
3,
0
],
"3": [
2,
1
],
"0": [
1,
2
],
"1": [
3,
0
]
}
}
}
}
================================================
FILE: evogym/envs/sim_files/rigid_3x3.json
================================================
{
"grid_width": 3,
"grid_height": 3,
"objects": {
"new_object_3": {
"indices": [
6,
7,
8,
3,
4,
5,
0,
1,
2
],
"types": [
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"neighbors": {
"6": [
7,
3
],
"7": [
6,
8,
4
],
"8": [
7,
5
],
"3": [
6,
0,
4
],
"4": [
3,
5,
7,
1
],
"5": [
8,
2,
4
],
"0": [
1,
3
],
"1": [
2,
0,
4
],
"2": [
5,
1
]
}
}
}
}
================================================
FILE: evogym/envs/traverse.py
================================================
from evogym.envs.base import EvoGymBase
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
from typing import Dict, Any, Optional
class StairsBase(BenchmarkBase):
def __init__(
self,
world: EvoWorld,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
super().__init__(world=world, render_mode=render_mode, render_options=render_options)
def get_reward(self, robot_pos_init, robot_pos_final):
robot_com_pos_init = np.mean(robot_pos_init, axis=1)
robot_com_pos_final = np.mean(robot_pos_final, axis=1)
reward = (robot_com_pos_final[0] - robot_com_pos_init[0])
return reward
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
robot_ort = self.object_orientation_at_time(self.get_time(), "robot")
obs = np.concatenate((
self.get_vel_com_obs("robot"),
np.array([robot_ort]),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
return obs, {}
class StepsUp(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'UpStepper-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
np.array([robot_ort_final]),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
#error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
#check termination conditions
com_pos = np.mean(robot_pos_final, axis=1)
if com_pos[0] > (69)*self.VOXEL_SIZE:
done = True
reward += 2.0
if robot_ort_final > (math.pi/2 - math.pi/12) and robot_ort_final < (3*math.pi/2 + math.pi/12):
done = True
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class StepsDown(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'DownStepper-v0.json'))
self.world.add_from_array('robot', body, 1, 11, connections=connections)
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
np.array([robot_ort_final]),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check termination conditions
com_pos = np.mean(robot_pos_final, axis=1)
if com_pos[0] > (74)*self.VOXEL_SIZE:
done = True
reward += 2.0
if robot_ort_final > math.pi/2 and robot_ort_final < 3*math.pi/2:
done = True
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class WalkingBumpy(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'ObstacleTraverser-v0.json'))
self.world.add_from_array('robot', body, 2, 1, connections=connections)
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
np.array([robot_ort_final]),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check termination condition
com_pos = np.mean(robot_pos_final, axis=1)
if com_pos[0] > (79)*self.VOXEL_SIZE:
done = True
reward += 2.0
if robot_ort_final > math.pi/2 and robot_ort_final < 3*math.pi/2:
done = True
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class WalkingBumpy2(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'ObstacleTraverser-v1.json'))
self.world.add_from_array('robot', body, 2, 4, connections=connections)
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check termination condition
com_pos = np.mean(robot_pos_final, axis=1)
if com_pos[0] > (59)*self.VOXEL_SIZE:
done = True
reward += 2.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class VerticalBarrier(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Hurdler-v0.json'))
self.world.add_from_array('robot', body, 2, 4, connections=connections)
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["ground"], self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
if robot_ort_final > math.pi/2 and robot_ort_final < 3*math.pi/2:
done = True
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
class FloatingPlatform(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'PlatformJumper-v0.json'))
self.world.add_from_array('robot', body, 1, 6, connections=connections)
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
# terrain
self.terrain_list = ["platform_1", "platform_2", "platform_3", "platform_4", "platform_5", "platform_6", "platform_7"]
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", self.terrain_list, self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check if y coordinate is below lowest platform
com = np.mean(robot_pos_final, 1)
if com[1] < 0.4: # force stop
reward -= 3.0
done = True
if robot_ort_final > math.pi/2 and robot_ort_final < 3*math.pi/2:
done = True
reward -= 3.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
EvoGymBase.reset(self, seed=seed, options=options)
# observation
robot_ort = self.object_orientation_at_time(self.get_time(), "robot")
obs = np.concatenate((
self.get_vel_com_obs("robot"),
np.array([robot_ort]),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", self.terrain_list, self.sight_dist),
))
return obs, {}
class Gaps(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'GapJumper-v0.json'))
self.world.add_from_array('robot', body, 1, 6, connections=connections)
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
# terrain
self.terrain_list = ["platform_1", "platform_2", "platform_3", "platform_4", "platform_5"]
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", self.terrain_list, self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check if y coordinate is below lowest platform
com = np.mean(robot_pos_final, 1)
if com[1] < (4)*self.VOXEL_SIZE:
reward -= 3.0
done = True
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
EvoGymBase.reset(self, seed=seed, options=options)
# observation
robot_ort = self.object_orientation_at_time(self.get_time(), "robot")
obs = np.concatenate((
self.get_vel_com_obs("robot"),
np.array([robot_ort]),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", self.terrain_list, self.sight_dist),
))
return obs, {}
class BlockSoup(StairsBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Traverser-v0.json'))
self.world.add_from_array('robot', body, 1, 9, connections=connections)
self.blocks = [
[20, 1, 3],
[24, 1, 3],
[27, 1, 2],
[31, 1, 3],
[34, 1, 3],
[38, 1, 2],
[41, 1, 3],
[45, 1, 3],
[21, 4, 3],
[24, 4, 2],
[26, 4, 1],
[29, 4, 2],
[31, 4, 3],
[34, 4, 2],
[36, 4, 2],
[40, 4, 3],
[43, 4, 2],
[46, 4, 3],
]
for i in range(20, 45, 3):
self.blocks.append([i, 7, 2])
count = 0
self.terrain_list = ["ground"]
for x, y, size in self.blocks:
temp_obj = WorldObject.from_json(os.path.join(self.DATA_PATH, f'rigid_{size}x{size}.json'))
temp_obj.set_pos(x, y)
temp_obj.rename(f'block_{count}')
self.world.add_object(temp_obj)
self.terrain_list.append(f'block_{count}')
count += 1
# init sim
StairsBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(3 + num_robot_points + (2*self.sight_dist +1),), dtype=float)
def step(self, action):
# collect pre step information
robot_pos_init = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
robot_pos_final = self.object_pos_at_time(self.get_time(), "robot")
robot_ort_final = self.object_orientation_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", self.terrain_list, self.sight_dist),
))
# compute reward
reward = super().get_reward(robot_pos_init, robot_pos_final)
#error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check termination conditions
com_pos = np.mean(robot_pos_final, axis=1)
if com_pos[0] > (59)*self.VOXEL_SIZE:
done = True
reward += 2.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
robot_ort = self.object_orientation_at_time(self.get_time(), "robot")
obs = np.concatenate((
self.get_vel_com_obs("robot"),
np.array([robot_ort]),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", self.terrain_list, self.sight_dist),
))
return obs, {}
================================================
FILE: evogym/envs/walk.py
================================================
import gymnasium as gym
from gymnasium import error, spaces
from gymnasium import utils
from gymnasium.utils import seeding
from typing import Optional, Dict, Any
from evogym import *
from evogym.envs import BenchmarkBase
import random
import math
import numpy as np
import os
class WalkingFlat(BenchmarkBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'Walker-v0.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)
# init sim
BenchmarkBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(2 + num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
))
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (com_2[0] - com_1[0])
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check goal met
if com_2[0] > 99*self.VOXEL_SIZE:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
class SoftBridge(BenchmarkBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'BridgeWalker-v0.json'))
self.world.add_from_array('robot', body, 2, 5, connections=connections)
# init sim
BenchmarkBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(2 + 1 + num_robot_points,), dtype=float)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
))
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (com_2[0] - com_1[0])
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check goal met
if com_2[0] > (60)*self.VOXEL_SIZE:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_ort_obs("robot"),
self.get_relative_pos_obs("robot"),
))
return obs, {}
class Duck(BenchmarkBase):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):
# make world
self.world = EvoWorld.from_json(os.path.join(self.DATA_PATH, 'CaveCrawler-v0.json'))
self.world.add_from_array('robot', body, 1, 2, connections=connections)
# init sim
BenchmarkBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)
# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
num_robot_points = self.object_pos_at_time(self.get_time(), "robot").size
self.sight_dist = 5
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(2 + num_robot_points + 2*(self.sight_dist*2 +1),), dtype=float)
def step(self, action):
# collect pre step information
pos_1 = self.object_pos_at_time(self.get_time(), "robot")
# step
done = super().step({'robot': action})
# collect post step information
pos_2 = self.object_pos_at_time(self.get_time(), "robot")
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["terrain"], self.sight_dist),
self.get_ceil_obs("robot", ["terrain"], self.sight_dist),
))
# compute reward
com_1 = np.mean(pos_1, 1)
com_2 = np.mean(pos_2, 1)
reward = (com_2[0] - com_1[0])
# error check unstable simulation
if done:
print("SIMULATION UNSTABLE... TERMINATING")
reward -= 3.0
# check goal met
if com_2[0] > (69)*self.VOXEL_SIZE:
done = True
reward += 1.0
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:
super().reset(seed=seed, options=options)
# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
self.get_floor_obs("robot", ["terrain"], self.sight_dist),
self.get_ceil_obs("robot", ["terrain"], self.sight_dist),
))
return obs, {}
================================================
FILE: evogym/sim.py
================================================
#!/usr/bin/env python
"""
This module defines the EvoSim class which provides a clean interface to Evolution Gym's simulator.
"""
from typing import Dict, Set
import numpy as np
from evogym.world import EvoWorld
from evogym.utils import *
from evogym.simulator_cpp import Sim
### TODO: Add documentation for current_time() and step()
class EvoSim(Sim):
"""
Create, step, reset, and get data from an Evolution Gym simulation.
Args:
world (EvoWorld): object containing world voxel specification.
"""
_has_displayed_version = False
VOXEL_SIZE = 0.1
def __init__(self, world: EvoWorld) -> None:
if not EvoSim._has_displayed_version:
Sim.get_version()
EvoSim._has_displayed_version = True
super().__init__()
self.init(world.grid_size.x, world.grid_size.y)
self._object_names: Set[str] = set()
self._robot_name_to_actuator_indices: Dict[str, np.ndarray] = {}
self._init_world_items(world)
def _init_world_items(self, world: EvoWorld) -> None:
"""
Initializes simulation from world voxel data.
Args:
world (EvoWorld): object containing world voxel specification.
"""
# sort objects for consistency
names_ordered_tup = []
for name, obj in world.objects.items():
#is robot
if np.sum(obj.grid == VOXEL_TYPES['V_ACT']) + np.sum(
obj.grid == VOXEL_TYPES['H_ACT']) > 0:
names_ordered_tup.append((0, name))
else:
names_ordered_tup.append((1, name))
names_ordered_tup = sorted(names_ordered_tup)
names_ordered = [name for (is_robot_value, name) in names_ordered_tup]
# loads objects into sim
for name in names_ordered:
obj = world.objects[name]
structure = np.flipud(obj.grid)
is_robot = False
if np.sum(obj.grid == VOXEL_TYPES['V_ACT']) + np.sum(
obj.grid == VOXEL_TYPES['H_ACT']) > 0:
is_robot = True
connections = []
for y in range(obj.grid_size.y):
for x in range(obj.grid_size.x):
if obj.grid[y][x] != VOXEL_TYPES['EMPTY'] and Pair(x, y) in obj.neighbors:
for nei in obj.neighbors[Pair(x, y)]:
oy = (obj.grid_size.y - 1) - y
nei_oy = (obj.grid_size.y - 1) - nei.y
connections.append([
oy * obj.grid_size.x + x,
nei_oy * obj.grid_size.x + nei.x
])
connections_numpy = np.array(connections).T
if len(connections_numpy) == 0:
connections_numpy = np.empty((2, 1))
if is_robot:
self.read_robot_from_array(structure, connections_numpy, obj.name,
obj.pos.x, obj.pos.y)
self._robot_name_to_actuator_indices[
obj.name] = self.get_indices_of_actuators(obj.name).flatten()
else:
self.read_object_from_array(structure, connections_numpy, obj.name,
obj.pos.x, obj.pos.y)
self._object_names.add(obj.name)
def get_actuator_indices(self, robot_name: str) -> np.ndarray:
"""
Returns the voxel indices a target robot's actuators in the simulation.
Args:
robot_name (str): name of robot.
Returns:
np.ndarray: `(n,)` array of actuator indices, where `n` is the number of actuators.
"""
self._check_valid_robot_name(robot_name)
return self._robot_name_to_actuator_indices[robot_name].copy()
def get_dim_action_space(self, robot_name: str) -> int:
"""
Returns the number of actuators for a target robot in the simulation.
Args:
robot_name (str): name of robot.
Returns:
int: number of actuators.
"""
self._check_valid_robot_name(robot_name)
return len(self._robot_name_to_actuator_indices[robot_name])
def set_action(self, robot_name: str, action: np.ndarray) -> None:
"""
Set an action for a target robot. This function updates the robot's actuator targets, but will not step the simulation.
Args:
robot_name (str): name of robot
action (np.ndarray): `(n,)` array of actions, where `n` is the number of actuators of the target robot.
"""
self._check_valid_robot_name(robot_name)
indices = self._robot_name_to_actuator_indices[robot_name].copy()
if indices.shape != action.flatten().shape:
raise ValueError(
f'expected action with {len(indices)} values but got action with {len(action.flatten())} values for {robot_name}'
)
informative_action = np.stack((indices, action.flatten()), axis=1)
super().set_action(robot_name, informative_action)
def _check_valid_time(self, time: int) -> None:
"""
Throws an error if `time` is invalid.
Args:
time (int): time to check.
"""
if not isinstance(time, int):
raise TypeError(f'time {time} is not of type int')
if time < 0 or time > super().get_time():
raise ValueError(f'time {time} is outside valid range [{0}, {super().get_time()}]')
def _check_valid_robot_name(self, robot_name: str) -> None:
"""
Throws an error if no robot by the name 'robot_name' has been loaded into the simulation.
Args:
robot_name (str): name of robot to check.
"""
if robot_name not in self._robot_name_to_actuator_indices:
raise ValueError(f'{robot_name} is not a valid robot name')
def _check_valid_object_name(self, object_name: str) -> None:
"""
Throws an error if no object by the name 'object_name' has been loaded into the simulation.
Args:
object_name (str): object to check.
"""
if object_name not in self._object_names:
raise ValueError(f'{object_name} is not a valid object name')
def pos_at_time(self, time: int) -> np.ndarray:
"""
Returns positions of all point-masses in the simulation at time `time`. Use `EvoSim.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of points in the simulation.
"""
self._check_valid_time(time)
return super().pos_at_time(time)/self.VOXEL_SIZE
def vel_at_time(self, time: int) -> np.ndarray:
"""
Returns velocities of all point-masses in the simulation at time `time`. Use `EvoSim.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of points in the simulation.
"""
self._check_valid_time(time)
return super().vel_at_time(time)/self.VOXEL_SIZE
def object_pos_at_time(self, time: int, object_name: str) -> np.ndarray:
"""
Returns positions of all point-masses in a target object at time `time`. Use `EvoSim.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
object_name (str): name of object
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of point-masses in the target object.
"""
self._check_valid_time(time)
self._check_valid_object_name(object_name)
return super().object_pos_at_time(time, object_name)/self.VOXEL_SIZE
def object_vel_at_time(self, time: int, object_name: str) -> np.ndarray:
"""
Returns velocities of all point-masses in a target object at time `time`. Use `EvoSim.get_time()` to get current measurements.
Args:
time (int): time at which to return measurements.
object_name (str): name of object
Returns:
np.ndarray: `(2, n)` array of measurements, where `n` is the number of point-masses in the target object.
"""
self._check_valid_time(time)
self._check_valid_object_name(object_name)
return super().object_vel_at_time(time, object_name)/self.VOXEL_SIZE
def object_orientation_at_time(self, time: int, object_name: str) -> float:
"""
Returns an estimate of the orientation of an object at time `time`. Use `EvoSim.get_time()` to get current measurements.
Args:
time (int): time at which to return measurement.
object_name (str): name of object
Returns:
float: orientation with respect to x-axis in radians (increasing counter-clockwise) from the range [0, 2π].
"""
self._check_valid_time(time)
self._check_valid_object_name(object_name)
return super().object_orientation_at_time(time, object_name)
def reset(self,) -> None:
"""
Reset the simulation to time `0`.
"""
self.revert(0)
================================================
FILE: evogym/simulator/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.1.0)
set(CMAKE_SUPPRESS_REGENERATION true)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
project(simulator_cpp)
# Enable C++ 11
set(CMAKE_CXX_STANDARD 11)
# Suppress warnings.
add_definitions(
-D_CRT_SECURE_NO_WARNINGS
)
if(UNIX)
set(GCC_COVERAGE_COMPILE_FLAGS "-Wno-format")
add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
endif()
if(UNIX)
find_package(OpenGL REQUIRED)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) # use custom FindGLEW.cmake
set(GLEW_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/externals/glew/include)
set(GLEW_LIBRARY ${PROJECT_SOURCE_DIR}/externals/glew/lib/libGLEW.*)
find_package(GLEW REQUIRED)
endif()
set(EXTERNAL_ROOT ${PROJECT_SOURCE_DIR}/externals)
add_subdirectory(${EXTERNAL_ROOT})
get_directory_property(EXTERNAL_HEADER
DIRECTORY ${EXTERNAL_ROOT}
DEFINITION EXTERNAL_HEADER)
# Expose PROJECT_DIR to the source code.
add_definitions(-DPROJECT_DIR="${PROJECT_SOURCE_DIR}")
add_definitions(-DGRAPHICS_CODEBASE_SOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}")
include_directories(${EXTERNAL_HEADER})
add_definitions(
-DTW_STATIC
-DTW_NO_LIB_PRAGMA
-DTW_NO_DIRECT3D
-DGLEW_STATIC
-D_CRT_SECURE_NO_WARNINGS
)
add_subdirectory(SimulatorCPP/)
set(CMAKE_CXX_STANDARD_LIBRARIES -ldl)
# set(CMAKE_VERBOSE_MAKEFILE ON)
================================================
FILE: evogym/simulator/FindGLEW.cmake
================================================
# FindGLEW.cmake
# Search for GLEW library and include directories
find_path(GLEW_INCLUDE_DIR GL/glew.h)
find_library(GLEW_LIBRARY NAMES GLEW GLEW32)
if (GLEW_INCLUDE_DIR AND GLEW_LIBRARY)
set(GLEW_FOUND TRUE)
else()
set(GLEW_FOUND FALSE)
endif()
if (GLEW_FOUND)
if (NOT GLEW_FIND_QUIETLY)
message(STATUS "Found GLEW: ${GLEW_LIBRARY}")
endif ()
else()
if (GLEW_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find GLEW")
endif ()
endif()
mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY)
================================================
FILE: evogym/simulator/SimulatorCPP/BBTreeNode.cpp
================================================
#include "BBTreeNode.h"
BBTreeNode::BBTreeNode()
{
}
BBTreeNode::BBTreeNode(int a_index, int b_index) {
BBTreeNode::a_index = a_index;
BBTreeNode::b_index = b_index;
BBTreeNode::is_leaf = false;
BBTreeNode::is_finished = false;
}
BBTreeNode::BBTreeNode(int boxel_index) {
BBTreeNode::boxel_index = boxel_index;
BBTreeNode::is_leaf = true;
BBTreeNode::is_finished = false;
}
BBTreeNode::~BBTreeNode()
{
}
================================================
FILE: evogym/simulator/SimulatorCPP/BBTreeNode.h
================================================
#ifndef BB_TREE_NODE_H
#define BB_TREE_NODE_H
#include "main.h"
#include