{"id":43112945,"url":"https://github.com/abr/abr_control","last_synced_at":"2026-01-31T18:33:38.614Z","repository":{"id":22334522,"uuid":"66477342","full_name":"abr/abr_control","owner":"abr","description":"Robotic arm control in Python","archived":false,"fork":false,"pushed_at":"2023-12-18T01:49:46.000Z","size":19935,"stargazers_count":359,"open_issues_count":8,"forks_count":97,"subscribers_count":15,"default_branch":"main","last_synced_at":"2024-04-21T04:03:54.814Z","etag":null,"topics":["controllers","robot-arm","robot-control"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abr.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE.rst","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-08-24T15:44:38.000Z","updated_at":"2024-04-13T02:02:56.000Z","dependencies_parsed_at":"2023-12-02T19:43:19.652Z","dependency_job_id":null,"html_url":"https://github.com/abr/abr_control","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/abr/abr_control","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abr%2Fabr_control","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abr%2Fabr_control/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abr%2Fabr_control/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abr%2Fabr_control/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abr","download_url":"https://codeload.github.com/abr/abr_control/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abr%2Fabr_control/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28949448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T18:30:42.805Z","status":"ssl_error","status_checked_at":"2026-01-31T18:30:19.593Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["controllers","robot-arm","robot-control"],"created_at":"2026-01-31T18:33:37.552Z","updated_at":"2026-01-31T18:33:38.603Z","avatar_url":"https://github.com/abr.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. image:: https://imgur.com/4qIqbRn.jpg\n\n***********\nABR Control\n***********\n\nThe ABR Control library is a python package for the control and path planning of\nrobotic arms in real or simulated environments. ABR Control provides API's for the\nMujoco, CoppeliaSim (formerly known as VREP), and Pygame simulation environments, and\narm configuration files for one, two, and three-joint models, as well as the UR5 and\nKinova Jaco 2 arms. Users can also easily extend the package to run with custom arm\nconfigurations. ABR Control auto-generates efficient C code for generating the control\nsignals, or uses Mujoco's internal functions to carry out the calculations. Example\nscripts showing how to use the ABR Control package are in the ``docs/examples`` folder.\n\nABR also provides an interface and config available for controlling a real Jaco 2\nat the `ABR_Jaco2 \u003chttps://github.com/abr/abr_jaco2/\u003e`_ repository.\n\nInstallation\n============\n\nThe ABR Control library depends on NumPy, SymPy, SciPy, CloudPickle, Cython,\nSetupTools, Nengo, and Matplotlib. We recommend using\n`Anaconda \u003chttps://store.continuum.io/cshop/anaconda/\u003e`_.\nNote that installing in a clean environment will require compiling of the dependent\nlibraries, and will take a few minutes.\n\nTo install ABR Control, clone this repository and run::\n\n    sudo apt-get install g++\n    sudo apt-get install python-dev\n    sudo apt-get install libfreetype6-dev\n    conda activate your_environment\n    pip install -e .\n\nABR Control is tested to work on Python 3.6+, Python 2 is not supported.\n\nOptional Installation\n=====================\n\nMujoco\n------\nTo run Mujoco simulations, you will need the ``mujoco`` and ``mujoco-python-viewer``\npackages installed. You can either `pip install` these yourself or run the repo\ninstall with ``pip install -e .[optional]``.  Additionally, in Ubuntu 20.04 you\nmay need::\n\n    sudo apt install libomesa6-dev\n    sudo apt install libglew-dev\n    sudo apt install patchelf\n\nPygame\n------\nIf you would like to use the Pygame API, from your anaconda environment run::\n\n    pip install pygame\n\nCoppeliaSim\n-----------\nWe support CoppeliaSim \u003c=4.2. You will need to download\n`Vrep \u003chttp://coppeliarobotics.com/previousVersions/\u003e`_ and follow the installation\ninstructions.\n\n\nABR Jaco2\n---------\nIn addition to simulation of the Kinova Jaco2 in CoppeliaSim and Mujoco, we have an\nAPI for controlling the real arm. For installation instructions, see the\n`ABR_Jaco2 \u003chttps://github.com/abr/abr_jaco2/\u003e`_ repository.\n\n\nUsage\n=====\n\nThe ABR Control repo is comprised of four parts: 1) arms, 2) controllers, 3) path planners,\nand 4) interfaces.\n\n1a) Arms: Config files for CoppeliaSim, Pygame, or real arms\n------------------------------------------------------------\nAll of the required information about an arm model is kept in that arm's config file.\nTo use the ABR Control library with a new arm, the user must provide a new config. For\nCoppeliaSim, Pygame, or a real arm, the config must contain the transformation\nmatrices (written using SymPy expressions) from the robot's origin reference frame to\neach link's centre-of-mass (COM) and joints. These are specified sequentially, e.g.\norigin -\u003e link0 COM, link0 COM -\u003e joint0, joint0 -\u003e link1 COM, etc. The arm config file\nand any simulation code is kept in a folder named the same as the arm in the\n``abr_control/arms/`` directory.\n\n1b) Arms: Config files for Mujoco\n---------------------------------\nWhen using Mujoco the process is a bit different. Mujoco handles the calculation of all\nthe kinematics and dynamics functions, and only requires an xml config be made\ndescribing the kinematic chain. The\n`Mujoco API \u003chttp://www.mujoco.org/book/modeling.html\u003e`_ page describes this in detail.\n\nDetailed models can be created by importing 3D modeling stl files and using the\n``mesh`` object type in the ``\u003cgeom\u003e`` tag. An example of this is the\n``abr_control/arms/jaco2/jaco2.xml``.  For users building their own models, you may\nspecify the location of the xml with the ``folder`` parameter. For more details, please\nrefer to the Mujoco documentation linked above and use the xml files in this repository\nas examples.\n\nFor a detailed walk-through of how the ur5 mujoco model was built, see\n`this tutorial \u003chttps://studywolf.wordpress.com/2020/03/22/building-models-in-mujoco/\u003e`_\n\n\n1c) Arms: Instantiation and transforms\n--------------------------------------\nThe ABR Control configuration base class uses the SymPy transform matrices to provide\nfunctions that will calculate the transforms, Jacobian, Jacobian derivative, inertia\nmatrices, gravity forces, and centripetal and Coriolis effects for each joint and COM.\nThere is also a base config class written for mujoco that has wrappers for these function\nso that they can be accessed in the same way. This way your code should work between\nvarious simulators with minimal changes required. The different config files can be\ninstantiated as:\n\nPygame and CoppeliaSim::\n\n    from abr_control.arms import jaco2 as arm\n\n    # ur5, onelink, twolink, and threelink also available to import\n    robot_config = arm.Config()\n\nMujoco::\n\n    from abr_control.arms import mujoco_config as arm\n\n    # 'ur5', 'onelink', 'twolink', and 'threelink' also available as arm_model's\n    arm_model = 'jaco2'\n    robot_config = arm.MujocoConfig(arm_model)\n\nABR Jaco2 (real arm)::\n\n    import abr_jaco2\n    robot_config = abr_jaco2.Config()\n\nThe transforms can then be accessed from the instantiated robot config::\n\n    # calculate the following given the arm state at joint_angles\n    robot_config.Tx('joint3', q=joint_angles)  # the (x, y, z) position of joint3\n    robot_config.M(q=joint_angles)  # calculate the inertia matrix in joint space\n    robot_config.J('EE', q=joint_angles)  # the Jacobian of the end-effector\n\n\n1d) Arms: Cython for real-time control\n--------------------------------------\nBy default, the ``use_cython`` parameter is set to ``True`` to allow for real-time\ncontrol by generating optimized Cython code for each of the robot configuration\nfunctions. This can take a little bit of time to generate these functions, but they\nare saved in `~.cache/abr_control/arm_name/saved_functions` where they will be loaded\nfrom for future runs. Note that a hash is saved for the config, so if any changes are\nmade the functions will be regenerated during the next use. The cython optimization can\nbe turned off on instantiation::\n\n    from abr_control.arms import ur5\n\n    robot_config = ur5.Config(use_cython=False)\n\nBelow are results from running the operational space controller with different\ncontrollers with ``use_cython=True`` and ``False``.\n\n.. image:: docs/examples/timing.png\n\n2) Controllers\n--------------\nControllers make use of the robot configuration files to generate control signals that\naccomplish a given task (for most controllers this is reaching a target). The ABR\nControl library provides implementations of several primary controllers, including\noperational space, generalized coordinates (joint) space, sliding, and floating\ncontrol.\n\nWhen using an operational space controller (OSC), it is possible to also pass in secondary\ncontrollers to operate in the null space of the operational space controller. These\nsecondary controllers can be set up to achieve secondary goals such as avoiding joint\nlimits and obstacles, damping movement, or maintaining a configuration near a specified\nresting state. Additionally, the OSC can be set to control any combination of the\n6 controllable degrees of freedom of the end-effector. These are the end-effectors\nx, y, z position, and a, b, g orientation.\n\nThere is also an implementation of nonlinear adaptive control in the ``controllers/signals``\nfolder, as well as examples in Mujoco, PyGame, and CoppeliaSim showing how this class\ncan be used to overcome unexpected forces acting on the arm. See the ``docs/examples``\nfolder for various use cases and examples of these controllers.\n\n3a) Path Planners: generating a path\n------------------------------------\nIn the ``controllers/path_planners`` folder there is a generalized path planner that can\nbe used in conjunction with the controllers to provide filtered via points to your target state.\nThis can greatly improve the stability of an arm's motion. The path planner can generate up to a\n12 dimensional path that follows velocity and acceleration limitations. The path planner determines these limits\nand the shape of the path to take by the position and velocity profiles passed on __init__.\n\nThe path planner has a ``generate_path()`` function that takes in start and target positions,\nand a maximum velocity to travel. Optionally, start and target velocities (default 0 and 0)\nand orientations can be passed in. The path planner will generate a trajectory from your desired\nstart to target positions (and optionally orientations). It will also discretize the path over\ntime such that it will be moving at the set start velocity at the beginning of the path, and will\nreach your target position and orientation while moving at your target velocity in that moment.\nThe path planner will use the velocity profile to accelerate from your ``start_velocity`` up to your\n``max_velocity``, and back down to your ``target_velocity``. If the path to travel is too short\nto reach the maximum velocity, the path planner will reach the maximum velocity it can before it\nneeds to begin decelerating to converge to your target state, while maintaining the desired path\nshape. For longer paths the path planner will output a constant velcoity of ``max_velocity``\nonce that speed is reached, until it is time to decelerate.\n\nThe orientation path is planned using spherical linear interpolation (SLERP) to generate\na set of orientations from a start to a target orientation. The time profile will match\nthat of the path planner (ie: a linear velocity profile will have a linear step in orientation over\ntime, with a constant change in orientation, whereas a gaussian velocity profile will\nhave a bell shaped profile with the largest steps occurring during the middle of the\nmovement, with an acceleration and deceleration at the start and end, respectively.)\n\n3b) Path Planners: position profiles\n------------------------------------\nThe position profiles can be thought of as the general shape the path should follow. They contain\na ``step(t)`` function that outputs a 3D position in the domain of ``[0, 1]``. ``[0, 0, 0]`` and\n``[1, 1, 1]`` are restricted to be the start and end of the path, which correspond to times ``0`` and\n``1``, respectively. For a straight-line path this would be a straight line from ``[0, 0, 0]`` to\n``[1, 1, 1]``. The path planner will rotate the position profile to align with the direction of\nyour ``target_position-start_position``, then translate and transform it to start and end at\nthe start and target positions.\n\n.. image:: docs/examples/linear_position_profile.png\n\nMore complex shapes are available such as ellipse and sin curves are readily available, and custom\nones can be added with relative ease. For example, an ellipse profile can be followed, with an additional\nparameter than can adjust the stretching along the horizontal axis\n\n.. image:: docs/examples/ellipse_position_profile.png\n\n3c) Path Planners: velocity profiles\n------------------------------------\nThe velocity profiles are decoupled from the position profiles so that arbitrary low frequency shapes\ncan be defined, and the planned path will follow those shapes while maintaining physically\nlimited velocity and acceleration profiles. The velocity profiles have a ``generate()`` function\nthat outputs a list of velocities from a set start to target velocity. The various velocity_profiles\nvary in their acceleration curves. For example, the ``velocity_profiles.Linear()`` class has a\nconstant acceleration from start to target.\n\n.. image:: docs/examples/linear_path_linear_velocity.png\n\nIn comparison, the ``velocity_profiles.Gaussian()`` class has a smoothly changing velocity that\nfollows a gaussian curve.\n\n.. image:: docs/examples/linear_path_gauss_velocity.png\n\n4) Interfaces\n-------------\nFor communications to and from the system under control, an interface API is used.\nThe functions available in each class vary depending on the specific system, but must\nprovide ``connect``, ``disconnect``, ``send_forces`` and ``get_feedback`` methods.\n\nPutting everything together\n---------------------------\nA control loop using these four files looks like::\n\n    import numpy as np\n\n    from abr_control.arms import ur5 as arm\n    from abr_control.controllers import OSC, Damping\n    from abr_control.controllers.path_planners import PathPlanner\n    from abr_control.controllers.path_planners.position_profiles import Linear\n    from abr_control.controllers.path_planners.velocity_profiles import Gaussian\n    from abr_control.interfaces import CoppeliaSim\n    from abr_control.utils import transformations\n\n    # Sim step size\n    dt = 0.005\n\n    # Initialize our robot config\n    robot_config = arm.Config()\n\n    # Damp the movements of the arm\n    damping = Damping(robot_config, kv=10)\n\n    # Create opreational space controller controlling all 6 DOF\n    ctrlr = OSC(\n        robot_config,\n        kp=100,  # position gain\n        ko=250,  # orientation gain\n        null_controllers=[damping],\n        vmax=None,  # [m/s, rad/s]\n        # control all DOF [x, y, z, alpha, beta, gamma]\n        ctrlr_dof=[True, True, True, True, True, True],\n    )\n\n    # Create our interface\n    interface = CoppeliaSim(robot_config, dt=dt)\n    interface.connect()\n\n    # Create a path planner with a linear shape and gaussian velocity curve\n    path_planner = PathPlanner(\n        pos_profile=Linear(),\n        vel_profile=Gaussian(dt=dt, acceleration=2)\n    )\n\n    # Get our starting state\n    feedback = interface.get_feedback()\n    hand_xyz = robot_config.Tx(\"EE\", feedback[\"q\"])\n    starting_orientation = robot_config.quaternion(\"EE\", feedback[\"q\"])\n\n    # Generate a target\n    target_orientation = np.random.random(3)\n    target_orientation /= np.linalg.norm(target_orientation)\n    # convert our orientation to a quaternion\n    target_orientation = [0] + list(target_orientation)\n    target_position = [-0.4, -0.3, 0.6]\n\n    starting_orientation = transformations.euler_from_quaternion(\n        starting_orientation, axes='rxyz')\n\n    target_orientation = transformations.euler_from_quaternion(\n        target_orientation, axes='rxyz')\n\n    # Generate our 12D path\n    path_planner.generate_path(\n        start_position=hand_xyz,\n        target_position=target_position,\n        start_orientation=starting_orientation,\n        target_orientation=target_orientation,\n        start_velocity=0,\n        target_velocity=0,\n        max_velocity=2\n    )\n\n    count = 0\n\n    # Step through the planned path, with the OSC trying to\n    # bring the end-effector to the filtered target state\n    while count \u003c path_planner.n_timesteps:\n        # get arm feedback\n        feedback = interface.get_feedback()\n        hand_xyz = robot_config.Tx(\"EE\", feedback[\"q\"])\n\n        next_target = path_planner.next()\n        pos = next_target[:3]\n        vel = next_target[3:6]\n        orient = next_target[6:9]\n\n        u = ctrlr.generate(\n            q=feedback[\"q\"],\n            dq=feedback[\"dq\"],\n            target=np.hstack([pos, orient]),\n            target_velocity=np.hstack([vel, np.zeros(3)])\n        )\n\n        # apply the control signal, step the sim forward\n        interface.send_forces(u)\n\n        count += 1\n\n    interface.disconnect()\n\n**NOTE** that when using the Mujoco interface it is necessary to instantiate and\nconnect the interface before instantiating the controller. Some parameters only get\nparsed from the xml once the arm config is linked to the mujoco interface, which\nhappens upon connection. See Section 1 above for the difference in arm instantiation\nfor a Mujoco sim.\n\nExamples\n========\n\nThe ABR Control repo comes with several examples that demonstrate the use of the\ndifferent interfaces and controllers. You can find the examples in the `docs/examples`\nfolder.\n\nBy default all of the PyGame examples run with the three-link MapleSim arm. You can\nalso run the examples using the two-link Python arm by changing the import statement at\nthe top of the example scripts.\n\nTo run the CoppeliaSim examples, have the most recent CoppeliaSim version open. By\ndefault, the CoppeliaSim examples all run with the UR5 or Jaco2 arm model. To change\nthis, change which arm folder is imported at the top of the example script. The first\ntime you run an example you will be promted to download the arm model. Simply select\n``yes`` to download the file and the simulation will start once the download completes.\n\nTo run the Mujoco examples, you will be promted to download any mesh or texture files,\nif they are used in the xml config, similarly to the CoppeliaSim arm model. Once the\ndownload completes the simulation will start. If you are using the forked Mujoco-Py\nrepository (See Optional Installation section) you can exit the simulation with the ESC\nkey and pause with the spacebar.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabr%2Fabr_control","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabr%2Fabr_control","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabr%2Fabr_control/lists"}