From 9236a9bf8ad6f5e8d0efcb402470d0b7bddb4001 Mon Sep 17 00:00:00 2001 From: thetooler Date: Wed, 30 Sep 2026 13:19:33 +0800 Subject: [PATCH 1/2] docs: remove all ROS references from docs and comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The library never depended on ROS, but its docs and comments described it as the "ROS-agnostic" layer of a ROS stack, which reads as ROS-adjacent to anyone opening the repository cold. Drop every ROS reference: the package name, the layer diagram, the colcon build note, and the ROS-side provenance of the safety ceilings and the control loop. Prose that carried real information is rewritten rather than deleted — "the ROS-side gate" becomes "the old Python gate", "the node" becomes "the process", and "## Non-ROS usage" becomes "## Minimal example". package.xml is kept (it declares the plain-cmake package) with its description cleaned and the ros.org schema processing instruction removed; the resulting file stays well-formed XML. No behavior change: comments, descriptions, documentation and the pkg-config Description field only. --- CMakeLists.txt | 8 +++----- README.md | 22 +++++++++------------- README_zh.md | 20 ++++++++------------ cmake/litegrip_cpp.pc.in | 2 +- examples/CMakeLists.txt | 5 +++-- include/litegrip/can/controller.hpp | 4 ++-- include/litegrip/control_loop.hpp | 10 +++++----- include/litegrip/gripper.hpp | 5 ++--- include/litegrip/safety.hpp | 8 ++++---- package.xml | 15 ++++++--------- src/control_loop.cpp | 14 +++++++------- src/safety.cpp | 2 +- src/version.cpp | 2 +- 13 files changed, 52 insertions(+), 65 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2f5e85..34515bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,12 @@ cmake_minimum_required(VERSION 3.16) project(litegrip_cpp VERSION 0.1.0 LANGUAGES CXX) -# litegrip_cpp — ROS-agnostic C++ SDK for the LiteGrip adaptive two-finger gripper. +# litegrip_cpp — C++ SDK for the LiteGrip adaptive two-finger gripper. # # Design constraints (see ../PLAN-litegrip-cpp.md): # * C++17, zero third-party dependencies (stdlib + Linux SocketCAN only). -# * MUST NOT depend on ROS / ament / ros2_control — this library is the bottom -# layer that ros2_control links, and is usable from any plain C++ program. -# * Installable both into a ROS workspace (colcon, plain-cmake package.xml) -# and into a normal prefix (find_package + pkg-config). +# * No framework dependencies — usable from any plain C++ program. +# * Installable into a normal prefix (find_package + pkg-config). if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(LITEGRIP_CPP_IS_TOP_LEVEL ON) diff --git a/README.md b/README.md index d9e6e42..f552cae 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,15 @@ # litegrip_cpp -ROS-agnostic **C++ SDK** for the LiteGrip adaptive two-finger gripper. +**C++ SDK** for the LiteGrip adaptive two-finger gripper. **English** · [简体中文](README_zh.md) -This is layer 1 of the litegrip stack — `litegrip_cpp` (SDK) → `litegrip_ros2_control` -(hardware interface) → `litegrip_moveit_config` (MoveIt). It speaks SocketCAN and -the Damiao DM4310 MIT protocol directly and depends on **nothing** but the C++17 -standard library, `pthread`, and the Linux SocketCAN headers: no ROS, no ament, -no third-party libraries. Non-ROS implementations can link it as-is. +The bottom layer of the litegrip stack. It speaks SocketCAN and the Damiao +DM4310 MIT protocol directly and depends on **nothing** but the C++17 standard +library, `pthread`, and the Linux SocketCAN headers: no third-party libraries. +Any plain C++ program can link it as-is. -> Status: **layer 1 is complete** — `can/*`, `GripperBus`, `LiteGrip`, +> Status: **the SDK is complete** — `can/*`, `GripperBus`, `LiteGrip`, > `json`/calibration, `SafetyGuard` and `ControlLoop` are all implemented and > tested. @@ -80,7 +79,7 @@ motion, calibration, and the transport send/receive path. | `GripperBus` | single-gripper bus API (init = hold) | `protocols/can_bus.py` | | `LiteGrip` | high-level API | `gripper.py` | | `SafetyGuard` + `SafetyLimits` | red lines, torque budget, watchdog, modes | `safety_limits.py` (core) | -| `ControlLoop` | background 200 Hz streaming + rate limit + gate | old ROS-side daemon | +| `ControlLoop` | background 200 Hz streaming + rate limit + gate | old Python-side daemon | ## Build @@ -92,21 +91,18 @@ cmake --build build -j ctest --test-dir build --output-on-failure ``` -It is also buildable by `colcon` (declared as a plain-cmake package via -`package.xml`) so a ROS workspace can build it beside the ROS packages. - ## Consume ```cmake find_package(litegrip_cpp REQUIRED) -target_link_libraries(my_node PRIVATE litegrip_cpp::litegrip_cpp) +target_link_libraries(my_app PRIVATE litegrip_cpp::litegrip_cpp) ``` ```bash pkg-config --cflags --libs litegrip_cpp ``` -## Non-ROS usage +## Minimal example ```cpp #include diff --git a/README_zh.md b/README_zh.md index 67c110a..19d7a8c 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,13 +1,12 @@ # litegrip_cpp -LiteGrip 自适应两指夹爪的 **ROS 无关 C++ SDK**。 +LiteGrip 自适应两指夹爪的 **C++ SDK**。 -本包是 litegrip 栈的第 1 层 —— `litegrip_cpp`(SDK)→ `litegrip_ros2_control` -(硬件接口)→ `litegrip_moveit_config`(MoveIt)。它直接讲 SocketCAN 与达妙 -DM4310 的 MIT 协议,依赖**只有** C++17 标准库、`pthread` 和 Linux SocketCAN -头文件:没有 ROS、没有 ament、没有第三方库。非 ROS 实现可以直接链接使用。 +litegrip 栈的最底层。它直接讲 SocketCAN 与达妙 DM4310 的 MIT 协议,依赖 +**只有** C++17 标准库、`pthread` 和 Linux SocketCAN 头文件:没有第三方库。 +任何普通 C++ 程序都可以直接链接。 -> 状态:**第 1 层已全部实现**(`can/*`、`GripperBus`、`LiteGrip`、 +> 状态:**SDK 已全部实现**(`can/*`、`GripperBus`、`LiteGrip`、 > `json`/标定、`SafetyGuard`、`ControlLoop`)。 ## 分层 @@ -21,7 +20,7 @@ DM4310 的 MIT 协议,依赖**只有** C++17 标准库、`pthread` 和 Linux S | `GripperBus` | 单爪总线 API(`init` = 持位) | `protocols/can_bus.py` | | `LiteGrip` | 高层 API | `gripper.py` | | `SafetyGuard` + `SafetyLimits` | 红线、力矩预算、看门狗、模式 | `safety_limits.py`(核心) | -| `ControlLoop` | 后台 200 Hz 流式发送 + 限速 + 闸门 | 旧的 ROS 侧守护进程 | +| `ControlLoop` | 后台 200 Hz 流式发送 + 限速 + 闸门 | 旧的 Python 侧守护进程 | ## 构建 @@ -33,21 +32,18 @@ cmake --build build -j ctest --test-dir build --output-on-failure ``` -它同时可以被 `colcon` 构建(通过 `package.xml` 声明为 plain-cmake 包), -因此 ROS 工作空间能把它和其余 ROS 包一起构建。 - ## 消费方式 ```cmake find_package(litegrip_cpp REQUIRED) -target_link_libraries(my_node PRIVATE litegrip_cpp::litegrip_cpp) +target_link_libraries(my_app PRIVATE litegrip_cpp::litegrip_cpp) ``` ```bash pkg-config --cflags --libs litegrip_cpp ``` -## 非 ROS 用法 +## 最小示例 ```cpp #include diff --git a/cmake/litegrip_cpp.pc.in b/cmake/litegrip_cpp.pc.in index c1563a5..701cfc6 100644 --- a/cmake/litegrip_cpp.pc.in +++ b/cmake/litegrip_cpp.pc.in @@ -9,7 +9,7 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ datadir=${prefix}/@CMAKE_INSTALL_DATADIR@ Name: litegrip_cpp -Description: ROS-agnostic C++ SDK for the LiteGrip adaptive two-finger gripper (SocketCAN / Damiao DM4310 MIT protocol) +Description: C++ SDK for the LiteGrip adaptive two-finger gripper (SocketCAN / Damiao DM4310 MIT protocol) Version: @PROJECT_VERSION@ Libs: -L${libdir} -llitegrip_cpp Libs.private: -lpthread diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 85fa0b1..6555443 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,6 @@ -# Examples are plain C++ programs that link the SDK. They are the -# "non-ROS consumer" proof: nothing here may include ROS headers. +# Examples are plain C++ programs that link the SDK. They are the "plain C++ +# consumer" proof: nothing here may include anything beyond the SDK and the +# standard library. # # ⚠ Examples that open can0 and drive the motor are added in T2–T4; the T1 set # is limited to things that cannot move hardware. diff --git a/include/litegrip/can/controller.hpp b/include/litegrip/can/controller.hpp index 2556d2d..109c54a 100644 --- a/include/litegrip/can/controller.hpp +++ b/include/litegrip/can/controller.hpp @@ -1,8 +1,8 @@ // litegrip/can/controller.hpp — manages DM motors over one CAN transport. // // Port of litegrip_driver/litegrip/can/controller.py. Kept multi-motor capable -// even though LiteGrip uses a single motor: it is the reusable "outside ROS" -// surface for anyone driving several Damiao motors on one bus. +// even though LiteGrip uses a single motor: it is the general-purpose surface +// for anyone driving several Damiao motors on one bus. #pragma once diff --git a/include/litegrip/control_loop.hpp b/include/litegrip/control_loop.hpp index c42931c..becb3f2 100644 --- a/include/litegrip/control_loop.hpp +++ b/include/litegrip/control_loop.hpp @@ -1,13 +1,13 @@ // litegrip/control_loop.hpp — background streaming control loop. // -// Replaces the old ros2_control Python daemon (hw_daemon.py + sdk_adapter.py + -// the shared-memory bridge). With a C++ SDK the two-process split has no reason -// to exist: the ros2_control hardware component links this class directly. +// Replaces the old Python daemon (hw_daemon.py + sdk_adapter.py + the +// shared-memory bridge). With a C++ SDK the two-process split has no reason to +// exist: the layer above links this class directly. // // R1: the loop runs on its own background thread. A DM motor needs a continuous // MIT frame stream (~900 ms of silence latches the 0xD comm-loss fault), and -// the controller_manager cycle is not guaranteed stable — so the plugin's -// write() only posts a target and its read() only reads a cached snapshot. +// the caller's cycle is not guaranteed stable — so the layer above only posts a +// target and reads a cached snapshot. // // What the loop owns (all of it used to be spread across safety_gate.py, // driver_adapter.py's TrajectoryLimiter and sdk_adapter.py's _send_motion): diff --git a/include/litegrip/gripper.hpp b/include/litegrip/gripper.hpp index 6db5ed6..9f71ff3 100644 --- a/include/litegrip/gripper.hpp +++ b/include/litegrip/gripper.hpp @@ -1,8 +1,7 @@ // litegrip/gripper.hpp — high-level gripper API (LiteGrip). // // Port of litegrip_driver/litegrip/gripper.py. This is the entry point most -// non-ROS consumers use: connect, init (hold), open/close/goto, calibrate, -// read state. +// consumers use: connect, init (hold), open/close/goto, calibrate, read state. // // v1 capability scope (PLAN-litegrip-cpp.md D6). Deliberately NOT in v1: // * grasp() / set_force() — force control, deferred @@ -43,7 +42,7 @@ class LiteGrip { LiteGrip& operator=(LiteGrip&& other) noexcept; /// Connect and return a live instance (throws ConnectError on failure). - /// The RAII one-liner for the non-ROS case. + /// The RAII one-liner: the returned object disconnects on destruction. static LiteGrip connect_raii(GripperConfig config = GripperConfig{}); // ── properties ──────────────────────────────────────────────────────── diff --git a/include/litegrip/safety.hpp b/include/litegrip/safety.hpp index a3b1cd7..4d6a5e4 100644 --- a/include/litegrip/safety.hpp +++ b/include/litegrip/safety.hpp @@ -2,10 +2,10 @@ // // Ported from the safety-aware SDK variant's safety_limits.py (core only — // exclude the contact/force/stall/no-load physics models, see -// PLAN-litegrip-cpp.md D5), plus the ROS-side gate's two hard ceilings +// PLAN-litegrip-cpp.md D5), plus the old Python gate's two hard ceilings // (TORQUE_LIMIT_CEILING_NM / MAX_COMMAND_VELOCITY_CEILING_RAD_S) so that the -// whole stack keeps a single source of truth now that the ROS-side Python is -// going away (D2/D4). +// whole stack keeps a single source of truth now that the old Python is going +// away (D2/D4). // // The Python original's long-form Chinese rationale is NOT copied here — it // lives in safety_limits.py and in the plan. What is preserved is the set of @@ -62,7 +62,7 @@ inline constexpr double kProtocolQMaxRad = 12.5; /// protocol range / a fake 0 read from nothing. inline constexpr double kZeroTorqueQFallback = -0.6; -/// ROS-side torque hard ceiling, N.m. Read-only: limits may only go below it. +/// Torque hard ceiling, N.m. Read-only: limits may only go below it. inline constexpr double kTorqueLimitCeilingNm = 3.5; /// Command-trajectory velocity hard ceiling, rad/s. Read-only. diff --git a/package.xml b/package.xml index e75b366..5f1c71c 100644 --- a/package.xml +++ b/package.xml @@ -1,19 +1,16 @@ - litegrip_cpp 0.1.0 - ROS-agnostic C++ SDK for the LiteGrip adaptive two-finger gripper. + C++ SDK for the LiteGrip adaptive two-finger gripper. - This is the bottom layer of the litegrip stack (sdk → ros2_control → - moveit_config). It speaks SocketCAN and the Damiao DM4310 MIT protocol - directly and depends on nothing but the C++17 standard library and the - Linux SocketCAN headers — deliberately no ROS, no ament, no third-party - libraries, so that non-ROS implementations can reuse it as-is. + This is the bottom layer of the litegrip stack. It speaks SocketCAN and the + Damiao DM4310 MIT protocol directly and depends on nothing but the C++17 + standard library and the Linux SocketCAN headers — no third-party + libraries. - Declared as a plain-cmake package (build_type cmake) purely so a colcon - workspace can build it alongside the ROS packages; the library itself is + Declared as a plain-cmake package (build_type cmake); the library itself is built and installed like any ordinary CMake project. TODO diff --git a/src/control_loop.cpp b/src/control_loop.cpp index 6c8a456..c025596 100644 --- a/src/control_loop.cpp +++ b/src/control_loop.cpp @@ -1,20 +1,20 @@ // control_loop.cpp — the background control loop. // -// Replaces the old ros2_control Python daemon + shared-memory bridge: with a -// C++ SDK the two-process split has no reason to exist, so "rate-limit the -// target, allocate the torque budget, gate the frame, stream it, watch the -// feedback" now lives in one thread inside the library. +// Replaces the old Python daemon + shared-memory bridge: with a C++ SDK the +// two-process split has no reason to exist, so "rate-limit the target, allocate +// the torque budget, gate the frame, stream it, watch the feedback" now lives +// in one thread inside the library. // // R1: the loop owns a background thread. A DM motor needs a continuous MIT // frame stream (~900 ms of silence latches the 0xD comm-loss fault) and the -// controller_manager cycle is not guaranteed stable, so the layer above only -// posts a target and reads a cached snapshot. +// caller's cycle is not guaranteed stable, so the layer above only posts a +// target and reads a cached snapshot. // // dry_run is not "do nothing": it runs the whole control path — rate limiting, // torque-budget allocation and the safety gate — against a simulated plant and // only skips opening CAN and sending. That makes the gate and the // deploy-config fail-closed behaviour testable without hardware, and is what -// makes a dry-run ros2_control stack meaningful. +// makes a dry-run deployment meaningful. #include "litegrip/control_loop.hpp" diff --git a/src/safety.cpp b/src/safety.cpp index d8f66d1..5fe4fcb 100644 --- a/src/safety.cpp +++ b/src/safety.cpp @@ -731,7 +731,7 @@ SafetyLimits load_safety_baseline(const std::optional& version) { : safety_baseline_path(wanted); if (!file_exists(path)) { // Fail-closed: silently falling back would make "the config was lost" look - // identical to "the config is correct", and the node would run with a + // identical to "the config is correct", and the process would run with a // torque ceiling nobody confirmed. throw SafetyConfigError("safety baseline '" + wanted + "' file does not exist: " + path + diff --git a/src/version.cpp b/src/version.cpp index 1954735..69e0948 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -1,4 +1,4 @@ -// litegrip_cpp — ROS-agnostic C++ SDK for the LiteGrip adaptive two-finger gripper. +// litegrip_cpp — C++ SDK for the LiteGrip adaptive two-finger gripper. #include "litegrip/version.hpp" From 451d2e14f32d8d2256e8c52cad2d32ceec551dc2 Mon Sep 17 00:00:00 2001 From: thetooler Date: Wed, 30 Sep 2026 13:24:00 +0800 Subject: [PATCH 2/2] docs: drop v1 scope, license and red-line notes from readmes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "What is not in this version" section read as a project-management artifact: it cited an "agreed v1 scope" and listed what was deferred, which is not what a README is for. The same applies to the license section — the MIT LICENSE file at the repository root is the statement, and restating it in one language only made the two readmes diverge. Also drop the "Red lines are not yet unit-specific" section. Nothing is lost: the warning ships with the library, verbatim, in the baseline data (calibration/safety_limits_350.json, "★ NOT VERIFIED ON THIS UNIT" plus the re-derivation and max_feedback_velocity_rad_s note) and in include/litegrip/safety.hpp. The fail-closed behaviour it describes is enforced by the control loop, not by the documentation. The v1 capability scope stays documented where callers meet it: the header comment in include/litegrip/gripper.hpp. No behavior change: README.md loses 15 lines, README_zh.md 20, all deletions. --- README.md | 15 --------------- README_zh.md | 20 -------------------- 2 files changed, 35 deletions(-) diff --git a/README.md b/README.md index f552cae..1afd6bc 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,6 @@ Any plain C++ program can link it as-is. > `json`/calibration, `SafetyGuard` and `ControlLoop` are all implemented and > tested. -## What is **not** in this version - -Per the agreed v1 scope: `grasp()`, `set_force()`, `move_at_speed*()` and the -public zero-gravity mode. `close(force_n=...)` accepts the argument, ignores it -and says so, because applying a grip force needs torque feed-forward and -verified force calibration. - ## Safety wiring The motion path (`goto_rad` / `move_to` / `open` / `close` / `home`) passes @@ -129,11 +122,3 @@ These are the safety argument and must not be relaxed: be bounded ⇒ do not move that way. 4. **Strict numeric boundary** — NaN / ±inf / non-numbers are rejected before any comparison. - -## Red lines are not yet unit-specific - -The packaged safety baseline carries the reference unit's hand-push measurement. -They must be re-derived per gripper (caliper + closed-end re-zero) before -real-hardware motion, and `ControlLoopConfig::max_feedback_velocity_rad_s` must -be calibrated first — until it is, the loop refuses to send any motion frame -(deliberate fail-closed). diff --git a/README_zh.md b/README_zh.md index 19d7a8c..8cbaff9 100644 --- a/README_zh.md +++ b/README_zh.md @@ -59,12 +59,6 @@ int main() { } ``` -## 本版本**不包含** - -按已确认的 v1 范围:`grasp()`、`set_force()`、`move_at_speed*()`,以及公开的零重力 -模式。`close(force_n=...)` 接受该参数但**忽略并明确告警**,因为施加夹持力需要力矩 -前馈与经过验证的力标定,两者都不在 v1 范围内。 - ## 安全不变量 这些是安全论证本身,**不得放宽**: @@ -86,16 +80,6 @@ int main() { - **标定流程** —— 它们本来就要把机构顶到**机械**端点,而机械端点在红线之外。 (标定与红线之间的正确关系仍是一个待定事项,见方案中的未决项。) -## 红线尚未按本台夹爪重建 - -随包的安全基线携带的是**参考台**的手推实测值,且文件内已明确标注 -**未在本机验证**。在真机运动之前必须重新标定(卡尺 + 闭合端重设零点)并以实测值 -重建红线;同时 `ControlLoopConfig::max_feedback_velocity_rad_s` 必须先行标定 —— -在该值给出之前,控制环**拒绝发送任何运动帧**(这是刻意的 fail-closed)。 - -推论:若某台夹爪的标定使闭合端落在红线之外,本 SDK 会(正确地)**拒绝一切运动**, -直到红线被重建。 - ## 测试 ```bash @@ -121,7 +105,3 @@ ctest --test-dir build --output-on-failure 覆盖** —— 需要 vcan 接口(需 root)或真机。 同样没有覆盖、需要真机的部分:连接、`init`/使能、运动、标定。 - -## 许可证 - -MIT。