diff --git a/.github/workflows/predicators.yml b/.github/workflows/predicators.yml index 19627c853b..f6e744ae6c 100644 --- a/.github/workflows/predicators.yml +++ b/.github/workflows/predicators.yml @@ -18,7 +18,7 @@ jobs: cache-dependency-path: '**/setup.py' - run: | pip install -e . - pip install pytest-cov + pip install pytest-cov==2.12.1 - name: Pytest run: | pytest -s tests/ --cov-config=.coveragerc --cov=predicators/ --cov=tests/ --cov-fail-under=100 --cov-report=term-missing:skip-covered @@ -61,13 +61,13 @@ jobs: - name: Install dependencies run: | pip install -e . - pip install pytest-pylint + pip install pytest-pylint==0.18.0 - name: Pylint run: | pytest . --pylint -m pylint --pylint-rcfile=.predicators_pylintrc env: PYTHONHASHSEED: 0 - autoformat: + yapf: runs-on: ubuntu-latest strategy: matrix: @@ -80,9 +80,56 @@ jobs: python-version: ${{ matrix.python-version }} cache: 'pip' cache-dependency-path: '**/setup.py' - - name: Run YAPF to test if python code is correctly formatted - uses: AlexanderMelde/yapf-action@master + - name: Install dependencies + run: | + pip install yapf==0.32.0 + - name: Run yapf to detect any autoformatting changes + run: | + yapf --diff -r --style .style.yapf --exclude '**/third_party' predicators + yapf --diff -r --style .style.yapf scripts + yapf --diff -r --style .style.yapf tests + yapf --diff -r --style .style.yapf setup.py + env: + PYTHONHASHSEED: 0 + isort: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.8] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: '**/setup.py' + - name: Install dependencies + run: | + pip install isort==5.10.1 + - name: Run isort to detect any changes + run: | + isort --check-only . + env: + PYTHONHASHSEED: 0 + docformatter: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.8] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 with: - args: --verbose --style .style.yapf --exclude '**/third_party' - - name: Run isort to organize imports - uses: isort/isort-action@master \ No newline at end of file + python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: '**/setup.py' + - name: Install dependencies + run: | + pip install docformatter==1.4 + - name: Run docformatter to detect any autoformatting changes + run: | + docformatter --check -r . --exclude venv predicators/third_party + env: + PYTHONHASHSEED: 0 diff --git a/mypy.ini b/mypy.ini index 3d05235c38..d1692d9b5d 100644 --- a/mypy.ini +++ b/mypy.ini @@ -83,5 +83,11 @@ ignore_missing_imports = True [mypy-panda_robot_client.*] ignore_missing_imports = True +[mypy-gym.*] +ignore_missing_imports = True + +[mypy-gym_sokoban.*] +ignore_missing_imports = True + [mypy-tqdm.*] ignore_missing_imports = True diff --git a/predicators/pybullet_helpers/motion_planning.py b/predicators/pybullet_helpers/motion_planning.py index 2248db9db6..c449d0edf8 100644 --- a/predicators/pybullet_helpers/motion_planning.py +++ b/predicators/pybullet_helpers/motion_planning.py @@ -13,10 +13,13 @@ def run_motion_planning( - robot: SingleArmPyBulletRobot, initial_positions: JointPositions, - target_positions: JointPositions, collision_bodies: Collection[int], - seed: int, - physics_client_id: int) -> Optional[Sequence[JointPositions]]: + robot: SingleArmPyBulletRobot, + initial_positions: JointPositions, + target_positions: JointPositions, + collision_bodies: Collection[int], + seed: int, + physics_client_id: int, +) -> Optional[Sequence[JointPositions]]: """Run BiRRT to find a collision-free sequence of joint positions. Note that this function changes the state of the robot. @@ -24,9 +27,18 @@ def run_motion_planning( rng = np.random.default_rng(seed) joint_space = robot.action_space joint_space.seed(seed) - _sample_fn = lambda _: joint_space.sample() num_interp = CFG.pybullet_birrt_extend_num_interp + def _sample_fn(pt: JointPositions) -> JointPositions: + new_pt: JointPositions = list(joint_space.sample()) + # Don't change the fingers. + new_pt[robot.left_finger_joint_idx] = pt[robot.left_finger_joint_idx] + new_pt[robot.right_finger_joint_idx] = pt[robot.right_finger_joint_idx] + return new_pt + + def _set_state(pt: JointPositions) -> None: + robot.set_joints(pt) + def _extend_fn(pt1: JointPositions, pt2: JointPositions) -> Iterator[JointPositions]: pt1_arr = np.array(pt1) @@ -38,7 +50,7 @@ def _extend_fn(pt1: JointPositions, yield list(pt1_arr * (1 - i / num) + pt2_arr * i / num) def _collision_fn(pt: JointPositions) -> bool: - robot.set_joints(pt) + _set_state(pt) p.performCollisionDetection(physicsClientId=physics_client_id) for body in collision_bodies: if p.getContactPoints(robot.robot_id, @@ -48,6 +60,8 @@ def _collision_fn(pt: JointPositions) -> bool: return False def _distance_fn(from_pt: JointPositions, to_pt: JointPositions) -> float: + # NOTE: only using positions to calculate distance. Should use + # orientations as well in the near future. from_ee = robot.forward_kinematics(from_pt) to_ee = robot.forward_kinematics(to_pt) return sum(np.subtract(from_ee, to_ee)**2) diff --git a/scripts/analyze_results_directory.py b/scripts/analyze_results_directory.py index 5e326f793b..9d29aa3471 100644 --- a/scripts/analyze_results_directory.py +++ b/scripts/analyze_results_directory.py @@ -49,7 +49,7 @@ ] -def _compute_percentage_tasks_solved(d: pd.DataFrame) -> pd.DataFrame: +def _compute_percentage_tasks_solved(d: Dict[str, float]) -> float: try: ret_df = (d["num_solved"] / d["num_test_tasks"]) * 100 except ZeroDivisionError: diff --git a/setup.py b/setup.py index 624098d56d..ffb57c0db2 100644 --- a/setup.py +++ b/setup.py @@ -3,26 +3,48 @@ # NOTE: Windows users will have to install windows-curses # (https://pypi.org/project/windows-curses/) -setup(name="predicators", - version="0.1.0", - packages=find_packages(include=["predicators", "predicators.*"]), - install_requires=[ - "numpy>=1.22.3", "pytest", "gym==0.21.0", "matplotlib", "imageio", - "imageio-ffmpeg", "pandas", "torch", "scipy", "tabulate", "dill", - "pyperplan", "pathos", "requests", "slack_bolt", "pybullet>=3.2.0", - "scikit-learn", "graphlib-backport", "openai", "pyyaml", - "pylint==2.14.5", "types-PyYAML", "lisdf", "seaborn", - "smepy@git+https://github.com/sebdumancic/structure_mapping.git" - ], - include_package_data=True, - extras_require={ - "develop": [ - "pytest-cov>=2.12.1", - "pytest-pylint>=0.18.0", - "yapf==0.32.0", - "docformatter", - "isort", - "mypy@git+https://github.com/python/mypy.git@9bd651758e8ea2494" + - "837814092af70f8d9e6f7a1", - ] - }) +setup( + name="predicators", + version="0.1.0", + packages=find_packages(include=["predicators", "predicators.*"]), + install_requires=[ + "numpy>=1.22.3", + "pytest", + "gym==0.26.2", + "matplotlib", + "imageio", + "imageio-ffmpeg", + "pandas", + "torch", + "scipy", + "tabulate", + "dill", + "pyperplan", + "pathos", + "requests", + "slack_bolt", + "pybullet>=3.2.0", + "scikit-learn", + "graphlib-backport", + "openai", + "pyyaml", + "pylint==2.14.5", + "types-PyYAML", + "lisdf", + "seaborn", + "smepy@git+https://github.com/sebdumancic/structure_mapping.git", + "pg3@git+https://github.com/tomsilver/pg3.git", + "gym_sokoban@git+https://github.com/Learning-and-Intelligent-Systems/gym-sokoban.git" # pylint: disable=line-too-long + ], + include_package_data=True, + extras_require={ + "develop": [ + "pytest-cov==2.12.1", + "pytest-pylint==0.18.0", + "yapf==0.32.0", + "docformatter==1.4", + "isort==5.10.1", + "mypy@git+https://github.com/python/mypy.git@9bd651758e8ea2494" + + "837814092af70f8d9e6f7a1", + ] + }) diff --git a/tests/approaches/test_random_actions_approach.py b/tests/approaches/test_random_actions_approach.py index 9269051d83..4c73be12cc 100644 --- a/tests/approaches/test_random_actions_approach.py +++ b/tests/approaches/test_random_actions_approach.py @@ -25,4 +25,4 @@ def test_random_actions_approach(): actions.append(act) assert env.action_space.contains(act.arr) # Test reproducibility - assert str(actions) == "[Action(_arr=array([0.70787615], dtype=float32)), Action(_arr=array([0.3698764], dtype=float32)), Action(_arr=array([0.29010695], dtype=float32)), Action(_arr=array([0.10647454], dtype=float32)), Action(_arr=array([0.9975787], dtype=float32)), Action(_arr=array([0.9942262], dtype=float32)), Action(_arr=array([0.98252517], dtype=float32)), Action(_arr=array([0.55868745], dtype=float32)), Action(_arr=array([0.68523175], dtype=float32)), Action(_arr=array([0.99104315], dtype=float32))]" # pylint: disable=line-too-long + assert str(actions) == "[Action(_arr=array([0.6823519], dtype=float32)), Action(_arr=array([0.05382102], dtype=float32)), Action(_arr=array([0.22035988], dtype=float32)), Action(_arr=array([0.18437181], dtype=float32)), Action(_arr=array([0.1759059], dtype=float32)), Action(_arr=array([0.8120945], dtype=float32)), Action(_arr=array([0.92334497], dtype=float32)), Action(_arr=array([0.2765744], dtype=float32)), Action(_arr=array([0.81975454], dtype=float32)), Action(_arr=array([0.8898927], dtype=float32))]" # pylint: disable=line-too-long diff --git a/tests/approaches/test_random_options_approach.py b/tests/approaches/test_random_options_approach.py index a76272e85d..d9213a13d1 100644 --- a/tests/approaches/test_random_options_approach.py +++ b/tests/approaches/test_random_options_approach.py @@ -49,7 +49,7 @@ def _solved_classifier(s, o): policy = approach.solve(task, 500) solved = False act_var = None - for _ in range(10): + for _ in range(25): act = policy(state) assert act.has_option() if act_var is None: @@ -111,4 +111,4 @@ def _solved_classifier(s, o): act_var = act.arr.item() state = _simulator(state, act) # Test reproducibility - assert str(actions) == "[Action(_arr=array([0.70787615], dtype=float32)), Action(_arr=array([0.3698764], dtype=float32)), Action(_arr=array([0.29010695], dtype=float32)), Action(_arr=array([0.9975787], dtype=float32)), Action(_arr=array([0.9942262], dtype=float32)), Action(_arr=array([0.98252517], dtype=float32)), Action(_arr=array([0.55868745], dtype=float32)), Action(_arr=array([0.68523175], dtype=float32)), Action(_arr=array([0.99104315], dtype=float32)), Action(_arr=array([0.8620031], dtype=float32))]" # pylint: disable=line-too-long + assert str(actions) == "[Action(_arr=array([0.6823519], dtype=float32)), Action(_arr=array([0.8120945], dtype=float32)), Action(_arr=array([0.92334497], dtype=float32)), Action(_arr=array([0.2765744], dtype=float32)), Action(_arr=array([0.81975454], dtype=float32)), Action(_arr=array([0.8898927], dtype=float32)), Action(_arr=array([0.51297045], dtype=float32)), Action(_arr=array([0.8242416], dtype=float32)), Action(_arr=array([0.74146706], dtype=float32)), Action(_arr=array([0.6299402], dtype=float32))]" # pylint: disable=line-too-long