{"id":25833102,"url":"https://github.com/woolfrey/server_serial_link","last_synced_at":"2026-06-03T20:31:43.961Z","repository":{"id":253532118,"uuid":"776063113","full_name":"Woolfrey/server_serial_link","owner":"Woolfrey","description":"ROS2 action servers for controlling serial link robots.","archived":false,"fork":false,"pushed_at":"2025-09-10T10:47:06.000Z","size":27719,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-04-25T22:42:45.623Z","etag":null,"topics":["action-server","control","cpp","robot","ros2"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Woolfrey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-03-22T15:53:29.000Z","updated_at":"2025-09-10T10:47:09.000Z","dependencies_parsed_at":"2024-08-17T13:44:59.227Z","dependency_job_id":"9cdbde7d-4f69-45a2-9dbb-1dfba37616ea","html_url":"https://github.com/Woolfrey/server_serial_link","commit_stats":null,"previous_names":["woolfrey/server_serial_link"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/Woolfrey/server_serial_link","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fserver_serial_link","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fserver_serial_link/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fserver_serial_link/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fserver_serial_link/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Woolfrey","download_url":"https://codeload.github.com/Woolfrey/server_serial_link/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Woolfrey%2Fserver_serial_link/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33878990,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["action-server","control","cpp","robot","ros2"],"created_at":"2025-02-28T22:47:05.743Z","updated_at":"2026-06-03T20:31:43.956Z","avatar_url":"https://github.com/Woolfrey.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# :cartwheeling: Serial Link Action Server\n\nThis package contains [ROS2 action servers](https://design.ros2.org/articles/actions.html) defined in the [serial link interface package](https://github.com/Woolfrey/interface_serial_link), using [Robot Library](https://github.com/Woolfrey/software_robot_library) for the underlying control algorithms.\n\n#### :sparkles: Features:\n- Real-time control of serial link robot arms,\n- Joint space \u0026 Cartesian control,\n- Seemless integration with the [serial link action client](https://github.com/Woolfrey/client_serial_link) package, and\n- Classes for implementing your own custom control algorithms.\n\n#### :compass: Navigation\n- [Requirements](#clipboard-requirements)\n- [Installation](#floppy_disk-installation)\n- [Classes](#card_file_box-classes)\n- [Nodes](#satellite-nodes)\n- [Contributing](#handshake-contributing)\n- [Citing this Repository](#bookmark_tabs-citing-this-repository)\n- [License](#scroll-license)\n\n## :clipboard: Requirements\n\n- [Ubuntu 22.04](https://ubuntu.com/blog/tag/22-04-lts), or later,\n- [ROS2 Humble](https://docs.ros.org/en/humble/index.html), or later,\n- [RobotLibrary v2.0.0](https://github.com/Woolfrey/software_robot_library/releases/tag/v2.0.0)), and\n- The [serial link interfaces v1.0.0](https://github.com/Woolfrey/interface_serial_link/releases/tag/v1.1.0) package.\n\n\u003e [!NOTE]\n\u003e This package was built and tested using Ubuntu 22.04, and ROS2 Humble.\n\n## :floppy_disk: Installation\n\nYour directory structure should end up looking something like this:\n```\nros2_workspace/\n├── build/\n├── install/\n├── log/\n└── src/\n    ├── interface_serial_link/\n    └── server_serial_link/\n```\n\n1. In the `src/` directory of your ROS2 workspace, clone the interfaces repository:\n\n```\ngit clone https://github.com/Woolfrey/interface_serial_link.git\n```\n\n2. Clone the action server repository:\n\n```\ngit clone http://github.com/Woolfrey/server_serial_link.git\n```\n\n3. Navigate back to the root of your ROS2 workspace and build:\n\n```\ncolcon build\n```\n\n4. Source the local directory (if you haven't yet altered your .bashrc file):\n\n```\nsource ./install/setup.bash\n```\n\n5. Check successful installation:\n\n```\nros2 pkg list\n```\n   \nIf you scroll down the list, you should see both `serial_link_action_server`, and `serial_link_interfaces`.\n\n[:top: Back to Top.](#cartwheeling-serial-link-action-server)\n\n## :card_file_box: Classes\n\nThis package contains several classes that implement action servers for the actions specified in the [interface repository](https://github.com/Woolfrey/interface_serial_link). The diagram below shows how the classes and nodes are organised in an executable to control a robot:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/server_overview.png\" width=\"700\" height=\"auto\"/\u003e\n\u003c/p\u003e\n\n- A `RobotLibrary::Model::KinematicTree` object is used to compute the forward kinematics \u0026 inverse dynamics of the robot.\n- A `ModelUpdater` node subscribes to a `sensor_msgs::msg::JointState` topic and update the `KinematicTree` as messages are received.\n- A `RobotLibrary::Control::SerialLinkBase` object uses the model to control a branch on the `KinematicTree`.\n- The `ActionServerBase` is a templated class that provides a standardised structure \u0026 interface for all derived classes.\n- The derived classes, e.g. `FollowTransform`, `FollowJointTrajectory`, use the `SerialLinkBase` object to implement the control loop in order to perform the desired action.\n\n[:top: Back to Top.](#cartwheeling-serial-link-action-server)\n\n## :satellite: Nodes\n\nThis package contains nodes with pre-configured actions that you can use. Of course, you can easily make your own, and mix-and-match different actions to suit your own task. Just follow the diagram above, or check how the nodes are written in the `src/nodes/` directory.\n\nEach executable requires 4 arguments:\n1. A path to a valid URDF file,\n2. The name of the endpoint link to be controlled,\n3. The name of the topic to publish the `serial_link_interfaces::msg::JointCommand` message, and\n4. The name of the `sensor_msgs::msg::JointState` topic to subscribe to.\n\nThere is also parameters for the `RobotLibrary::Control::SerialLinkBase` that can be loaded via a `.YAML` file:\n\n```\n/**:\n    ros__parameters:\n\n        # These are for the RobotLibrary::Control class(es):\n        cartesian_damping: [10.0,  0.0,  0.0, 0.0, 0.0, 0.0,\n                             0.0, 10.0,  0.0, 0.0, 0.0, 0.0,\n                             0.0,  0.0, 10.0, 0.0, 0.0, 0.0,\n                             0.0,  0.0,  0.0, 1.0, 0.0, 0.0,\n                             0.0,  0.0,  0.0, 0.0, 1.0, 0.0,\n                             0.0,  0.0,  0.0, 0.0, 0.0, 1.0]\n        cartesian_stiffness: [200.0,   0.0,   0.0,   0.0,   0.0,   0.0,\n                                0.0, 200.0,   0.0,   0.0,   0.0,   0.0,\n                                0.0,   0.0, 200.0,   0.0,   0.0,   0.0,\n                                0.0,   0.0,   0.0, 100.0,   0.0,   0.0,\n                                0.0,   0.0,   0.0,   0.0, 100.0,   0.0,\n                                0.0,   0.0,   0.0,   0.0,   0.0, 100.0]\n        frequency: 500.0\n        joint_position_gain: 50.0\n        joint_velocity_gain:  10.0\n        manipulability_threshold: 0.001\n        max_joint_acceleration: 10.0\n\n        # These are for the underlying QPSolver class:\n        initial_barrier_scalar: 500.0\n        barrier_reduction_rate: 0.001\n        step_size_tolerance: 0.05\n        max_steps: 10\n```\n\nThe best way to run the node is using a launch file, for example `trajectory_tracking.py` might look like:\n\n```\nimport os\nfrom launch import LaunchDescription\nfrom launch_ros.actions import Node\n\ndef generate_launch_description():\n\n    trajectory_tracking = Node(\n        package    = 'serial_link_action_server',\n        executable = 'trajectory_tracking_server',\n        name       = 'trajectory_tracking_server',\n        output     = 'screen',\n        parameters = ['config/control_parameters.yaml')],\n        arguments  = ['urdf/robot.urdf'),                     # URDF location\n                     'end_effector',                          # Endpoint name\n                     'joint_commands',                        # Topic to publish joint commands to\n                     'joint_state']                           # Joint state topic to subscribe to\n    )\n\n    return LaunchDescription([trajectory_tracking])\n```\n\n### Follow Transform Server\n\nThis node contains the `FollowJointTrajectory` action, so you can move the robot in to different joint configurations, and the `FollowTransform` action. With the latter, you use a corresponding client to tell the server the `frame_id` of a `tf2_ros::Transform` that is broadcast somehow over the network. The server listens for this transform, and performs feedback control to align the robot endpoint pose with it.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/follow_transform.png\" width=\"500\" height=\"auto\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/follow_transform.gif\" width=\"600\" height=\"auto\"\u003e\n\u003c/p\u003e\n\n\n### Follow Twist Server\n\nThis node contains the `FollowJointTrajectory` action, so you can move the robot in to different joint configurations, and the `FollowTwist` action. Using the latter's matching client, you send a goal with the topic name for a `geometry_msgs::msg::TwistStamped` message that is being published somehow over the ROS2 network. The action client will subscribe to this topic, and move the endpoint of the robot at the given speed.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/follow_twist.png\" width=\"600\" height=\"auto\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/follow_twist.gif\" width=\"600\" height=\"auto\"\u003e\n\u003c/p\u003e\n\n\n### Track Trajectory Server\n\nThis node contains the `FollowJointTrajectory` action, and the `FollowCartesianTrajectory` action. Using the former, you can move the robot in to different joint configurations. Using the latter, you can make the endpoint follow a trajectory defined by a series of `serial_link_interfaces::msg::CartesianTrajectoryPoint`s. The actions erver takes these waypoints and fits a spline to them, and performs feedback control to follow it.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/track_trajectory.png\" width=\"350\" height=\"auto\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"doc/track_trajectory.gif\" width=\"600\" height=\"auto\"\u003e\n\u003c/p\u003e\n\n[:top: Back to Top.](#cartwheeling-serial-link-action-server)\n\n## :handshake: Contributing\n\nContributions to this repositore are welcome! Feel free to:\n1. Fork the repository,\n2. Implement your changes / improvements, then\n3. Issue a pull request.\n\nIf you're looking for ideas, you can always check the [Issues tab](https://github.com/Woolfrey/server_serial_link/issues) for those with :raising_hand: [OPEN]. These are things I'd like to implement, but don't have time for. It'd be much appreciated, and you'll be tagged as a contributor :sunglasses:\n\n[:top: Back to Top.](#cartwheeling-serial-link-action-server)\n\n## :bookmark_tabs: Citing this Repository\n\nIf you find this code useful, spread the word by acknowledging it. Click on `Cite this repository` under the **About** section in the top-right corner of this page :arrow_upper_right:.\n\nHere's a BibTeX reference:\n```\n@software{woolfrey_serial_link_action_server_2005\n     author  = {Woolfrey, Jon},\n     month   = apr,\n     title   = {{S}erial {L}ink {A}ction {S}erver},\n     url     = {https://github.com/Woolfrey/server_serial_link},\n     version = {1.0.0},\n     year    = {2025}\n}\n```\nHere's the automatically generated APA format:\n```\nWoolfrey, J. (2025). Serial Link Action Server (Version 1.0.0). Retrieved from https://github.com/Woolfrey/server_serial_link\n```\n\n[:top: Back to Top.](#cartwheeling-serial-link-action-server)\n\n## :scroll: License\n\nThis software package is licensed under the [GNU General Public License v3.0 (GPL-3.0)](https://choosealicense.com/licenses/gpl-3.0/). You are free to use, modify, and distribute this package, provided that any modified versions also comply with the GPL-3.0 license. All modified versions must make the source code available and be licensed under GPL-3.0. The license also ensures that the software remains free and prohibits the use of proprietary restrictions such as Digital Rights Management (DRM) and patent claims. For more details, please refer to the [full license text](LICENSE).\n\n[:top: Back to Top.](#cartwheeling-serial-link-action-server)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoolfrey%2Fserver_serial_link","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwoolfrey%2Fserver_serial_link","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoolfrey%2Fserver_serial_link/lists"}