In our builds, we use a sandpaper-structured midlayer as the dielectric.
Procedure
For a full walkthrough, please see our assembly instruction video above.
Prepare base layer: Apply double-sided tape along the boundary of one fPCB piece.
Attach dielectric (0:05):
Laminate the dielectric layer onto the second fPCB piece, trimming as needed.
Align electrodes (1:22):
Carefully align the top and bottom electrode layers by matching the exposed copper taxels.
Bond Assembly (1:46):
Press around the edges to ensure the double-sided tape bonds the two pieces together securely.
After assembly, verify the sensor by following the firmware instructions provided in the Firmware & Interfacing Setup to flash and interface with the sensor. If assembled correctly, the sensor should appear as follows:
File Overview
Below we provide a brief overview of files available in our release. For full details, please see the /hardware section of our repository.
finger/DexSkin_Electrode_design.svg: Layout of top and bottom capacitive electrode layers for the finger design described in the paper.
For researchers interested in access to the stretchable cylindrical DexSkin form described in the paper or tactile arrays in other grid formats, please contact Baiyu Shi at the Bao Group (baiyushi@stanford.edu) regarding sample availability.
fpcb/dexskin_5pin_row_interconnection.zip and fpcb/dexskin_12pin_column_interconnection.zip: flexible PCB interconnect files for the stretchable cylindrical DexSkin embodiment described in the paper.
fpcb/5pin_row_fabrication_output.zip and fpcb/12pin_column_fabrication_output.zip: fabrication-ready Gerber files for the 5 x 12 taxel flexible sensor layout for easy adoption.
5 x 12 taxel layout, mountable on flat or cylindrical grippers
2.5 mm x 2.5 mm square taxels
1.5 mm spacing between neighboring taxels
Special flex-PCB ordering notes: these fabrication-output Gerbers include a few nonstandard annotations that should be communicated explicitly to the flex-PCB vendor during ordering.
Mechanical Layer 1: flex PCB outline
Top Overlay: outline for the top EMI shielding film
Bottom Overlay: outline for the bottom stiffener
readout_pcb/dexskin_readout_pcb_v1.1.zip: Manufacturing files for the 4-layer readout board used to read both finger arrays simultaneously, prepared as a fabrication-ready Gerber archive
calibration/*.stl
3D-printable parts used to mold the Ecoflex and build airtight chambers for the 3-minute transfer calibration procedure described in the paper.
Manufacturing Notes
The ZIP archives in fpcb/ and readout_pcb/ are intended for direct submission to a PCB manufacturer.
If your manufacturer asks for layer clarification on the flexible PCB files, you may use the layer notes above.
If you haven't worked with embedded systems before, you will need a driver to communicate with the onboard Serial USB.
Please visit and install the USB serial drivers:
Linux: typically already installed (check via Step #3)
2. Install Flashing Tool (esptool)
The esptool utility is a universal Python-based application used to communicate and flash in firmware with the ESP32 MCU series.
pip install esptool
3. Identify Serial Port
Connect the board via USB-C.
If there are two ports, orient the board such that ESP32 is facing up, antenna is on the right, and use the top-left port. You need to identify the specific port and its name assigned to the connected board:.
Windows
Right-click the Start menu, select Device Manager, and expand Ports (COM & LPT).
Look for USB Serial Port (COMx).
The software architecture is split into two independent processes that communicate via shared memory:
./scripts/readout.py:
Handles serial communication, packet decoding, and baseline normalization.
Always run this script first; it must be running for the visualization or any other application to access sensor data.
./scripts/visualize.py:
Provides a real-time visualization of tactile data for both the left and right fingers.
Each taxel is displayed as a white dot, with dot size proportional to the raw sensor values
(sampled pressure / force magnitude). If the script is running correctly, the visualization will look like:
Developer Guide: Interfacing with Shared Memory
The DexSkin system exposes its real-time data buffer to the operating system's shared memory.
This allows developers to write their own scripts (e.g., for Machine Learning inference,
ROS robot control, or custom logging) without modifying the core driver.
Any Python script running on the same machine can attach to the shared memory block as a client:
SHM_NAME = 'dexskin_memory'
NUM_TAXELS = 120
try:
self.shm = shm.SharedMemory(name=SHM_NAME)
self.frame_buffer = np.ndarray((NUM_TAXELS,), dtype=np.float32, buffer=self.shm.buf)
print(f"Attached to shared memory: {SHM_NAME}")
except FileNotFoundError:
print(f"ERROR: Shared memory block '{SHM_NAME}' not found.")
print("Please ensure the data providing script is running.")
sys.exit(1)
Then in other function calls, use:
self.frame_buffer.copy()
to access the latest data.
Guide
Learning Integration
This guide gives a brief overview of data collection and base policy training with DexSkin. We also provide several sample scripts for RL fine-tuning with DexSkin, see files under learning/scripts in the release repository.
Data Collection
We collect real-world demonstrations using a teleoperated Franka robot setup equipped with DexSkin sensors. Our data is also hosted on HuggingFace as a helpful example.
Each demonstration consists of:
Robot observations (e.g., proprioception, optional vision via wrist camera)
DexSkin tactile readings
Corresponding action trajectories
These demonstrations are used to train an initial policy via imitation learning. In our setup, ~50 human demonstrations per task are sufficient to learn a reasonable base policy.
Base Policy Training
We train a base manipulation policy using a standard diffusion policy formulation, though any imitation-learning framework will do. Please see our paper Appendix for training details and hyperparameters.
RL Fine-Tuning with DexSkin
We provide a small set of example residual RL scripts to illustrate how DexSkin can be used in real-world, online learning settings. These scripts are provided as a helpful reference implementation, however, reward functions, force thresholds, termination conditions, etc. should be adapted to one's own target task and hardware setup.
Script Overview
./scripts/franka_env_with_policy.py:
Defines a Gym-compatible Franka environment that combines a pretrained diffusion policy with a residual controller. The residual action modifies the base policy's gripper action online, where DexSkin signals are used to compute force-threshold rewards together with an action-magnitude penalty.
./scripts/residual_inference_train_env.py:
Constructs a FrankaEnvWithPolicy environment and runs Franka rollouts with the base policy plus a residual controller, which is one of:
(default) a learned residual policy
--base_policy_only: the base policy only
--random_residual: a random residual baseline
If neither --base_policy_only nor --random_residual is set, this script can also continue updating the learned residual policy online.
./scripts/residual_train.py:
Trains a residual SAC policy online on the Franka robot. This script loads the pretrained base policy, constructs the DexSkin-enabled FrankaEnvWithPolicy environment, performs online rollouts, updates the residual policy, and periodically saves checkpoints.
BibTeX
@inproceedings{wistreich2025dexskin,
title={DexSkin: High-Coverage Conformable Robotic Skin for Learning Contact-Rich Manipulation},
author={Suzannah Wistreich and Baiyu Shi and Stephen Tian and Samuel Clarke and Michael Nath and Chengyi Xu and Zhenan Bao and Jiajun Wu},
booktitle={Conference on Robot Learning (CoRL)},
year={2025},
eprint={2509.18830},
archivePrefix={arXiv},
primaryClass={cs.RO},
url={https://arxiv.org/abs/2509.18830},
}