@rainbow-robotics/muscat-plugin-kit 0.1.2-dev.4 → 0.1.2-dev.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -16
- package/cli/README.md +5 -5
- package/cli/bin/create-muscat-plugin.mjs +1 -1
- package/cli/bin/muscat-pk.mjs +20 -10
- package/cli/bundle-templates.mjs +28 -0
- package/cli/docker/Dockerfile.bridge +17 -0
- package/cli/docker/Dockerfile.cpp +22 -0
- package/cli/docker/Dockerfile.dev +14 -0
- package/cli/docker/Dockerfile.python +20 -0
- package/cli/docker/bridge-package.json +8 -0
- package/cli/src/bridge.mjs +92 -0
- package/cli/src/build.mjs +398 -36
- package/cli/src/check-package.mjs +8 -23
- package/cli/src/cpp.mjs +61 -0
- package/cli/src/dev.mjs +16 -3
- package/cli/src/devBack.mjs +239 -53
- package/cli/src/devUi.mjs +118 -15
- package/cli/src/esbuild.mjs +51 -10
- package/cli/src/manifest.mjs +193 -0
- package/cli/src/new.mjs +168 -37
- package/cli/src/preview.mjs +91 -0
- package/cli/src/python.mjs +122 -0
- package/cli/src/ros2.mjs +90 -0
- package/cli/src/socketBridge.mjs +129 -0
- package/cli/src/templates-embedded.mjs +3 -0
- package/cli/src/type.mjs +105 -0
- package/cli/src/uninstall.mjs +98 -0
- package/cli/src/update.mjs +259 -30
- package/cli/src/util.mjs +97 -7
- package/cli/templates/common/README.md +383 -9
- package/cli/templates/common/manifest.json +13 -13
- package/cli/templates/common/package.json +5 -11
- package/cli/templates/common/py/main.py +88 -0
- package/cli/templates/common/requirements.txt +4 -0
- package/cli/templates/common/tsconfig.json +1 -1
- package/cli/templates/common/{src → ui}/content.tsx +3 -2
- package/cli/templates/common/vite.config.ts +22 -13
- package/cli/templates/cpp/cpp/CMakeLists.txt +14 -0
- package/cli/templates/cpp/cpp/main.cpp +25 -0
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/__init__.py +0 -0
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/node.py +25 -0
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/package.xml +10 -0
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/resource/__PLUGIN_SLUG__ +0 -0
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/setup.py +18 -0
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/CMakeLists.txt +17 -0
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/package.xml +11 -0
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/src/node.cpp +22 -0
- package/package.json +4 -4
- package/cli/src/pack.mjs +0 -58
- package/cli/templates/sdk/main.py +0 -21
- package/cli/templates/sdk/requirements.txt +0 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import rclpy
|
|
2
|
+
from rclpy.node import Node
|
|
3
|
+
from rainbow.rb_sdk import RBManipulateSDK # PyPI: rainbow-rb-sdk
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
sdk = RBManipulateSDK()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class __PLUGIN_CLASS__Node(Node):
|
|
10
|
+
def __init__(self):
|
|
11
|
+
super().__init__("__PLUGIN_SLUG___node")
|
|
12
|
+
self.get_logger().info("__PLUGIN_NAME__ node started")
|
|
13
|
+
# sdk is available here — use it alongside ROS2 topics as needed
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main(args=None):
|
|
17
|
+
rclpy.init(args=args)
|
|
18
|
+
node = __PLUGIN_CLASS__Node()
|
|
19
|
+
rclpy.spin(node)
|
|
20
|
+
node.destroy_node()
|
|
21
|
+
rclpy.shutdown()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
main()
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0"?>
|
|
2
|
+
<package format="3">
|
|
3
|
+
<name>__PLUGIN_SLUG__</name>
|
|
4
|
+
<version>0.0.1</version>
|
|
5
|
+
<description>__PLUGIN_NAME__ ROS2 node</description>
|
|
6
|
+
<maintainer email="todo@example.com">maintainer</maintainer>
|
|
7
|
+
<license>Proprietary</license>
|
|
8
|
+
<depend>rclpy</depend>
|
|
9
|
+
<export><build_type>ament_python</build_type></export>
|
|
10
|
+
</package>
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
|
|
3
|
+
package_name = "__PLUGIN_SLUG__"
|
|
4
|
+
|
|
5
|
+
setup(
|
|
6
|
+
name=package_name,
|
|
7
|
+
version="0.0.1",
|
|
8
|
+
packages=[package_name],
|
|
9
|
+
data_files=[
|
|
10
|
+
("share/ament_index/resource_index/packages", ["resource/" + package_name]),
|
|
11
|
+
("share/" + package_name, ["package.xml"]),
|
|
12
|
+
],
|
|
13
|
+
install_requires=["setuptools"],
|
|
14
|
+
zip_safe=True,
|
|
15
|
+
entry_points={
|
|
16
|
+
"console_scripts": ["__PLUGIN_SLUG___node = __PLUGIN_SLUG__.node:main"],
|
|
17
|
+
},
|
|
18
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.16)
|
|
2
|
+
project(__PLUGIN_SLUG__)
|
|
3
|
+
|
|
4
|
+
if(NOT CMAKE_CXX_STANDARD)
|
|
5
|
+
set(CMAKE_CXX_STANDARD 17)
|
|
6
|
+
endif()
|
|
7
|
+
|
|
8
|
+
find_package(ament_cmake REQUIRED)
|
|
9
|
+
find_package(rclcpp REQUIRED)
|
|
10
|
+
|
|
11
|
+
add_executable(__PLUGIN_SLUG___node src/node.cpp)
|
|
12
|
+
ament_target_dependencies(__PLUGIN_SLUG___node rclcpp)
|
|
13
|
+
|
|
14
|
+
install(TARGETS __PLUGIN_SLUG___node
|
|
15
|
+
DESTINATION lib/${PROJECT_NAME})
|
|
16
|
+
|
|
17
|
+
ament_package()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<?xml version="1.0"?>
|
|
2
|
+
<package format="3">
|
|
3
|
+
<name>__PLUGIN_SLUG__</name>
|
|
4
|
+
<version>0.0.1</version>
|
|
5
|
+
<description>__PLUGIN_NAME__ ROS2 node (rclcpp)</description>
|
|
6
|
+
<maintainer email="todo@example.com">maintainer</maintainer>
|
|
7
|
+
<license>Proprietary</license>
|
|
8
|
+
<buildtool_depend>ament_cmake</buildtool_depend>
|
|
9
|
+
<depend>rclcpp</depend>
|
|
10
|
+
<export><build_type>ament_cmake</build_type></export>
|
|
11
|
+
</package>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// __PLUGIN_NAME__ — ROS2 node (rclcpp).
|
|
2
|
+
//
|
|
3
|
+
// The node is launched with `--ros-args -r __ns:=/{slug}` automatically by
|
|
4
|
+
// dev:back. ROS2 topics are bridged to the plugin communication layer, so a
|
|
5
|
+
// plain rclcpp node is all you need — relative topic names get the namespace
|
|
6
|
+
// prefix applied automatically.
|
|
7
|
+
#include "rclcpp/rclcpp.hpp"
|
|
8
|
+
|
|
9
|
+
class __PLUGIN_CLASS__Node : public rclcpp::Node {
|
|
10
|
+
public:
|
|
11
|
+
__PLUGIN_CLASS__Node() : Node("__PLUGIN_SLUG___node") {
|
|
12
|
+
RCLCPP_INFO(this->get_logger(), "__PLUGIN_NAME__ node started");
|
|
13
|
+
// create publishers / subscribers / services here
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
int main(int argc, char** argv) {
|
|
18
|
+
rclcpp::init(argc, argv);
|
|
19
|
+
rclcpp::spin(std::make_shared<__PLUGIN_CLASS__Node>());
|
|
20
|
+
rclcpp::shutdown();
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rainbow-robotics/muscat-plugin-kit",
|
|
3
|
-
"version": "0.1.2-dev.
|
|
3
|
+
"version": "0.1.2-dev.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20"
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"@types/react-dom": "^19.0.4"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@rainbow-robotics/preview-host": "
|
|
35
|
-
"
|
|
34
|
+
"@rainbow-robotics/preview-host": "0.1.2-dev.41",
|
|
35
|
+
"socket.io": "^4.8.1"
|
|
36
36
|
},
|
|
37
37
|
"optionalDependencies": {
|
|
38
38
|
"esbuild-wasm": "^0.25.0"
|
|
39
39
|
}
|
|
40
|
-
}
|
|
40
|
+
}
|
package/cli/src/pack.mjs
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// muscat-pk pack — build, then create a distributable ZIP with a size report.
|
|
2
|
-
import { execSync } from "node:child_process";
|
|
3
|
-
import { existsSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
4
|
-
import { basename, resolve } from "node:path";
|
|
5
|
-
import { buildPlugin } from "./build.mjs";
|
|
6
|
-
import { findPluginRoot, humanSize, log } from "./util.mjs";
|
|
7
|
-
|
|
8
|
-
function dirSize(dir) {
|
|
9
|
-
let total = 0;
|
|
10
|
-
for (const entry of readdirSync(dir)) {
|
|
11
|
-
const full = resolve(dir, entry);
|
|
12
|
-
const st = statSync(full);
|
|
13
|
-
total += st.isDirectory() ? dirSize(full) : st.size;
|
|
14
|
-
}
|
|
15
|
-
return total;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export async function runPack() {
|
|
19
|
-
const pluginRoot = findPluginRoot();
|
|
20
|
-
await buildPlugin({ root: pluginRoot, minify: true });
|
|
21
|
-
|
|
22
|
-
const manifest = JSON.parse(
|
|
23
|
-
readFileSync(resolve(pluginRoot, "manifest.json"), "utf8"),
|
|
24
|
-
);
|
|
25
|
-
const zipName = `${basename(pluginRoot)}-${manifest.version || "0.0.0"}.zip`;
|
|
26
|
-
const zipPath = resolve(pluginRoot, zipName);
|
|
27
|
-
rmSync(zipPath, { force: true });
|
|
28
|
-
|
|
29
|
-
// Contents: dist/ + back-end files if present.
|
|
30
|
-
const entries = ["dist"];
|
|
31
|
-
for (const f of ["main.py", "requirements.txt"]) {
|
|
32
|
-
if (existsSync(resolve(pluginRoot, f))) entries.push(f);
|
|
33
|
-
}
|
|
34
|
-
if (existsSync(resolve(pluginRoot, "ros2_ws/install"))) {
|
|
35
|
-
entries.push("ros2_ws/install");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
log.step(`packing ${entries.join(", ")} → ${zipName}`);
|
|
39
|
-
try {
|
|
40
|
-
execSync(`zip -r -q "${zipPath}" ${entries.map((e) => `"${e}"`).join(" ")}`, {
|
|
41
|
-
cwd: pluginRoot,
|
|
42
|
-
stdio: "inherit",
|
|
43
|
-
});
|
|
44
|
-
} catch {
|
|
45
|
-
throw new Error("`zip` not found. Install zip or pack manually.");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const zipBytes = statSync(zipPath).size;
|
|
49
|
-
log.ok(`${zipName} ${humanSize(zipBytes)}`);
|
|
50
|
-
for (const e of entries) {
|
|
51
|
-
const full = resolve(pluginRoot, e);
|
|
52
|
-
const size = statSync(full).isDirectory() ? dirSize(full) : statSync(full).size;
|
|
53
|
-
log.info(` ├─ ${e} ${humanSize(size)}`);
|
|
54
|
-
}
|
|
55
|
-
log.warn(
|
|
56
|
-
"robot install checks free space via GET /plugin/capacity (507 if low).",
|
|
57
|
-
);
|
|
58
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
|
|
3
|
-
from rb_sdk import RBManipulateSDK # PyPI: rainbow-rb-sdk
|
|
4
|
-
|
|
5
|
-
sdk = RBManipulateSDK()
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
async def on_action(payload: dict):
|
|
9
|
-
# Matches manifest.actions[].topic — handle the "grip" action here.
|
|
10
|
-
width = payload.get("width")
|
|
11
|
-
print(f"[__PLUGIN_NAME__] grip width={width}")
|
|
12
|
-
# TODO: drive the robot via the SDK.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
async def main():
|
|
16
|
-
await sdk.subscribe("rby2/plugin/__PLUGIN_ID__/grip", on_action)
|
|
17
|
-
await sdk.spin()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if __name__ == "__main__":
|
|
21
|
-
asyncio.run(main())
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
rainbow-rb-sdk==__SDK_VERSION__
|