Project

General

Profile

Task #216

Updated by Sanghoon Lee about 2 months ago

This project is a marker publisher called xela_taxel_viz_ahv4 that visualizes Allegrohand sensor data and publishes it to a marker topic. 
 I plan to develop a visualization app that subscribes to the sensor data topic provided by xela_server2_ah and publishes visualized markers. Using the force values ​​(taxel values ​​if unavailable) and sensor model (frame_id) information from the sensor data, I will convert the x, y, and z values ​​into markers and visualize them on a grid-based sensor model. As an additional feature, I will link it to the xela_model information to display the corresponding model values ​​as markers at each sensor location in the visualized model. 

 This app publishes data to the Marker topic, allowing RViz and other ROS apps to easily subscribe to and visualize this marker topic. 

 xela_taxel_viz_ahv4 targets the following models: 
 - uSCuAH (left, right) 

 Supported models use pre-defined profiles for each model, which can be selected as parameters at startup. 

 ------------------- 

 !{width:800px}clipboard-202602152303-rc6wx.png! 

 ------------------- 

 h1. xela_taxel_viz_ahv4 

 h2. Goals 

 * Visualize @/x_taxel_ah@ tactile data as a 31x26 grid pattern with 368 active cells. 
 * Support URDF marker mode for Allegro Hand (left/right). 
 * Reuse the visual style from @xela_taxel_viz_2f@ (circle size/color + arrow direction/length). 
 * Support real-time updates with best-effort performance. 

 h2. Inputs 

 * Topic: @/x_taxel_ah@ 
 * Message: @xela_taxel_msgs/XTaxelSensorTArray@ 
 * Fields used: 
 * @x_modules[].frame_ids[]@ (always @_joint@ suffix) 
 * @x_modules[].forces[]@ (optional) 
 * @x_modules[].taxels[]@ (primary data) 
 * @x_modules[].temps[]@ (ignored) 

 h2. Data Mapping 

 h3. A) Flat index mapping 

 * Use @taxel_joint_map_new.yaml@ to map @frame_id -> flat_index (0..367)@. 
 * Build a flat array of length 368 per incoming message. 
 * Matching rule: 
 * If @frame_id@ exists in the map, place the sample at @flat_index@. 
 * If missing, warn and skip. 

 h3. B) Pattern grid mapping 

 * Pattern grid size: 31 rows x 26 columns. 
 * Traversal order: top-left, row-major (top->bottom, left->right). 
 * Pattern YAML contains an @index_map@ matrix: 
 * @-1@ for inactive cells 
 * @0..367@ for active cells (flat indices) 
 * Visualization uses @index_map@ to place each index on the 2D grid. 

 h2. Value Selection 

 * If @forces@ is present and @use_forces_if_present=true@, use @forces@. 
 * Otherwise, use @taxels@. 
 * Baseline is computed per index; visualization uses @current - baseline@. 

 h2. Normalization 

 * Use the same normalization model as @xela_taxel_viz_2f@. 
 * Ranges (from tech spec): 
 * X/Y: baseline +/- 1350 
 * Z: baseline to baseline + 16000 
 * Z negative deltas are clamped to 0 for normalization. 

 h2. Visualization Style 

 * Same as @xela_taxel_viz_2f@: 
 * Circle radius and color scale with normalized magnitude. 
 * Arrow length scales with the same magnitude. 
 * Arrow direction uses XY direction (default). 

 h2. Parameters (draft) 

 * @in_topic@, @out_topic@, @frame_id@ (default @x_taxel_ah_viz@ for grid mode) 
 * @pattern_yaml@ (pattern file path) 
 * @mapping_yaml@ (taxel_joint_map_new.yaml path) 
 * @hand_side@ (left/right prefix rewrite) 
 * @grid_rows@, @grid_cols@, @cell_size@, @origin_x@, @origin_y@ 
 * @use_forces_if_present@ 
 * @baseline_duration_sec@ 
 * @use_axis_normalization@, @xy_range@, @z_range@ 
 * @circle_*@, @arrow_*@, @grid_*@, @color_*@ 
 * @marker_stamp_mode@, @marker_time_offset_sec@ 

 h2. Tooling: CSV -> Pattern YAML 

 h3. Recommended workflow 

 1) Export the Excel sheet to CSV (31 rows x 26 cols, empty cells allowed). 
 2) Convert CSV to YAML using a small Python script. 

 h3. Example script (Python) 

 <pre><code> 
 python3 - <<'PY' 
 import csv 
 import yaml 
 from pathlib import Path 

 csv_path = Path('pattern.csv') 
 out_path = Path('pattern.yaml') 

 rows = [] 
 with csv_path.open(newline='') as f: 
     reader = csv.reader(f) 
     for row in reader: 
         parsed = [] 
         for cell in row: 
             cell = cell.strip() 
             if cell == '' or cell.lower() == 'nan': 
                 parsed.append(-1) 
             else: 
                 parsed.append(int(float(cell))) 
         rows.append(parsed) 

 payload = { 
     'pattern': { 
         'rows': len(rows), 
         'cols': len(rows[0]) if rows else 0, 
         'index_map': rows, 
     } 
 } 

 with out_path.open('w') as f: 
     yaml.safe_dump(payload, f, sort_keys=False) 

 print('wrote', out_path) 
 PY 
 </code></pre> 

 h2. Open Questions 

 * Confirm whether forces should override taxels (default: yes). 
 * Confirm QoS policy (best-effort suggested). 
 * Confirm default marker timestamp offset per platform. 

 h2. Risks 

 * Missing @frame_id@ mapping will leave holes in the grid. 
 * Performance may degrade if update rate is very high; consider throttling if needed. 

 --------------- 

 h1. README 

 RViz2 visualization for @/x_taxel_ah@ (@xela_taxel_msgs/XTaxelSensorTArray@). 
 Supports both grid and URDF marker modes for Allegro Hand (AHv4) left/right. 

 h2. Build 

 <pre><code> 
 cd ~/xela_robotics/02_dev_ws 
 colcon build --packages-select xela_taxel_viz_ahv4 
 </code></pre> 

 h2. Run 

 Grid mode (default): 
 <pre><code> 
 source ~/xela_robotics/02_dev_ws/install/setup.bash 
 ros2 launch xela_taxel_viz_ahv4 xela_taxel_viz_ahv4.launch.py viz_mode:=grid 
 </code></pre> 

 URDF mode: 
 <pre><code> 
 source ~/xela_robotics/02_dev_ws/install/setup.bash 
 ros2 launch xela_taxel_viz_ahv4 xela_taxel_viz_ahv4.launch.py viz_mode:=urdf 
 </code></pre> 

 h2. Demo (no /x_taxel_ah source yet) 

 Starts a synthetic publisher and the visualizer. 
 <pre><code> 
 source ~/xela_robotics/02_dev_ws/install/setup.bash 
 ros2 launch xela_taxel_viz_ahv4 xela_taxel_viz_ahv4_demo.launch.py 
 </code></pre> 

 Optional: set demo publish rate 
 <pre><code> 
 ros2 launch xela_taxel_viz_ahv4 xela_taxel_viz_ahv4_demo.launch.py publish_rate_hz:=10.0 
 </code></pre> 

 h2. Sim (replayer + server + viz) 

 <pre><code> 
 source ~/xela_robotics/02_dev_ws/install/setup.bash 
 ros2 launch xela_taxel_viz_ahv4 sim_all_svc_xela_taxel_viz_ahv4.launch.py \ 
   model_name:=XR23AHLCPP viz_mode:=urdf 
 </code></pre> 

 h2. RViz2 

 Grid mode fixed frame should be @x_taxel_ah_viz@. 
 URDF mode uses the URDF frames (e.g., @world@/@hand_root@). 

 @sim_all_svc_xela_taxel_viz_ahv4.launch.py@ selects RViz configs automatically: 
 * grid: @config/grid_xela_taxel_viz_ah.rviz@ 
 * urdf: @config/urdf_xela_taxel_viz_ah.rviz@ 

 h2. Pattern Conversion (CSV -> YAML) 

 <pre><code> 
 ~/xela_robotics/02_dev_ws/install/xela_taxel_viz_ahv4/lib/xela_taxel_viz_ahv4/csv_to_pattern_yaml.py \ 
   pattern.csv -o pattern.yaml 
 </code></pre> 

 h2. Key Parameters 

 See @config/xela_taxel_viz_ahv4.yaml@ for defaults. 
 * @mapping_yaml@: @taxel_joint_map_new.yaml@ 
 * @pattern_yaml@: @pattern_lahv4.yaml@ 
 * @use_forces_if_present@: prefer forces when available 
 * @xy_range@, @z_range@: normalization ranges 
 * @hand_side@: @left|right@ (prefix rewrite for @x_taxel_0_@ vs @x_taxel_1_@) 
 * @marker_stamp_mode@: @keep|now|zero@ 
 * @marker_time_offset_sec@: default @-0.1@ for TF stability 

 h2. Left/Right Notes 

 * @model_name:=XR23AHLCPP@ (left) and @model_name:=XR23AHRCPP@ (right). 
 * @pattern_lahv4.yaml@ (left) and @pattern_rahv4.yaml@ (right) are selected 
   automatically by @sim_all_svc_xela_taxel_viz_ahv4.launch.py@. 

 ------------------ 

 {{video("xela_viz_ahv4_n_sim_server.mp4",800, 400)}}

Back