agenticros 0.1.8 → 0.1.10
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/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +36 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +39 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +7 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +54 -1
- package/dist/commands/up.js.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/menu.js +1 -1
- package/dist/menu.js.map +1 -1
- package/dist/util/profiles.d.ts +50 -0
- package/dist/util/profiles.d.ts.map +1 -0
- package/dist/util/profiles.js +173 -0
- package/dist/util/profiles.js.map +1 -0
- package/package.json +1 -1
- package/runtime/BUNDLE.json +1 -1
- package/runtime/ros2_ws/src/agenticros_sim/README.md +52 -13
- package/runtime/ros2_ws/src/agenticros_sim/config/arm_bridge.yaml +84 -0
- package/runtime/ros2_ws/src/agenticros_sim/config/arm_view.rviz +109 -0
- package/runtime/ros2_ws/src/agenticros_sim/launch/sim_arm.launch.py +223 -0
- package/runtime/ros2_ws/src/agenticros_sim/models/agenticros_amr/model.sdf +1 -1
- package/runtime/ros2_ws/src/agenticros_sim/models/agenticros_arm/model.config +26 -0
- package/runtime/ros2_ws/src/agenticros_sim/models/agenticros_arm/model.sdf +426 -0
- package/runtime/ros2_ws/src/agenticros_sim/urdf/agenticros_arm.urdf.xacro +205 -0
- package/runtime/ros2_ws/src/agenticros_sim/worlds/agenticros_indoor.sdf +1 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mode profile storage for AgenticROS.
|
|
3
|
+
*
|
|
4
|
+
* Profiles live at ~/.agenticros/profiles/<mode>.json. The active profile is
|
|
5
|
+
* copied into ~/.agenticros/config.json (which is what every adapter actually
|
|
6
|
+
* reads). Swapping profiles is what `agenticros config use <mode>` (and the
|
|
7
|
+
* up-runners) does so users can flip between real-robot and simulation
|
|
8
|
+
* without hand-editing JSON.
|
|
9
|
+
*
|
|
10
|
+
* Why profiles instead of a single config: the real robot and the sim AMR
|
|
11
|
+
* have different namespaces, transports, safety limits, and camera topics.
|
|
12
|
+
* Tracking both in one file requires the MCP server to know "which mode is
|
|
13
|
+
* active right now," which is exactly the problem `.mcp.json` env override
|
|
14
|
+
* already tried to solve - badly, because env vars unconditionally win and
|
|
15
|
+
* silently break the other mode. With profiles + a live ~/.agenticros/
|
|
16
|
+
* config.json, everything reads from one place; the CLI just swaps it.
|
|
17
|
+
*
|
|
18
|
+
* Profile bootstrap policy:
|
|
19
|
+
* * On first use, if ~/.agenticros/config.json exists but no profiles do,
|
|
20
|
+
* we treat the current config as the user's last-used mode and seed
|
|
21
|
+
* profiles from defaults for both modes (preserving any namespace the
|
|
22
|
+
* user already had for whichever mode matches it).
|
|
23
|
+
* * Otherwise we write the canonical defaults below.
|
|
24
|
+
*/
|
|
25
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import { getCliPaths } from "./paths.js";
|
|
28
|
+
export function profilesDir() {
|
|
29
|
+
return join(getCliPaths().userDataDir, "profiles");
|
|
30
|
+
}
|
|
31
|
+
export function profilePath(mode) {
|
|
32
|
+
return join(profilesDir(), `${mode}.json`);
|
|
33
|
+
}
|
|
34
|
+
export function activeConfigPath() {
|
|
35
|
+
return join(getCliPaths().userDataDir, "config.json");
|
|
36
|
+
}
|
|
37
|
+
export function modeMarkerPath() {
|
|
38
|
+
return join(getCliPaths().userDataDir, "active-mode");
|
|
39
|
+
}
|
|
40
|
+
export function readActiveMode() {
|
|
41
|
+
try {
|
|
42
|
+
const raw = readFileSync(modeMarkerPath(), "utf8").trim();
|
|
43
|
+
if (raw === "real" || raw === "sim")
|
|
44
|
+
return raw;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// No marker yet.
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Canonical real-robot profile. The namespace is intentionally a placeholder
|
|
53
|
+
* - users edit it once after `init` (or `config set robot.namespace=...`) to
|
|
54
|
+
* match their robot. We DO NOT bake in the workspace's example UUID because
|
|
55
|
+
* that gets shared in repos.
|
|
56
|
+
*/
|
|
57
|
+
function realProfileDefaults(namespaceFallback) {
|
|
58
|
+
return {
|
|
59
|
+
transport: { mode: "local" },
|
|
60
|
+
robot: {
|
|
61
|
+
namespace: namespaceFallback ?? "my_robot",
|
|
62
|
+
name: "Real Robot",
|
|
63
|
+
cameraTopic: "/camera/camera/color/image_raw",
|
|
64
|
+
},
|
|
65
|
+
safety: { maxLinearVelocity: 1.0, maxAngularVelocity: 1.5 },
|
|
66
|
+
teleop: { cmdVelTopic: "/cmd_vel", speedDefault: 0.3 },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Canonical sim-AMR profile. Mirrors ros2_ws/src/agenticros_sim/config/
|
|
71
|
+
* agenticros-sim.config.json - namespace MUST be empty because the sim
|
|
72
|
+
* bridge in amr_bridge.yaml publishes /cmd_vel, /odom, etc. at the graph
|
|
73
|
+
* root (no robot prefix). Setting a namespace here means Claude publishes
|
|
74
|
+
* into a void during simulation.
|
|
75
|
+
*/
|
|
76
|
+
function simProfileDefaults() {
|
|
77
|
+
return {
|
|
78
|
+
transport: { mode: "local" },
|
|
79
|
+
robot: {
|
|
80
|
+
namespace: "",
|
|
81
|
+
name: "Sim AMR",
|
|
82
|
+
cameraTopic: "/camera/camera/color/image_raw",
|
|
83
|
+
},
|
|
84
|
+
safety: { maxLinearVelocity: 0.5, maxAngularVelocity: 1.0 },
|
|
85
|
+
teleop: { cmdVelTopic: "/cmd_vel", speedDefault: 0.2 },
|
|
86
|
+
skills: {
|
|
87
|
+
followme: { depthTopic: "/camera/camera/depth/image_rect_raw" },
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function safeReadJson(p) {
|
|
92
|
+
try {
|
|
93
|
+
return JSON.parse(readFileSync(p, "utf8"));
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Ensure both real and sim profile files exist. Returns true if anything was
|
|
101
|
+
* written (so callers can log it).
|
|
102
|
+
*/
|
|
103
|
+
export function ensureProfilesExist() {
|
|
104
|
+
const dir = profilesDir();
|
|
105
|
+
mkdirSync(dir, { recursive: true });
|
|
106
|
+
let wrote = false;
|
|
107
|
+
const realPath = profilePath("real");
|
|
108
|
+
const simPath = profilePath("sim");
|
|
109
|
+
// Bootstrap: if a config.json already exists from before profiles existed,
|
|
110
|
+
// try to preserve whatever namespace the user had set. We don't know which
|
|
111
|
+
// mode that config represents, so we use the current namespace for the
|
|
112
|
+
// real-mode default (most users had a real-robot setup) and leave sim
|
|
113
|
+
// strictly empty.
|
|
114
|
+
let existingNs;
|
|
115
|
+
const active = activeConfigPath();
|
|
116
|
+
if (existsSync(active)) {
|
|
117
|
+
const cur = safeReadJson(active);
|
|
118
|
+
const ns = cur?.robot?.namespace;
|
|
119
|
+
if (typeof ns === "string" && ns.length > 0)
|
|
120
|
+
existingNs = ns;
|
|
121
|
+
}
|
|
122
|
+
if (!existsSync(realPath)) {
|
|
123
|
+
writeFileSync(realPath, JSON.stringify(realProfileDefaults(existingNs), null, 2) + "\n");
|
|
124
|
+
wrote = true;
|
|
125
|
+
}
|
|
126
|
+
if (!existsSync(simPath)) {
|
|
127
|
+
writeFileSync(simPath, JSON.stringify(simProfileDefaults(), null, 2) + "\n");
|
|
128
|
+
wrote = true;
|
|
129
|
+
}
|
|
130
|
+
return wrote;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Swap ~/.agenticros/config.json to the requested mode and persist the
|
|
134
|
+
* active-mode marker. Returns the absolute path to the active config.
|
|
135
|
+
*
|
|
136
|
+
* Idempotent: calling switchMode("sim") when sim is already active just
|
|
137
|
+
* re-copies the profile (cheap, ensures freshness).
|
|
138
|
+
*/
|
|
139
|
+
export function switchMode(mode) {
|
|
140
|
+
ensureProfilesExist();
|
|
141
|
+
const src = profilePath(mode);
|
|
142
|
+
const dst = activeConfigPath();
|
|
143
|
+
mkdirSync(getCliPaths().userDataDir, { recursive: true });
|
|
144
|
+
copyFileSync(src, dst);
|
|
145
|
+
writeFileSync(modeMarkerPath(), mode + "\n");
|
|
146
|
+
return dst;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Mutate a single field inside the profile JSON (e.g. real.robot.namespace).
|
|
150
|
+
* Use sparingly - profiles are normally edited by hand or via `agenticros
|
|
151
|
+
* config set` against the active config.
|
|
152
|
+
*/
|
|
153
|
+
export function patchProfile(mode, path, value) {
|
|
154
|
+
ensureProfilesExist();
|
|
155
|
+
const p = profilePath(mode);
|
|
156
|
+
const obj = safeReadJson(p) ?? {};
|
|
157
|
+
let cursor = obj;
|
|
158
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
159
|
+
const k = path[i];
|
|
160
|
+
const next = cursor[k];
|
|
161
|
+
if (next && typeof next === "object" && !Array.isArray(next)) {
|
|
162
|
+
cursor = next;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const o = {};
|
|
166
|
+
cursor[k] = o;
|
|
167
|
+
cursor = o;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
cursor[path[path.length - 1]] = value;
|
|
171
|
+
writeFileSync(p, JSON.stringify(obj, null, 2) + "\n");
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/util/profiles.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agenticros",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgenticROS - agentic AI for ROS-powered robots. Single CLI to launch real-robot or simulated demos, manage configuration, and inspect status.",
|
|
6
6
|
"keywords": [
|
package/runtime/BUNDLE.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"packedAt": "2026-06-
|
|
2
|
+
"packedAt": "2026-06-06T13:54:42.821Z",
|
|
3
3
|
"repo": "https://github.com/PlaiPin/agenticros",
|
|
4
4
|
"note": "This directory is a snapshot of the agenticros monorepo source. `agenticros init` will copy it to ~/agenticros and run pnpm install + colcon build there.",
|
|
5
5
|
"layout": {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# agenticros_sim
|
|
2
2
|
|
|
3
3
|
Gazebo Harmonic simulation assets for the AgenticROS project: an indoor world,
|
|
4
|
-
a 2-wheel diff-drive AMR
|
|
5
|
-
|
|
6
|
-
plugin already expects.
|
|
4
|
+
a 2-wheel diff-drive AMR (depth camera + 2D lidar + IMU), a 6-DOF UR5e-shaped
|
|
5
|
+
robotic arm, and a `ros_gz_bridge` config that exposes everything on the topic
|
|
6
|
+
names the real-robot plugin already expects.
|
|
7
7
|
|
|
8
8
|
## What's inside
|
|
9
9
|
|
|
@@ -11,13 +11,20 @@ plugin already expects.
|
|
|
11
11
|
agenticros_sim/
|
|
12
12
|
├── worlds/agenticros_indoor.sdf 12 x 12 m indoor room with obstacles
|
|
13
13
|
│ and one "person" target for follow-me
|
|
14
|
-
├── models/
|
|
15
|
-
│ ├──
|
|
16
|
-
│ └──
|
|
14
|
+
├── models/
|
|
15
|
+
│ ├── agenticros_amr/ 2-wheel diff-drive AMR with sensors
|
|
16
|
+
│ └── agenticros_arm/ 6-DOF UR5e-shaped robotic arm
|
|
17
|
+
├── urdf/
|
|
18
|
+
│ ├── agenticros_amr.urdf.xacro URDF mirror for RViz (AMR)
|
|
19
|
+
│ └── agenticros_arm.urdf.xacro URDF mirror for RViz (arm)
|
|
17
20
|
├── config/
|
|
18
|
-
│ ├── amr_bridge.yaml gz <-> ROS topic mapping
|
|
19
|
-
│
|
|
20
|
-
├──
|
|
21
|
+
│ ├── amr_bridge.yaml gz <-> ROS topic mapping (AMR)
|
|
22
|
+
│ ├── amr_view.rviz RViz config: camera, scan, TF
|
|
23
|
+
│ ├── arm_bridge.yaml gz <-> ROS topic mapping (arm)
|
|
24
|
+
│ └── arm_view.rviz RViz config: RobotModel + TF
|
|
25
|
+
├── launch/
|
|
26
|
+
│ ├── sim_amr.launch.py One-stop launcher (AMR)
|
|
27
|
+
│ └── sim_arm.launch.py One-stop launcher (arm)
|
|
21
28
|
├── env-hooks/ Add the package's share/ to GZ_SIM_RESOURCE_PATH
|
|
22
29
|
└── CMakeLists.txt + package.xml Standard ament_cmake skeleton
|
|
23
30
|
```
|
|
@@ -26,18 +33,50 @@ agenticros_sim/
|
|
|
26
33
|
|
|
27
34
|
```bash
|
|
28
35
|
# Easiest: use the agenticros CLI (handles ROS sourcing + workspace build).
|
|
29
|
-
agenticros up sim-amr # GUI
|
|
30
|
-
agenticros up sim-amr --rviz # GUI + RViz panel
|
|
31
|
-
agenticros up sim-
|
|
36
|
+
agenticros up sim-amr # AMR: GUI
|
|
37
|
+
agenticros up sim-amr --rviz # AMR: GUI + RViz panel
|
|
38
|
+
agenticros up sim-arm # Arm: GUI
|
|
39
|
+
agenticros up sim-arm --rviz # Arm: GUI + RViz (RobotModel + TF)
|
|
32
40
|
|
|
33
|
-
# Or run the launch
|
|
41
|
+
# Or run the launch files directly:
|
|
34
42
|
cd ros2_ws && colcon build --symlink-install --packages-select agenticros_sim
|
|
35
43
|
source install/setup.bash
|
|
36
44
|
ros2 launch agenticros_sim sim_amr.launch.py
|
|
37
45
|
ros2 launch agenticros_sim sim_amr.launch.py use_rviz:=true
|
|
38
46
|
ros2 launch agenticros_sim sim_amr.launch.py gui:=false # headless
|
|
47
|
+
ros2 launch agenticros_sim sim_arm.launch.py
|
|
48
|
+
ros2 launch agenticros_sim sim_arm.launch.py use_rviz:=true
|
|
39
49
|
```
|
|
40
50
|
|
|
51
|
+
## Arm topic layout
|
|
52
|
+
|
|
53
|
+
The arm exposes one position-command topic per joint plus the usual
|
|
54
|
+
`/joint_states`, `/tf`, and `/clock`. Send a target angle in radians as a
|
|
55
|
+
`std_msgs/Float64` and the PD controller drives the joint there.
|
|
56
|
+
|
|
57
|
+
| Topic | Type | Direction |
|
|
58
|
+
|------------------------------------|-------------------------------|-----------|
|
|
59
|
+
| `/arm/shoulder_pan/cmd_pos` | `std_msgs/msg/Float64` | ROS -> GZ |
|
|
60
|
+
| `/arm/shoulder_lift/cmd_pos` | `std_msgs/msg/Float64` | ROS -> GZ |
|
|
61
|
+
| `/arm/elbow/cmd_pos` | `std_msgs/msg/Float64` | ROS -> GZ |
|
|
62
|
+
| `/arm/wrist_1/cmd_pos` | `std_msgs/msg/Float64` | ROS -> GZ |
|
|
63
|
+
| `/arm/wrist_2/cmd_pos` | `std_msgs/msg/Float64` | ROS -> GZ |
|
|
64
|
+
| `/arm/wrist_3/cmd_pos` | `std_msgs/msg/Float64` | ROS -> GZ |
|
|
65
|
+
| `/joint_states` | `sensor_msgs/msg/JointState` | GZ -> ROS |
|
|
66
|
+
| `/tf`, `/tf_static` | `tf2_msgs/msg/TFMessage` | GZ -> ROS |
|
|
67
|
+
| `/clock` | `rosgraph_msgs/msg/Clock` | GZ -> ROS |
|
|
68
|
+
|
|
69
|
+
Example - wave the elbow back and forth from the command line:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
ros2 topic pub /arm/elbow/cmd_pos std_msgs/msg/Float64 'data: 1.0' --once
|
|
73
|
+
sleep 2
|
|
74
|
+
ros2 topic pub /arm/elbow/cmd_pos std_msgs/msg/Float64 'data: -0.5' --once
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The same via an MCP `ros2_publish` tool call from Claude / Codex / Gemini works
|
|
78
|
+
identically.
|
|
79
|
+
|
|
41
80
|
## Topic layout
|
|
42
81
|
|
|
43
82
|
The bridge YAML deliberately matches the real-robot AgenticROS plugin's topic
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# arm_bridge.yaml
|
|
2
|
+
#
|
|
3
|
+
# Bridge config for the 6-DOF agenticros_arm sim. Feeds ros_gz_bridge's
|
|
4
|
+
# parameter_bridge so Gazebo Harmonic topics produced by the arm's
|
|
5
|
+
# JointPositionController + JointStatePublisher + PosePublisher plugins
|
|
6
|
+
# are exposed as the ROS 2 topics agent code expects.
|
|
7
|
+
#
|
|
8
|
+
# Direction notation:
|
|
9
|
+
# GZ_TO_ROS — gazebo publishes, ROS subscribes (joint feedback, TF, clock)
|
|
10
|
+
# ROS_TO_GZ — ROS publishes, gazebo subscribes (joint commands)
|
|
11
|
+
# BIDIRECTIONAL — rarely needed
|
|
12
|
+
#
|
|
13
|
+
# Topic naming convention: /arm/<joint>/cmd_pos for joint commands. Same
|
|
14
|
+
# naming pattern across all six joints so a Claude / Codex / Gemini
|
|
15
|
+
# `ros2_publish` tool call only needs to vary the joint name.
|
|
16
|
+
|
|
17
|
+
# ---------------- Clock (GZ -> ROS) ----------------
|
|
18
|
+
- ros_topic_name: "/clock"
|
|
19
|
+
gz_topic_name: "/clock"
|
|
20
|
+
ros_type_name: "rosgraph_msgs/msg/Clock"
|
|
21
|
+
gz_type_name: "gz.msgs.Clock"
|
|
22
|
+
direction: GZ_TO_ROS
|
|
23
|
+
|
|
24
|
+
# ---------------- /tf (GZ -> ROS) ----------------
|
|
25
|
+
- ros_topic_name: "/tf"
|
|
26
|
+
gz_topic_name: "/model/agenticros_arm/pose"
|
|
27
|
+
ros_type_name: "tf2_msgs/msg/TFMessage"
|
|
28
|
+
gz_type_name: "gz.msgs.Pose_V"
|
|
29
|
+
direction: GZ_TO_ROS
|
|
30
|
+
|
|
31
|
+
- ros_topic_name: "/tf_static"
|
|
32
|
+
gz_topic_name: "/model/agenticros_arm/pose_static"
|
|
33
|
+
ros_type_name: "tf2_msgs/msg/TFMessage"
|
|
34
|
+
gz_type_name: "gz.msgs.Pose_V"
|
|
35
|
+
direction: GZ_TO_ROS
|
|
36
|
+
|
|
37
|
+
# ---------------- Joint feedback (GZ -> ROS) ----------------
|
|
38
|
+
# robot_state_publisher consumes this to update the URDF transforms in
|
|
39
|
+
# RViz and to publish per-link /tf entries. The gz topic name matches the
|
|
40
|
+
# <topic>joint_states</topic> field on the SDF's JointStatePublisher
|
|
41
|
+
# plugin (gz-sim treats that as the literal topic, no model prefix).
|
|
42
|
+
- ros_topic_name: "/joint_states"
|
|
43
|
+
gz_topic_name: "/joint_states"
|
|
44
|
+
ros_type_name: "sensor_msgs/msg/JointState"
|
|
45
|
+
gz_type_name: "gz.msgs.Model"
|
|
46
|
+
direction: GZ_TO_ROS
|
|
47
|
+
|
|
48
|
+
# ---------------- Joint position commands (ROS -> GZ) ----------------
|
|
49
|
+
# Send std_msgs/Float64 (radians) to any of these to drive a joint.
|
|
50
|
+
- ros_topic_name: "/arm/shoulder_pan/cmd_pos"
|
|
51
|
+
gz_topic_name: "/arm/shoulder_pan/cmd_pos"
|
|
52
|
+
ros_type_name: "std_msgs/msg/Float64"
|
|
53
|
+
gz_type_name: "gz.msgs.Double"
|
|
54
|
+
direction: ROS_TO_GZ
|
|
55
|
+
|
|
56
|
+
- ros_topic_name: "/arm/shoulder_lift/cmd_pos"
|
|
57
|
+
gz_topic_name: "/arm/shoulder_lift/cmd_pos"
|
|
58
|
+
ros_type_name: "std_msgs/msg/Float64"
|
|
59
|
+
gz_type_name: "gz.msgs.Double"
|
|
60
|
+
direction: ROS_TO_GZ
|
|
61
|
+
|
|
62
|
+
- ros_topic_name: "/arm/elbow/cmd_pos"
|
|
63
|
+
gz_topic_name: "/arm/elbow/cmd_pos"
|
|
64
|
+
ros_type_name: "std_msgs/msg/Float64"
|
|
65
|
+
gz_type_name: "gz.msgs.Double"
|
|
66
|
+
direction: ROS_TO_GZ
|
|
67
|
+
|
|
68
|
+
- ros_topic_name: "/arm/wrist_1/cmd_pos"
|
|
69
|
+
gz_topic_name: "/arm/wrist_1/cmd_pos"
|
|
70
|
+
ros_type_name: "std_msgs/msg/Float64"
|
|
71
|
+
gz_type_name: "gz.msgs.Double"
|
|
72
|
+
direction: ROS_TO_GZ
|
|
73
|
+
|
|
74
|
+
- ros_topic_name: "/arm/wrist_2/cmd_pos"
|
|
75
|
+
gz_topic_name: "/arm/wrist_2/cmd_pos"
|
|
76
|
+
ros_type_name: "std_msgs/msg/Float64"
|
|
77
|
+
gz_type_name: "gz.msgs.Double"
|
|
78
|
+
direction: ROS_TO_GZ
|
|
79
|
+
|
|
80
|
+
- ros_topic_name: "/arm/wrist_3/cmd_pos"
|
|
81
|
+
gz_topic_name: "/arm/wrist_3/cmd_pos"
|
|
82
|
+
ros_type_name: "std_msgs/msg/Float64"
|
|
83
|
+
gz_type_name: "gz.msgs.Double"
|
|
84
|
+
direction: ROS_TO_GZ
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Panels:
|
|
2
|
+
- Class: rviz_common/Displays
|
|
3
|
+
Help Height: 0
|
|
4
|
+
Name: Displays
|
|
5
|
+
Property Tree Widget:
|
|
6
|
+
Expanded:
|
|
7
|
+
- /TF1
|
|
8
|
+
- /RobotModel1
|
|
9
|
+
Splitter Ratio: 0.5
|
|
10
|
+
Tree Height: 600
|
|
11
|
+
- Class: rviz_common/Views
|
|
12
|
+
Expanded:
|
|
13
|
+
- /Current View1
|
|
14
|
+
Name: Views
|
|
15
|
+
Splitter Ratio: 0.5
|
|
16
|
+
Visualization Manager:
|
|
17
|
+
Class: ""
|
|
18
|
+
Displays:
|
|
19
|
+
- Alpha: 0.5
|
|
20
|
+
Cell Size: 0.5
|
|
21
|
+
Class: rviz_default_plugins/Grid
|
|
22
|
+
Color: 160; 160; 164
|
|
23
|
+
Enabled: true
|
|
24
|
+
Line Style:
|
|
25
|
+
Line Width: 0.03
|
|
26
|
+
Value: Lines
|
|
27
|
+
Name: Grid
|
|
28
|
+
Normal Cell Count: 0
|
|
29
|
+
Offset:
|
|
30
|
+
X: 0
|
|
31
|
+
Y: 0
|
|
32
|
+
Z: 0
|
|
33
|
+
Plane: XY
|
|
34
|
+
Plane Cell Count: 12
|
|
35
|
+
Reference Frame: <Fixed Frame>
|
|
36
|
+
Value: true
|
|
37
|
+
- Class: rviz_default_plugins/TF
|
|
38
|
+
Enabled: true
|
|
39
|
+
Frame Timeout: 15
|
|
40
|
+
Frames:
|
|
41
|
+
All Enabled: true
|
|
42
|
+
Marker Scale: 0.15
|
|
43
|
+
Name: TF
|
|
44
|
+
Show Arrows: true
|
|
45
|
+
Show Axes: true
|
|
46
|
+
Show Names: true
|
|
47
|
+
Update Interval: 0
|
|
48
|
+
Value: true
|
|
49
|
+
- Alpha: 1
|
|
50
|
+
Class: rviz_default_plugins/RobotModel
|
|
51
|
+
Collision Enabled: false
|
|
52
|
+
Description File: ""
|
|
53
|
+
Description Source: Topic
|
|
54
|
+
Description Topic:
|
|
55
|
+
Depth: 5
|
|
56
|
+
Durability Policy: Volatile
|
|
57
|
+
History Policy: Keep Last
|
|
58
|
+
Reliability Policy: Reliable
|
|
59
|
+
Value: /robot_description
|
|
60
|
+
Enabled: true
|
|
61
|
+
Mass Properties:
|
|
62
|
+
Inertia: false
|
|
63
|
+
Mass: false
|
|
64
|
+
Name: RobotModel
|
|
65
|
+
TF Prefix: ""
|
|
66
|
+
Update Interval: 0
|
|
67
|
+
Value: true
|
|
68
|
+
Visual Enabled: true
|
|
69
|
+
Enabled: true
|
|
70
|
+
Global Options:
|
|
71
|
+
Background Color: 48; 48; 48
|
|
72
|
+
Fixed Frame: base_link
|
|
73
|
+
Frame Rate: 30
|
|
74
|
+
Name: root
|
|
75
|
+
Tools:
|
|
76
|
+
- Class: rviz_default_plugins/Interact
|
|
77
|
+
Hide Inactive Objects: true
|
|
78
|
+
- Class: rviz_default_plugins/MoveCamera
|
|
79
|
+
- Class: rviz_default_plugins/Select
|
|
80
|
+
- Class: rviz_default_plugins/FocusCamera
|
|
81
|
+
- Class: rviz_default_plugins/Measure
|
|
82
|
+
Line color: 128; 128; 0
|
|
83
|
+
Transformation:
|
|
84
|
+
Current:
|
|
85
|
+
Class: rviz_default_plugins/TF
|
|
86
|
+
Value: true
|
|
87
|
+
Views:
|
|
88
|
+
Current:
|
|
89
|
+
Class: rviz_default_plugins/Orbit
|
|
90
|
+
Distance: 2.5
|
|
91
|
+
Enable Stereo Rendering:
|
|
92
|
+
Stereo Eye Separation: 0.0599999987
|
|
93
|
+
Stereo Focal Distance: 1
|
|
94
|
+
Swap Stereo Eyes: false
|
|
95
|
+
Value: false
|
|
96
|
+
Focal Point:
|
|
97
|
+
X: 0.4
|
|
98
|
+
Y: 0
|
|
99
|
+
Z: 0.4
|
|
100
|
+
Focal Shape Fixed Size: true
|
|
101
|
+
Focal Shape Size: 0.05
|
|
102
|
+
Invert Z Axis: false
|
|
103
|
+
Name: Current View
|
|
104
|
+
Near Clip Distance: 0.01
|
|
105
|
+
Pitch: 0.35
|
|
106
|
+
Target Frame: base_link
|
|
107
|
+
Value: Orbit (rviz)
|
|
108
|
+
Yaw: 0.785
|
|
109
|
+
Saved: ~
|