diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 203f3c8..4ad7bd5 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,4 +3,4 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "weekly" + interval: "monthly" diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 9a799d4..edbfe30 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -17,7 +17,7 @@ jobs: runs-on: "${{ matrix.os }}-latest" strategy: matrix: - os: [ubuntu, macos] + os: [ubuntu] steps: - uses: actions/checkout@v5 - uses: cachix/install-nix-action@v31 @@ -26,6 +26,7 @@ jobs: name: gepetto authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: nix flake check -L + - run: nix build -L check: if: always() name: check-macos-linux-nix diff --git a/.github/workflows/update-flake-lock.yml b/.github/workflows/update-flake-lock.yml index 3c183c9..20d06aa 100644 --- a/.github/workflows/update-flake-lock.yml +++ b/.github/workflows/update-flake-lock.yml @@ -6,14 +6,28 @@ on: - cron: '0 18 1 * *' jobs: - lockfile: - runs-on: ubuntu-latest + update-flake-inputs: + runs-on: ubuntu-slim + permissions: + contents: write + pull-requests: write steps: + - name: Generate GitHub App Token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.GEPETTO_NIX_APP_ID }} + private-key: ${{ secrets.GEPETTO_NIX_APP_PRIVATE_KEY }} - name: Checkout repository - uses: actions/checkout@v4 - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main + uses: actions/checkout@v6 + with: + token: ${{ steps.app-token.outputs.token }} + - name: Setup Nix + uses: cachix/install-nix-action@v31 + - name: Update flake inputs + uses: mic92/update-flake-inputs@v1 with: - token: ${{ secrets.GH_TOKEN_FOR_UPDATES }} + github-token: ${{ steps.app-token.outputs.token }} + pr-labels: 'no-changelog' + git-author-name: 'hrp2-14' + git-author-email: '40568249+hrp2-14@users.noreply.github.com' diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2b7a4fe..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "cmake"] - path = cmake - url = https://github.com/jrl-umi3218/jrl-cmakemodules.git diff --git a/.mergify.yml b/.mergify.yml index 1e2dd5a..8ece7ea 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -5,6 +5,7 @@ pull_request_rules: - check-success = "pre-commit.ci - pr" - or: - author = dependabot[bot] + - author = gepetto-flake-updater[bot] - author = github-actions[bot] - author = hrp2-14 - author = pre-commit-ci[bot] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 416f304..3c0cdb0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,8 +1,8 @@ ci: - autoupdate_branch: devel + autoupdate_schedule: quarterly repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.1 + rev: v0.15.5 hooks: - id: ruff args: @@ -19,7 +19,7 @@ repos: - id: toml-sort-fix exclude: poetry.lock - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v21.1.2 + rev: v22.1.0 hooks: - id: clang-format args: diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f5fb78..557d885 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ install( urdf/cup.urdf urdf/door.urdf urdf/kitchen_area.urdf + urdf/kitchen_area_obstacle.urdf urdf/box_color.urdf urdf/rod.urdf urdf/table.urdf diff --git a/cmake b/cmake deleted file mode 160000 index c815b3b..0000000 --- a/cmake +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c815b3ba45fa8b7cf4b7a21b69b26ad0bc04fd5c diff --git a/flake.lock b/flake.lock index 851d4ba..a1c93df 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1760813311, - "narHash": "sha256-lbHQ7FXGzt6/IygWvJ1lCq+Txcut3xYYd6VIpF1ojkg=", + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "4e627ac2e1b8f1de7f5090064242de9a259dbbc8", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", "type": "github" }, "original": { @@ -36,37 +36,82 @@ "type": "github" } }, - "gepetto": { + "gazebros2nix": { "inputs": { "flake-parts": "flake-parts", + "gepetto-lib": "gepetto-lib", "nix-ros-overlay": "nix-ros-overlay", - "nix-system-graphics": "nix-system-graphics", "nixpkgs": [ "gepetto", + "gazebros2nix", + "nix-ros-overlay", + "nixpkgs" + ], + "pyproject-build-systems": "pyproject-build-systems", + "pyproject-nix": "pyproject-nix", + "systems": [ + "gepetto", + "gazebros2nix", "nix-ros-overlay", + "flake-utils", + "systems" + ], + "treefmt-nix": "treefmt-nix", + "uv2nix": "uv2nix" + }, + "locked": { + "lastModified": 1772816781, + "narHash": "sha256-Ac0KEl+8ygy+BnDgczNHgTumw8HpCasp/zJU5Yx3kQs=", + "owner": "gepetto", + "repo": "gazebros2nix", + "rev": "ea8aff2fca6d45fa85fe5e90ef3c71fe0fcc0d12", + "type": "github" + }, + "original": { + "owner": "gepetto", + "repo": "gazebros2nix", + "type": "github" + } + }, + "gepetto": { + "inputs": { + "flake-parts": [ + "gepetto", + "gazebros2nix", + "flake-parts" + ], + "gazebros2nix": "gazebros2nix", + "nix-ros-overlay": [ + "gepetto", + "gazebros2nix", + "nix-ros-overlay" + ], + "nix-system-graphics": "nix-system-graphics", + "nixpkgs": [ + "gepetto", + "gazebros2nix", "nixpkgs" ], - "src-agimus-controller": "src-agimus-controller", - "src-agimus-msgs": "src-agimus-msgs", - "src-franka-description": "src-franka-description", - "src-gepetto-viewer": "src-gepetto-viewer", "src-odri-control-interface": "src-odri-control-interface", "src-odri-masterboard-sdk": "src-odri-masterboard-sdk", "system-manager": "system-manager", "systems": [ "gepetto", - "nix-ros-overlay", - "flake-utils", + "gazebros2nix", "systems" ], - "treefmt-nix": "treefmt-nix" + "treefmt-nix": [ + "gepetto", + "gazebros2nix", + "treefmt-nix" + ] }, "locked": { - "lastModified": 1760912477, - "narHash": "sha256-f13hr5lblgh/1L902D5inme4jrxIUa5CNMoJrJ5CAbY=", + "lastModified": 1772825496, + "narHash": "sha256-ZCgGWufV1suEVlft03k9TGOD190kGRCA3rrO8qsjeQ0=", "owner": "gepetto", "repo": "nix", - "rev": "5b37aa4185cd3797bd024b88b3a4b6c78a50a032", + "rev": "5c1a5edffd02c51e267c42f8dfd36a13c7817950", "type": "github" }, "original": { @@ -75,17 +120,32 @@ "type": "github" } }, + "gepetto-lib": { + "locked": { + "lastModified": 1770945346, + "narHash": "sha256-L88f+oJbpIkMm9Ln1GP9SFyGztMvnOowbdshQHBeGGs=", + "owner": "Gepetto", + "repo": "nix-lib", + "rev": "82ef58cdf50514f6b1fde96b9d5b38fd8d3e83f5", + "type": "github" + }, + "original": { + "owner": "Gepetto", + "repo": "nix-lib", + "type": "github" + } + }, "nix-ros-overlay": { "inputs": { "flake-utils": "flake-utils", "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1760853526, - "narHash": "sha256-oIRhuCXd/uDXcYyb/MZC0uVfMU/PM0OcAda47FfK32s=", + "lastModified": 1771885942, + "narHash": "sha256-TlBFvE4YHNlbhKVkayP/FWBNAAv+yG9APA8vMR+5NBw=", "owner": "lopsided98", "repo": "nix-ros-overlay", - "rev": "e34da327d2988480fc91fa42b703e8c2149ca972", + "rev": "f891b118c8f4ddb2b6f38d6ce1bfe2f8079552ba", "type": "github" }, "original": { @@ -103,11 +163,11 @@ ] }, "locked": { - "lastModified": 1737457219, - "narHash": "sha256-nX9dxoATDCSQgWw/iv6BngXDJEyHVYYEvHEVQ7Ig3fI=", + "lastModified": 1763296639, + "narHash": "sha256-K9JBscC7ApwCnl0wR0sVkxrKFsoDYVqXN5fOujvyBWA=", "owner": "soupglasses", "repo": "nix-system-graphics", - "rev": "9c875e0c56cf2eb272b9102a4f3e24e4e31629fd", + "rev": "ac37f0f3ec0cb15d63a520918433c794d01d9dac", "type": "github" }, "original": { @@ -134,11 +194,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1754788789, - "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", + "lastModified": 1769909678, + "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", + "rev": "72716169fe93074c333e8d0173151350670b824c", "type": "github" }, "original": { @@ -147,94 +207,87 @@ "type": "github" } }, - "root": { + "pyproject-build-systems": { "inputs": { - "flake-parts": [ - "gepetto", - "flake-parts" - ], - "gepetto": "gepetto", - "nix-ros-overlay": [ - "gepetto", - "nix-ros-overlay" - ], "nixpkgs": [ "gepetto", + "gazebros2nix", "nixpkgs" ], - "systems": [ + "pyproject-nix": [ "gepetto", - "systems" + "gazebros2nix", + "pyproject-nix" ], - "treefmt-nix": [ + "uv2nix": [ "gepetto", - "treefmt-nix" + "gazebros2nix", + "uv2nix" ] - } - }, - "src-agimus-controller": { - "flake": false, - "locked": { - "lastModified": 1760697732, - "narHash": "sha256-7qnvv4VgLcpSFzsvKsbHJBsM+FZE1yhzYZknhVg7FuY=", - "owner": "agimus-project", - "repo": "agimus_controller", - "rev": "f37cd913920d81613ebbc0c75937705ce1f6c280", - "type": "github" }, - "original": { - "owner": "agimus-project", - "repo": "agimus_controller", - "type": "github" - } - }, - "src-agimus-msgs": { - "flake": false, "locked": { - "lastModified": 1759994370, - "narHash": "sha256-QuYtUR7VTOOtRBrYCxDjSLUP77wh0NlHbMtxZ1nSJFM=", - "owner": "agimus-project", - "repo": "agimus_msgs", - "rev": "e8e48c8c7b942cc2d2feba01f5e2d319c7915816", + "lastModified": 1771423342, + "narHash": "sha256-7uXPiWB0YQ4HNaAqRvVndYL34FEp1ZTwVQHgZmyMtC8=", + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "rev": "04e9c186e01f0830dad3739088070e4c551191a4", "type": "github" }, "original": { - "owner": "agimus-project", - "repo": "agimus_msgs", + "owner": "pyproject-nix", + "repo": "build-system-pkgs", "type": "github" } }, - "src-franka-description": { - "flake": false, + "pyproject-nix": { + "inputs": { + "nixpkgs": [ + "gepetto", + "gazebros2nix", + "nixpkgs" + ] + }, "locked": { - "lastModified": 1759137774, - "narHash": "sha256-D7vkjZ1B9qKecqUCmnpwHcxzZpakvoqp0qAhv4jGwRI=", - "owner": "agimus-project", - "repo": "franka_description", - "rev": "3cad53b368ea19f10ce1248f4fd781abfae1bdc6", + "lastModified": 1771518446, + "narHash": "sha256-nFJSfD89vWTu92KyuJWDoTQJuoDuddkJV3TlOl1cOic=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "eb204c6b3335698dec6c7fc1da0ebc3c6df05937", "type": "github" }, "original": { - "owner": "agimus-project", - "repo": "franka_description", + "owner": "pyproject-nix", + "repo": "pyproject.nix", "type": "github" } }, - "src-gepetto-viewer": { - "flake": false, - "locked": { - "lastModified": 1760391797, - "narHash": "sha256-5aWplS40CWL1GvF4LuLtipRP4TkTLNnOJUVTwzixpHA=", - "owner": "Gepetto", - "repo": "gepetto-viewer", - "rev": "1c942ecf7c755f615dcd43e17101a1f680795b8b", - "type": "github" - }, - "original": { - "owner": "Gepetto", - "ref": "devel", - "repo": "gepetto-viewer", - "type": "github" + "root": { + "inputs": { + "flake-parts": [ + "gepetto", + "flake-parts" + ], + "gazebros2nix": [ + "gepetto", + "gazebros2nix" + ], + "gepetto": "gepetto", + "nix-ros-overlay": [ + "gepetto", + "nix-ros-overlay" + ], + "nixpkgs": [ + "gepetto", + "nixpkgs" + ], + "systems": [ + "gepetto", + "systems" + ], + "treefmt-nix": [ + "gepetto", + "treefmt-nix" + ] } }, "src-odri-control-interface": { @@ -279,11 +332,11 @@ ] }, "locked": { - "lastModified": 1756281415, - "narHash": "sha256-CjpoVwpJJ+DOZilPrDpZ5S3V+B1Y0calaHxTp2xMvGs=", + "lastModified": 1770135975, + "narHash": "sha256-J3qmZ4rTfmgyjrsQRrQWT7ZIYVtYqtLomMNDUibuw2k=", "owner": "numtide", "repo": "system-manager", - "rev": "e271eedac9a24678ca6cfc61677837422bf474e0", + "rev": "413f296fb1fd210c44e38744e270b3afc4c733d7", "type": "github" }, "original": { @@ -311,15 +364,16 @@ "inputs": { "nixpkgs": [ "gepetto", + "gazebros2nix", "nixpkgs" ] }, "locked": { - "lastModified": 1760802554, - "narHash": "sha256-5YkOYOCF8/XNw89/ABKFB0c/P78U2EVuKRDGTql6+kA=", + "lastModified": 1770228511, + "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "296ebf0c3668ebceb3b0bfee55298f112b4b5754", + "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", "type": "github" }, "original": { @@ -327,6 +381,33 @@ "repo": "treefmt-nix", "type": "github" } + }, + "uv2nix": { + "inputs": { + "nixpkgs": [ + "gepetto", + "gazebros2nix", + "nixpkgs" + ], + "pyproject-nix": [ + "gepetto", + "gazebros2nix", + "pyproject-nix" + ] + }, + "locked": { + "lastModified": 1772187362, + "narHash": "sha256-gCojeIlQ/rfWMe3adif3akyHsT95wiMkLURpxTeqmPc=", + "owner": "pyproject-nix", + "repo": "uv2nix", + "rev": "abe65de114300de41614002fe9dce2152ac2ac23", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "uv2nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index e350b14..3bb357d 100644 --- a/flake.nix +++ b/flake.nix @@ -3,6 +3,7 @@ inputs = { gepetto.url = "github:gepetto/nix"; + gazebros2nix.follows = "gepetto/gazebros2nix"; flake-parts.follows = "gepetto/flake-parts"; nixpkgs.follows = "gepetto/nixpkgs"; nix-ros-overlay.follows = "gepetto/nix-ros-overlay"; @@ -12,20 +13,14 @@ outputs = inputs: - inputs.flake-parts.lib.mkFlake { inherit inputs; } { - systems = import inputs.systems; - imports = [ inputs.gepetto.flakeModule ]; - perSystem = - { - lib, - pkgs, - self', - ... - }: - { - packages = { - default = self'.packages.hpp-tutorial; - hpp-tutorial = pkgs.python3Packages.hpp-tutorial.overrideAttrs { + inputs.flake-parts.lib.mkFlake { inherit inputs; } ( + { lib, ... }: + { + systems = import inputs.systems; + imports = [ + inputs.gepetto.flakeModule + { + gazebros2nix.overrides.hpp-tutorial = _final: { src = lib.fileset.toSource { root = ./.; fileset = lib.fileset.unions [ @@ -43,7 +38,8 @@ ]; }; }; - }; - }; - }; + } + ]; + } + ); } diff --git a/script/hpp_python_tutorial_1.py b/script/hpp_python_tutorial_1.py new file mode 100644 index 0000000..5f5d6ef --- /dev/null +++ b/script/hpp_python_tutorial_1.py @@ -0,0 +1,85 @@ +import numpy as np +from pinocchio import SE3 +from pyhpp.core import DiffusingPlanner, Problem, RandomShortcut +from pyhpp.pinocchio import Device, urdf +from pyhpp_viser import Viewer + +urdfFilename = "package://example-robot-data/robots/pr2_description/urdf/pr2.urdf" +srdfFilename = "package://example-robot-data/robots/pr2_description/srdf/pr2.srdf" +rootJointType = "planar" +# Initialize robot and viewer +robot = Device("ur2") + +urdf.loadModel( + robot, 0, "r0", rootJointType, urdfFilename, srdfFilename, SE3.Identity() +) + +# Define initial and goal configurations +q_init = np.array(robot.currentConfiguration()) +q_goal = np.array(q_init[::].copy()) +model = robot.model() + +# Set root_joint bounds only +lowerLimit = model.lowerPositionLimit +upperLimit = model.upperPositionLimit + +# Set root_joint bounds specifically +root_joint_bounds = [-4, -3, -5, -3] +ij = model.getJointId("r0/root_joint") +iq = model.idx_qs[ij] + +# Apply bounds (assuming first 2 DOF are x,y position) +lowerLimit[iq] = -4 +upperLimit[iq] = -3 +lowerLimit[iq + 1] = -5 +upperLimit[iq + 1] = -3 + +rankInConfiguration = dict() +current_rank = 0 +for joint_id in range(1, model.njoints): + joint_name = model.names[joint_id] + joint = model.joints[joint_id] + rankInConfiguration[joint_name[3:]] = current_rank + + current_rank += joint.nq + +q_init[0:2] = [-3.2, -4] + +rank = rankInConfiguration["torso_lift_joint"] +q_init[rank] = 0.2 +q_goal[0:2] = [-3.2, -4] +rank = rankInConfiguration["l_shoulder_lift_joint"] +q_goal[rank] = 0.5 +rank = rankInConfiguration["l_elbow_flex_joint"] +q_goal[rank] = -0.5 +rank = rankInConfiguration["r_shoulder_lift_joint"] +q_goal[rank] = 0.5 +rank = rankInConfiguration["r_elbow_flex_joint"] +q_goal[rank] = -0.5 + +urdf.loadModel( + robot, + 0, + "kitchen_area", + "anchor", + "package://hpp_tutorial/urdf/kitchen_area_obstacle.urdf", + "", + SE3.Identity(), +) + +problem = Problem(robot) +problem.initConfig(q_init) +problem.addGoalConfig(q_goal) + +diffusingPlanner = DiffusingPlanner(problem) + +path_optimizer = RandomShortcut(problem) +path = diffusingPlanner.solve() +opt_path = path_optimizer.optimize(path) + +# launch in interactive mode to use viewer +viewer = Viewer(robot) +viewer.initViewer(open=True, loadModel=True) +viewer(np.array(q_init)) +viewer.loadPath(path, "path") +viewer.loadPath(opt_path, "opt_path") diff --git a/urdf/kitchen_area_obstacle.urdf b/urdf/kitchen_area_obstacle.urdf new file mode 100644 index 0000000..2a555d5 --- /dev/null +++ b/urdf/kitchen_area_obstacle.urdf @@ -0,0 +1,4729 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fixed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + 0.8 + 0.0000001 + 1000000.0 + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100000 + 1000000 + 50000 + 50000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +