diff --git a/poetry.lock b/poetry.lock index de4b7bcfb332839793df1d801a4b38d0264ad00a..bda0ede59e0968a8505efe4f830526990656c863 100644 --- a/poetry.lock +++ b/poetry.lock @@ -126,18 +126,12 @@ python-versions = ">=3.7" license = ["ukkonen"] [[package]] -name = "isort" -version = "5.10.1" -description = "A Python utility / library to sort Python imports." +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" category = "dev" optional = false -python-versions = ">=3.6.1,<4.0" - -[package.extras] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] -requirements_deprecated_finder = ["pipreqs", "pip-api"] -colors = ["colorama (>=0.4.3,<0.5.0)"] -plugins = ["setuptools"] +python-versions = "*" [[package]] name = "mccabe" @@ -147,14 +141,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "more-itertools" -version = "8.12.0" -description = "More routines for operating on iterables, beyond itertools" -category = "dev" -optional = false -python-versions = ">=3.5" - [[package]] name = "mypy" version = "0.931" @@ -221,14 +207,15 @@ test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock [[package]] name = "pluggy" -version = "0.13.1" +version = "1.0.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.extras] dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" @@ -283,25 +270,24 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "5.4.3" +version = "7.1.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [package.dependencies] atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=17.4.0" +attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} -more-itertools = ">=4.0.0" +iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0" -py = ">=1.5.0" -wcwidth = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +tomli = ">=1.0.0" [package.extras] -checkqa-mypy = ["mypy (==v0.761)"] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "pyyaml" @@ -372,18 +358,10 @@ six = ">=1.9.0,<2" docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"] testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"] -[[package]] -name = "wcwidth" -version = "0.2.5" -description = "Measures the displayed width of unicode strings in a terminal" -category = "dev" -optional = false -python-versions = "*" - [metadata] lock-version = "1.1" python-versions = ">=3.9,<3.11" -content-hash = "6f4fb43a3eb03bef2f49af983c6f3badb40dfae20eb298a2e675822bc2477752" +content-hash = "ab1f88cbf02688daeb723c77086aedf337fd9c15eac50157c4b0481537be2098" [metadata.files] "aspy.refactor-imports" = [ @@ -430,18 +408,14 @@ identify = [ {file = "identify-2.4.12-py2.py3-none-any.whl", hash = "sha256:5f06b14366bd1facb88b00540a1de05b69b310cbc2654db3c7e07fa3a4339323"}, {file = "identify-2.4.12.tar.gz", hash = "sha256:3f3244a559290e7d3deb9e9adc7b33594c1bc85a9dd82e0f1be519bf12a1ec17"}, ] -isort = [ - {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, - {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] -more-itertools = [ - {file = "more-itertools-8.12.0.tar.gz", hash = "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"}, - {file = "more_itertools-8.12.0-py3-none-any.whl", hash = "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b"}, -] mypy = [ {file = "mypy-0.931-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c5b42d0815e15518b1f0990cff7a705805961613e701db60387e6fb663fe78a"}, {file = "mypy-0.931-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c89702cac5b302f0c5d33b172d2b55b5df2bede3344a2fbed99ff96bddb2cf00"}, @@ -485,8 +459,8 @@ platformdirs = [ {file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"}, ] pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] pre-commit = [ {file = "pre_commit-2.17.0-py2.py3-none-any.whl", hash = "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616"}, @@ -509,8 +483,8 @@ pyparsing = [ {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] pytest = [ - {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, - {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, + {file = "pytest-7.1.1-py3-none-any.whl", hash = "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea"}, + {file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"}, ] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, @@ -571,7 +545,3 @@ virtualenv = [ {file = "virtualenv-20.13.4-py2.py3-none-any.whl", hash = "sha256:c3e01300fb8495bc00ed70741f5271fc95fed067eb7106297be73d30879af60c"}, {file = "virtualenv-20.13.4.tar.gz", hash = "sha256:ce8901d3bbf3b90393498187f2d56797a8a452fb2d0d7efc6fd837554d6f679c"}, ] -wcwidth = [ - {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, - {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, -] diff --git a/pyproject.toml b/pyproject.toml index d0e7fb4196d2519ac7634e05be43a81e3e9eb032..5a9b7d15dbbd7130870edfd8016a3fe9df06df0c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,13 +18,12 @@ repository = "https://gitlab.control.lth.se/selectica/py_ur_ctl" python = ">=3.9,<3.11" [tool.poetry.dev-dependencies] -pytest = "^5.2" -isort = "^5.10.1" flake8 = "^4.0.1" mypy = "^0.931" black = "^21.12b0" pre-commit = "^2.17.0" reorder-python-imports = "^3.0.1" +pytest = "^7.1.1" [tool.isort] profile = "black" diff --git a/tests/test_urscript_commands.py b/tests/test_urscript_commands.py new file mode 100644 index 0000000000000000000000000000000000000000..fd56c54314cabf08f03e5b4b88a4697bd1212d65 --- /dev/null +++ b/tests/test_urscript_commands.py @@ -0,0 +1,60 @@ +import pytest + +from ur_py_ctl.urscript_commands import _add_whitespace +from ur_py_ctl.urscript_commands import _get_conf +from ur_py_ctl.urscript_commands import _get_func +from ur_py_ctl.urscript_commands import _get_pose + + +@pytest.fixture() +def conf_list(): + return [50, 25, 12.5, 100, 270, 360] + + +@pytest.fixture +def conf_str(): + return "[50.00000, 25.00000, 12.50000, 100.00000, 270.00000, 360.00000]" + + +@pytest.fixture() +def pose_list(): + return [22, 13, 25, 3.14, 0, 1.7] + + +@pytest.fixture() +def pose_str(): + return "p[22.00000, 13.00000, 25.00000, 3.14000, 0.00000, 1.70000]" + + +def test__add_whitespace(): + def func(input_): + return input_[::-1] + + wrapped_func = _add_whitespace(func) + + input_ = "polyscope" + + output = wrapped_func(input_) + + assert output[0] == "\t" + assert output[-1] == "\n" + assert output.strip() == func(input_) + + +def test_get_func(): + func_name = "func" + urscript_args = "args" + urscript_kwargs = "kwargs" + + assert ( + _get_func(func_name, urscript_args, urscript_kwargs) + == f"{func_name}({urscript_args}, {urscript_kwargs})" + ) + + +def test__get_conf(conf_list, conf_str): + assert _get_conf(*conf_list) == conf_str + + +def test__get_pose(pose_list, pose_str): + assert _get_pose(*pose_list) == pose_str diff --git a/ur_py_ctl/urscript_commands.py b/ur_py_ctl/urscript_commands.py index d14711900d58c3edcfc5d67b97da7b13a04cee22..e4b6bb9c0c8db79d46a7de6fe9c4dbebee1d33e9 100644 --- a/ur_py_ctl/urscript_commands.py +++ b/ur_py_ctl/urscript_commands.py @@ -26,7 +26,7 @@ def _get_pose(x: float, y: float, z: float, ax: float, ay: float, az: float) -> return f"p[{x:.5f}, {y:.5f}, {z:.5f}, {ax:.5f}, {ay:.5f}, {az:.5f}]" -def _get_conf(j1, j2, j3, j4, j5, j6): +def _get_conf(j1: float, j2: float, j3: float, j4: float, j5: float, j6: float): return f"[{j1:.5f}, {j2:.5f}, {j3:.5f}, {j4:.5f}, {j5:.5f}, {j6:.5f}]" @@ -48,24 +48,47 @@ def _get_move_kwargs(**kwargs) -> str: @_add_whitespace -def set_tcp(*args) -> str: - return _get_func("set_tcp", _get_pose(*args)) +def set_tcp(x: float, y: float, z: float, rx: float, ry: float, rz: float) -> str: + return _get_func("set_tcp", _get_pose(x, y, z, rx, ry, rz)) @_add_whitespace -def move_to_pose(*pose_args, mode=Motion.JOINT, **kwargs): +def move_to_pose( + x: float, + y: float, + z: float, + rx: float, + ry: float, + rz: float, + mode=Motion.JOINT, + v: float = None, + a: float = None, + t: float = None, + r: float = None, +) -> str: func_name = "movel" if mode == Motion.LINEAR else "movej" - pose = _get_pose(*pose_args) - move_kwargs = _get_move_kwargs(**kwargs) + pose = _get_pose(x, y, z, rx, ry, rz) + move_kwargs = _get_move_kwargs(v=v, a=a, t=t, r=r) return _get_func(func_name, pose, move_kwargs) @_add_whitespace -def move_to_conf(*conf_args, **kwargs): - conf = _get_conf(*conf_args) - move_kwargs = _get_move_kwargs(**kwargs) +def move_to_conf( + j1: float, + j2: float, + j3: float, + j4: float, + j5: float, + j6: float, + v: float = None, + a: float = None, + t: float = None, + r: float = None, +) -> str: + conf = _get_conf(j1, j2, j3, j4, j5, j6) + move_kwargs = _get_move_kwargs(v=v, a=a, t=t, r=r) return _get_func("movej", conf, move_kwargs) @@ -77,15 +100,24 @@ def textmsg(string: str) -> str: @_add_whitespace def set_DO(pin: int, state: bool) -> str: - return f"set_digital_out({pin:d}, {state})" + """Construct a function call that sets the state of a digital out.""" + # bool(state) should convert numeric representation to boolean value and + # then into True or False as string. + return _get_func("set_digital_out", f"{pin:d}, {bool(state)}") @_add_whitespace def sleep(seconds: int) -> str: - return "sleep({})".format(seconds) + """Construct a function call that instructs the controller to sleep.""" + return _get_func("sleep", str(seconds)) @_add_whitespace def popup(string: str) -> str: - # Popup title not implemented, neither is error or warning flags + """Construct a function call that opens a popup on the teach pendant. + + Notes + ----- + Popup arguments title, error & warning is not implemented in URScript. + """ return f'popup("{string}")'