-
Notifications
You must be signed in to change notification settings - Fork 15
Add hand_eye_calibration_sim config #873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| cmake_minimum_required(VERSION 3.22) | ||
| project(hand_eye_calibration_sim) | ||
|
|
||
| find_package(ament_cmake REQUIRED) | ||
| find_package(picknik_accessories REQUIRED) | ||
|
|
||
|
|
||
| # Install all XML files in directory | ||
| set(PICKNIK_ACCESSORIES_SHARE_DIR | ||
| "${CMAKE_INSTALL_PREFIX}/../picknik_accessories/share/picknik_accessories/mujoco_assets/" | ||
| ) | ||
| # Destination directory | ||
| set(DEST_DIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/description/") | ||
|
|
||
| install(DIRECTORY "${PICKNIK_ACCESSORIES_SHARE_DIR}" | ||
| DESTINATION "${DEST_DIR}" | ||
| FILES_MATCHING PATTERN "*") | ||
|
|
||
| install( | ||
| DIRECTORY | ||
| config | ||
| description | ||
| launch | ||
| objectives | ||
| waypoints | ||
| DESTINATION | ||
| share/${PROJECT_NAME} | ||
| ) | ||
|
|
||
| if(BUILD_TESTING) | ||
| find_package(ament_lint_auto REQUIRED) | ||
| ament_lint_auto_find_test_dependencies() | ||
| endif() | ||
|
|
||
| ament_package() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Any contribution that you make to this repository will | ||
| be under the 3-Clause BSD License, as dictated by that | ||
| [license](https://opensource.org/licenses/BSD-3-Clause). | ||
|
|
||
| # Contributing to this Repository | ||
|
|
||
| Thanks for getting involved! If you want to add to this repository, please reach out to support@picknik.ai. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| Redistribution and use in source and binary forms, with or without | ||
| modification, are permitted provided that the following conditions are met: | ||
|
Comment on lines
+1
to
+2
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Add the package copyright notice. This BSD-3-Clause file starts with the license conditions but does not identify a copyright holder. Add the repository-approved copyright line at the top, consistent with 🤖 Prompt for AI Agents |
||
|
|
||
| * Redistributions of source code must retain the above copyright | ||
| notice, this list of conditions and the following disclaimer. | ||
|
|
||
| * Redistributions in binary form must reproduce the above copyright | ||
| notice, this list of conditions and the following disclaimer in the | ||
| documentation and/or other materials provided with the distribution. | ||
|
|
||
| * Neither the name of the copyright holder nor the names of its | ||
| contributors may be used to endorse or promote products derived from | ||
| this software without specific prior written permission. | ||
|
|
||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| POSSIBILITY OF SUCH DAMAGE. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| # hand_eye_calibration_sim | ||
|
|
||
| A MoveIt Pro simulation for validating hand-eye camera calibration. The scene | ||
| mirrors a mixed-mode multi-camera setup: a wrist-mounted camera (eye-in-hand) | ||
| that observes a world-fixed ChArUco board, and two fixed scene cameras | ||
| (eye-to-hand) that observe a ChArUco board rigidly mounted to the robot wrist. | ||
| Every camera and board pose is a designed value in the MJCF, so calibration | ||
| results can be asserted against exact ground truth. | ||
|
|
||
| The package is hidden from the user-facing configuration list via | ||
| `MOVEIT_PRO_IGNORE`; it exists for QA of the calibration Behaviors and | ||
| Objectives (moveit_pro issues #19835, #20570, #20572). | ||
|
|
||
| ## ChArUco boards | ||
|
|
||
| Generated by `scripts/generate_charuco_boards.py` (run it inside the dev | ||
| container to regenerate the PNGs in `description/assets/`). The two boards use | ||
| distinct dictionaries so detections stay unambiguous when a camera sees both. | ||
| These parameters are the intended defaults for the `DetectCharucoBoard` | ||
| Behavior ports. | ||
|
|
||
| | Board | Dictionary | Squares (x by y) | Square size | Marker size | Physical size | | ||
| |---|---|---|---|---|---| | ||
| | World board | `DICT_4X4_50` | 7 by 5 | 0.035 m | 0.026 m | 0.245 x 0.175 m | | ||
| | Flange board | `DICT_5X5_50` | 5 by 4 | 0.030 m | 0.022 m | 0.150 x 0.120 m | | ||
|
|
||
| The textures are drawn with `marginSize=0`, so the chessboard exactly spans the | ||
| plate geom's top face: interior corner `(i, j)` sits at | ||
| `(i * square_length, j * square_length)` from the plate corner. The in-plane | ||
| orientation of the texture on the plate (which plate corner is the OpenCV board | ||
| origin) must be pinned empirically from a rendered image when the calibration | ||
| QA objectives land; only the plate poses below are designed values. | ||
|
Comment on lines
+27
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(README\.md|.*(charuco|chess|board|texture|calib).*)$' | head -200
printf '%s\n' '--- README outline ---'
ast-grep outline src/hand_eye_calibration_sim/README.md 2>/dev/null || true
printf '%s\n' '--- README lines ---'
cat -n src/hand_eye_calibration_sim/README.md | sed -n '1,120p'
printf '%s\n' '--- relevant references ---'
rg -n -i -C 3 'world_board|flange_board|marginSize|square_length|OpenCV board|ChArUco|chessboard|texture|calibration' . --glob '!node_modules' --glob '!build' --glob '!dist' | head -400Repository: PickNikRobotics/moveit_pro_example_ws Length of output: 42289 🏁 Script executed: #!/bin/bash
set -e
for f in \
src/hand_eye_calibration_sim/scripts/generate_charuco_boards.py \
src/hand_eye_calibration_sim/description/scene.xml \
src/hand_eye_calibration_sim/description/ur5e_hand_eye.xml; do
printf '\n--- %s ---\n' "$f"
wc -l "$f"
ast-grep outline "$f" 2>/dev/null || true
done
printf '\n--- generator ---\n'
cat -n src/hand_eye_calibration_sim/scripts/generate_charuco_boards.py
printf '\n--- scene board-related sections ---\n'
rg -n -C 12 'charuco|board|plate|world_board|flange_board|top' src/hand_eye_calibration_sim/description/scene.xml
printf '\n--- hand-eye board-related sections ---\n'
rg -n -C 12 'charuco|board|plate|flange_board|top' src/hand_eye_calibration_sim/description/ur5e_hand_eye.xml
printf '\n--- asset metadata ---\n'
file src/hand_eye_calibration_sim/description/assets/charuco_world_board.png \
src/hand_eye_calibration_sim/description/assets/charuco_flange_board.pngRepository: PickNikRobotics/moveit_pro_example_ws Length of output: 15759 🏁 Script executed: #!/bin/bash
set -e
python3 - <<'PY'
from pathlib import Path
import struct, zlib
import xml.etree.ElementTree as ET
root = Path("src/hand_eye_calibration_sim")
for name, expected in [
("description/assets/charuco_world_board.png", (1400, 1000)),
("description/assets/charuco_flange_board.png", (1000, 800)),
]:
p = root / name
data = p.read_bytes()
assert data[:8] == b"\x89PNG\r\n\x1a\n", name
w, h, depth, color, *_ = struct.unpack(">IIBBBBB", data[16:29])
print(name, "dimensions=", (w, h), "bit_depth=", depth, "color_type=", color)
assert (w, h) == expected
pos = 8
idat = b""
while pos < len(data):
n = struct.unpack(">I", data[pos:pos+4])[0]
typ = data[pos+4:pos+8]
chunk = data[pos+8:pos+8+n]
pos += 12 + n
if typ == b"IDAT":
idat += chunk
if typ == b"IEND":
break
raw = zlib.decompress(idat)
channels = {0: 1, 2: 3, 3: 1, 4: 2, 6: 4}[color]
stride = w * channels
rows = []
i = 0
prev = bytearray(stride)
for y in range(h):
filt = raw[i]; i += 1
row = bytearray(raw[i:i+stride]); i += stride
# PNG unfilter for the generated 8-bit grayscale/RGB image.
for x in range(stride):
a = row[x-channels] if x >= channels else 0
b = prev[x]
c = prev[x-channels] if x >= channels else 0
if filt == 1: row[x] = (row[x] + a) & 255
elif filt == 2: row[x] = (row[x] + b) & 255
elif filt == 3: row[x] = (row[x] + ((a+b)//2)) & 255
elif filt == 4:
p0 = a + b - c
pa, pb, pc = abs(p0-a), abs(p0-b), abs(p0-c)
row[x] = (row[x] + (a if pa <= pb and pa <= pc else b if pb <= pc else c)) & 255
elif filt != 0: raise ValueError(f"unsupported filter {filt}")
rows.append(row)
prev = row
def px(x, y):
vals = rows[y][x*channels:(x+1)*channels]
return tuple(vals)
print(" corners:", {k: px(*xy) for k, xy in {
"top_left": (0,0), "top_right": (w-1,0),
"bottom_left": (0,h-1), "bottom_right": (w-1,h-1),
"center": (w//2,h//2)}.items()})
# Sample each square center. This identifies the alternating pattern
# and the image's top/bottom convention without decoding repository code.
sx, sy = expected[0] // (7 if "world" in name else 5), expected[1] // (5 if "world" in name else 4)
print(" square-center luminance samples:",
[[px((x*2+1)*sx//2, (y*2+1)*sy//2)[0]
for x in range(expected[0]//sx)] for y in range(expected[1]//sy)])
for xml_name in ["description/scene.xml", "description/ur5e_hand_eye.xml"]:
text = (root / xml_name).read_text()
print(xml_name, "texture references:",
[line.strip() for line in text.splitlines() if "texture=" in line or 'file="assets/charuco' in line])
PYRepository: PickNikRobotics/moveit_pro_example_ws Length of output: 1102 🌐 Web query:
💡 Result: In MuJoCo, using a 2D texture on a box geom results in automatic, non-uniform mapping that often causes visual stretching on four of the six faces [1][2]. The default 2D texture coordinate generator maps a 2D image to 3D space by projecting it [1][2]. For a box geom, the two faces whose normals are aligned with the Z-axis of the geom's local frame appear normal, while the other four faces (sides) appear stretched because the texture coordinates are essentially projected along the Z-axis [1][2]. Consequently, you cannot explicitly configure the 2D texture coordinates for a primitive box geom in the XML; the mapping is determined by the automatic generator [1][2]. If you require precise control over texture coordinates (e.g., to prevent stretching or orient the texture specifically on each face), you must use a mesh geom instead of a primitive box [3][4]. Mesh geoms allow you to provide explicit texture coordinates via OBJ or MSH files, which take priority over any automatic mapping mechanisms [3][5]. You can define these coordinates in an external modeling tool and export them as part of the mesh file [3][4]. For controlling the scale of the 2D texture, you can use the texrepeat attribute within the material element [1][2]. Additionally, if a 2D texture is unsuitable for your needs, consider using a cube texture, which is specifically designed to handle all sides of a box without the stretching artifacts common to 2D projections [1][2]. Citations:
🌐 Web query:
💡 Result: In OpenCV, the coordinate system for a ChArUco board is located in the board plane, centered at the bottom-left corner of the board [1][2]. The orientation is such that the X and Y axes lie within the plane of the board, and the Z axis is perpendicular to it [1][2]. Important developments to note regarding the coordinate system and orientation: 1. Incompatible Change (OpenCV 4.6.0+): As of OpenCV 4.6.0, there was a breaking change in the coordinate system [1][2]. Prior to this version, the Z-axis pointed out of the board plane [3][4][5]. In version 4.6.0 and later, the Z-axis points into the board plane [1][2]. This change affects pose estimation results [6]. 2. Axis Drawing: You can visualize this coordinate system using the Citations:
Pin and validate the ChArUco board-frame mapping. The MJCF defines plate poses, but it does not define which plate corner maps to the OpenCV board origin. Document the image-to-geom axis mapping and validate it from a rendered image before using 🤖 Prompt for AI Agents |
||
|
|
||
| ## Ground-truth transforms | ||
|
|
||
| All values are exactly as placed in the MJCF (`description/scene.xml` and | ||
| `description/ur5e_hand_eye.xml`). Rotations are given exactly as they appear in | ||
| the MJCF: quaternions in MuJoCo (w, x, y, z) order where the MJCF uses `quat`, | ||
| euler angles (radians, extrinsic x-y-z) where it uses `euler`. Optical frames | ||
| follow REP 103 (the camera pose rotated 180 degrees about its x-axis). | ||
|
|
||
| | Frame | Relative to | Position (m) | Rotation | | ||
| |---|---|---|---| | ||
| | `wrist_camera_optical_frame` | `wrist_3_link` | (0, 0.2, 0.05) | euler (-1.57, 0, 0) | | ||
| | `scene_camera_1_optical_frame` | world | (0.917266, 1.074437, 1.861509) | quat (0.233342, -0.306871, -0.734484, 0.558494) | | ||
| | `scene_camera_2_optical_frame` | world | (-0.401516, 1.072484, 1.82102) | quat (0.244002, -0.306655, 0.719923, -0.572833) | | ||
| | `world_board` (plate center) | world | (0.266, 0.650113, 0.665599) | quat (0.972489, 0.232951, 0, 0) | | ||
| | `flange_board` (plate center) | `wrist_3_link` | (0, 0.14, 0.16) | euler (0.6435, 0, 0) | | ||
|
|
||
| The board top faces (the textured faces) are at +0.004 m along each plate's | ||
| local z-axis; sites `world_board_top` and `flange_board_top` mark them. | ||
|
|
||
| Expected calibration results: | ||
|
|
||
| - Eye-in-hand: the wrist camera extrinsic must recover | ||
| `wrist_3_link -> wrist_camera_optical_frame`, and the fiducial mount must | ||
| recover the world board pose. | ||
| - Eye-to-hand: each scene camera extrinsic must recover that camera's pose in | ||
| the robot base frame, and the fiducial mount must recover | ||
| `wrist_3_link -> flange_board`. The scene camera poses above are world-frame | ||
| values; convert through the robot's base pose (which depends on the linear | ||
| rail position) when asserting in the base frame. | ||
|
|
||
| ## Notes | ||
|
|
||
| - The wrist camera pose is fixed by the shared ur5e model in | ||
| `picknik_accessories`; `description/ur5e_hand_eye.xml` is a copy of that | ||
| model that adds only the rigidly attached flange board (MJCF includes are | ||
| textual, so the board cannot be attached from the scene file, and a weld | ||
| constraint would be soft and corrupt the ground truth). | ||
| - All cameras render at 1280x720 with `fovy` 58 degrees; the offscreen buffer | ||
| must match every camera resolution exactly. | ||
| - Both board plates have contact disabled. They are calibration targets and | ||
| are not part of the URDF, so the motion planner does not know about them. | ||
|
|
||
| For detailed documentation see: [MoveIt Pro Documentation](https://docs.picknik.ai/) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # | ||
| # This contains information for a unique instance of a robot. | ||
| # | ||
|
|
||
| # Name of the package to specialize | ||
| based_on_package: "lab_sim" | ||
| runtime_launch_file: | ||
| package: "hand_eye_calibration_sim" | ||
| path: "launch/runtime.launch.xml" | ||
| hardware: | ||
| # Parameters used to configure the robot description through XACRO. | ||
| # A URDF and SRDF are both required. | ||
| # [Required] | ||
| robot_description: | ||
| urdf: | ||
| package: "lab_sim" | ||
| path: "description/picknik_ur.xacro" | ||
| srdf: | ||
| package: "lab_sim" | ||
| path: "config/moveit/picknik_ur.srdf" | ||
| urdf_params: | ||
| - mujoco_model_package: "hand_eye_calibration_sim" | ||
| # Configuration for loading behaviors and objectives. | ||
| # [Required] | ||
| objectives: | ||
| # Specify source folder for objectives | ||
| # [Required] | ||
| objective_library_paths: | ||
| mujoco_objectives: | ||
| package_name: "moveit_pro_objectives" | ||
| relative_path: "objectives/mujoco" | ||
| sim_objectives: | ||
| package_name: "hand_eye_calibration_sim" | ||
| relative_path: "objectives" | ||
| # Specify the location of the saved waypoints file. | ||
| # [Required] | ||
| waypoints_file: | ||
| package_name: "hand_eye_calibration_sim" | ||
| relative_path: "waypoints/ur_waypoints.yaml" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| Copyright 2018 ROS Industrial Consortium | ||
|
|
||
| Redistribution and use in source and binary forms, with or without modification, | ||
| are permitted provided that the following conditions are met: | ||
|
|
||
| 1. Redistributions of source code must retain the above copyright notice, this | ||
| list of conditions and the following disclaimer. | ||
|
|
||
| 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| this list of conditions and the following disclaimer in the documentation and/or | ||
| other materials provided with the distribution. | ||
|
|
||
| 3. Neither the name of the copyright holder nor the names of its contributors | ||
| may be used to endorse or promote products derived from this software without | ||
| specific prior written permission. | ||
|
|
||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | ||
| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
| ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| <!-- Hand-eye calibration QA scene: UR5e on a linear rail with a wrist camera | ||
| (eye-in-hand), two fixed scene cameras (eye-to-hand), a world-fixed | ||
| ChArUco board, and a wrist-mounted ChArUco board. The camera and board | ||
| poses below are the calibration ground truth; they are documented in the | ||
| package README and asserted by the calibration QA objectives. --> | ||
| <mujoco model="ur5e hand eye calibration scene"> | ||
| <include file="ur5e/ur5e_linear_rail_globals.xml" /> | ||
| <include file="lab_desk/desk_globals.xml" /> | ||
| <include file="robotiq_2f85/robotiq2f85_globals.xml" /> | ||
|
|
||
| <compiler angle="radian" autolimits="true" /> | ||
|
|
||
| <option integrator="implicitfast" timestep="0.003" /> | ||
|
|
||
| <!-- Offscreen buffer must EXACTLY match every non-lidar camera resolution | ||
| (picknik_mujoco_ros cameras.cpp). Single shared buffer for all cameras, | ||
| so scene_camera_1 and scene_camera_2 below plus wrist_camera (1280x720) | ||
| from the ur5e include must all be 1280x720, or ros2_control_node aborts | ||
| on load. --> | ||
| <visual> | ||
| <global offwidth="1280" offheight="720" /> | ||
| </visual> | ||
|
|
||
| <asset> | ||
| <!-- ChArUco board textures, generated by scripts/generate_charuco_boards.py. | ||
| The world board is DICT_4X4_50 7x5 squares (square 0.035 m, marker | ||
| 0.026 m); the flange board is DICT_5X5_50 5x4 squares (square 0.030 m, | ||
| marker 0.022 m). Distinct dictionaries keep detections unambiguous | ||
| when a camera sees both boards. --> | ||
| <texture | ||
| name="charuco_world" | ||
| type="2d" | ||
| file="assets/charuco_world_board.png" | ||
| /> | ||
| <material | ||
| name="charuco_world_material" | ||
| texture="charuco_world" | ||
| texuniform="false" | ||
| /> | ||
| <texture | ||
| name="charuco_flange" | ||
| type="2d" | ||
| file="assets/charuco_flange_board.png" | ||
| /> | ||
| <material | ||
| name="charuco_flange_material" | ||
| texture="charuco_flange" | ||
| texuniform="false" | ||
| /> | ||
| </asset> | ||
|
|
||
| <worldbody> | ||
| <light pos="0 0 1.5" dir="0 0 -1" directional="true" /> | ||
|
|
||
| <light | ||
| name="spotlight" | ||
| mode="targetbodycom" | ||
| target="wrist_2_link" | ||
| pos="0 -1 2" | ||
| /> | ||
| <geom | ||
| name="floor" | ||
| pos="0 0 -0.512" | ||
| size="0 0 0.05" | ||
| type="plane" | ||
| material="groundplane" | ||
| /> | ||
|
|
||
| <!-- Fixed scene cameras (eye-to-hand). Both sit high on the +Y side, | ||
| the hemisphere the wrist plate faces at the calibration pose, aimed | ||
| just above the wrist from different azimuths so the world board stays | ||
| below their frames: overlapping but not identical fields of view, so | ||
| partial per-camera board visibility is exercisable. Each optical-frame | ||
| site is the camera pose rotated 180 degrees about its x-axis (REP 103 | ||
| optical convention). --> | ||
| <site | ||
| name="scene_camera_1_optical_frame" | ||
| pos="0.917266 1.074437 1.861509" | ||
| quat="0.233342 -0.306871 -0.734484 0.558494" | ||
| /> | ||
| <camera | ||
| name="scene_camera_1" | ||
| pos="0.917266 1.074437 1.861509" | ||
| fovy="58" | ||
| mode="fixed" | ||
| resolution="1280 720" | ||
| quat="0.306871 0.233342 0.558494 0.734484" | ||
| /> | ||
| <geom | ||
| name="scene_camera_1_pedestal" | ||
| type="box" | ||
| pos="0.917266 1.074437 0.644754" | ||
| size="0.05 0.05 1.156754" | ||
| rgba="0.3 0.3 0.3 1" | ||
| contype="0" | ||
| conaffinity="0" | ||
| /> | ||
| <site | ||
| name="scene_camera_2_optical_frame" | ||
| pos="-0.401516 1.072484 1.82102" | ||
| quat="0.244002 -0.306655 0.719923 -0.572833" | ||
| /> | ||
| <camera | ||
| name="scene_camera_2" | ||
| pos="-0.401516 1.072484 1.82102" | ||
| fovy="58" | ||
| mode="fixed" | ||
| resolution="1280 720" | ||
| quat="0.306655 0.244002 -0.572833 -0.719923" | ||
| /> | ||
| <geom | ||
| name="scene_camera_2_pedestal" | ||
| type="box" | ||
| pos="-0.401516 1.072484 0.62451" | ||
| size="0.05 0.05 1.13651" | ||
| rgba="0.3 0.3 0.3 1" | ||
| contype="0" | ||
| conaffinity="0" | ||
| /> | ||
|
|
||
| <!-- World-fixed ChArUco board (eye-in-hand target), on a stand | ||
| 0.75 m down the wrist camera's boresight at the calibration pose, | ||
| tilted to face the camera. Physical size 0.245 x 0.175 m (7 x 5 squares of 0.035 m), | ||
| matching assets/charuco_world_board.png exactly. Contact is disabled: | ||
| the board is a calibration target, not a manipulation surface. --> | ||
| <body | ||
| name="world_board" | ||
| pos="0.266 0.650113 0.665599" | ||
| quat="0.972489 0.232951 0 0" | ||
| > | ||
| <geom | ||
| name="world_board_plate" | ||
| type="box" | ||
| size="0.1225 0.0875 0.004" | ||
| material="charuco_world_material" | ||
| contype="0" | ||
| conaffinity="0" | ||
| /> | ||
| <site name="world_board_top" pos="0 0 0.004" /> | ||
| </body> | ||
| <body name="world_board_stand" pos="0.266 0.700113 0.08218"> | ||
| <geom | ||
| type="box" | ||
| size="0.02 0.02 0.59418" | ||
| rgba="0.3 0.3 0.3 1" | ||
| contype="0" | ||
| conaffinity="0" | ||
| /> | ||
| </body> | ||
|
|
||
| <include file="ur5e_linear_rail_hand_eye.xml" /> | ||
| </worldbody> | ||
|
|
||
| <keyframe> | ||
| <!-- The calibration pose: arm up, wrist camera looking forward-down at | ||
| the world board, wrist plate facing up toward the scene cameras. | ||
| qpos follows JOINT order: linear_rail (1), shoulder_pan..wrist_3 (6), | ||
| robotiq right knuckle (1), 7 gripper mimic joints. ctrl follows | ||
| ACTUATOR order, which differs: shoulder_pan..wrist_3 (6), | ||
| linear_rail, gripper. Keep both orders straight or the held pose | ||
| will not match the spawned pose. --> | ||
| <key | ||
| name="default" | ||
| qpos=" | ||
| 0 | ||
| 0 -1.8849 1.0997 -1.2566 -1.57075 0 | ||
| 0 | ||
| 0 0 0 0 0 0 0" | ||
| ctrl="0 -1.8849 1.0997 -1.2566 -1.57075 0 0 0" | ||
| /> | ||
| </keyframe> | ||
| </mujoco> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: PickNikRobotics/moveit_pro_example_ws
Length of output: 45122
🏁 Script executed:
Repository: PickNikRobotics/moveit_pro_example_ws
Length of output: 12766
Resolve package paths through the ament package index.
The source path assumes an isolated install layout. Merged or system installs can make
find_package(picknik_accessories)succeed while this path is invalid. The absoluteDEST_DIRalso prevents relocation withcmake --install --prefix.Resolve the dependency share directory through an ament index helper or exported CMake path. Use a relative destination such as
share/${PROJECT_NAME}/description.🤖 Prompt for AI Agents