flexitac 0.2.2__tar.gz → 0.3.1__tar.gz
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.
- {flexitac-0.2.2/flexitac.egg-info → flexitac-0.3.1}/PKG-INFO +44 -2
- {flexitac-0.2.2 → flexitac-0.3.1}/README.md +43 -1
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/__init__.py +1 -1
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/flash.py +12 -11
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/sensor.py +42 -21
- {flexitac-0.2.2 → flexitac-0.3.1/flexitac.egg-info}/PKG-INFO +44 -2
- {flexitac-0.2.2 → flexitac-0.3.1}/LICENSE +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/examples/__init__.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/examples/stream_frames.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/examples/visualize_heatmap.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/find_port.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/firmware/__init__.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/firmware/template.ino +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/logging_utils.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac/py.typed +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac.egg-info/SOURCES.txt +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac.egg-info/dependency_links.txt +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac.egg-info/entry_points.txt +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac.egg-info/requires.txt +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/flexitac.egg-info/top_level.txt +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/pyproject.toml +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/setup.cfg +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/tests/test_find_port.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/tests/test_flash.py +0 -0
- {flexitac-0.2.2 → flexitac-0.3.1}/tests/test_sensor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flexitac
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Python runtime and flashing tools for FlexiTac tactile sensors
|
|
5
5
|
Author-email: Wesley Maa <wesley.maa@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -22,7 +22,7 @@ Requires-Dist: flexitac[dev]; extra == "all"
|
|
|
22
22
|
Requires-Dist: flexitac[examples]; extra == "all"
|
|
23
23
|
Dynamic: license-file
|
|
24
24
|
|
|
25
|
-
#
|
|
25
|
+
# PyFlexiTac
|
|
26
26
|
|
|
27
27
|
Python interface for [FlexiTac](https://flexitac.github.io/) tactile sensors.
|
|
28
28
|
Allows you to easily [flash](#flexitac-flash) Arduino firmware and read framed sensor data over serial.
|
|
@@ -30,6 +30,10 @@ Allows you to easily [flash](#flexitac-flash) Arduino firmware and read framed s
|
|
|
30
30
|
Defaults target the standard FlexiTac 12x32 sensor (12 rows wired to mux
|
|
31
31
|
channels 4-15). Override `--rows`, `--cols`, and `--mux-offset` for variants.
|
|
32
32
|
|
|
33
|
+
Serial port permissions apply to both flashing and reading. If you hit
|
|
34
|
+
`Permission denied` with either `flexitac-flash` or read tools like
|
|
35
|
+
`flexitac-stream`/`flexitac-heatmap`, see the note in [`flexitac-flash`](#flexitac-flash).
|
|
36
|
+
|
|
33
37
|
## Install
|
|
34
38
|
|
|
35
39
|
```bash
|
|
@@ -142,6 +146,24 @@ flexitac-flash --rows 16 --cols 32 --mux-offset 0
|
|
|
142
146
|
flexitac-flash --port /dev/ttyUSB0 --fqbn arduino:avr:uno
|
|
143
147
|
```
|
|
144
148
|
|
|
149
|
+
If flashing fails with a serial `Permission denied` error:
|
|
150
|
+
|
|
151
|
+
- On Linux, add your user to the serial group, then re-login:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
sudo usermod -aG dialout "$USER"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- On macOS, permissions are usually managed automatically, but if needed you can
|
|
158
|
+
grant temporary read/write access to the device (replace with your actual port):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
sudo chmod a+rw /dev/tty.usbmodem*
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
As a last-resort fallback, you can run `sudo chmod 666 /dev/tty...`,
|
|
165
|
+
but this is overly permissive.
|
|
166
|
+
|
|
145
167
|
Defaults: `rows=12`, `cols=32`, `baud=2000000`, `mux-offset=4` (standard
|
|
146
168
|
FlexiTac 12x32 sensor wired to mux channels 4-15). The firmware is generated
|
|
147
169
|
from `flexitac/firmware/template.ino` by substituting `ROW_COUNT`,
|
|
@@ -162,3 +184,23 @@ make format # ruff format + autofix
|
|
|
162
184
|
make static-checks # ruff + mypy
|
|
163
185
|
make test # pytest
|
|
164
186
|
```
|
|
187
|
+
|
|
188
|
+
## Citation
|
|
189
|
+
|
|
190
|
+
If you use this software in research or publications, please cite the repository.
|
|
191
|
+
On GitHub, use **Cite this repository**.
|
|
192
|
+
|
|
193
|
+
```bibtex
|
|
194
|
+
@misc{maa_pyflexitac_2026,
|
|
195
|
+
author = {Maa, Wesley},
|
|
196
|
+
title = {{PyFlexiTac}: Python runtime and flashing tools for FlexiTac tactile sensors},
|
|
197
|
+
year = {2026},
|
|
198
|
+
howpublished = {\url{https://github.com/WT-MM/PyFlexiTac}},
|
|
199
|
+
note = {Version 0.3.1},
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Acknowledgments
|
|
204
|
+
|
|
205
|
+
- [Binghao Huang](https://binghao-huang.github.io/), for the Arduino firmware template this project's firmware is derived from.
|
|
206
|
+
- [Naian Tao](https://tna001-ai.github.io/), for leading the [LeFlexiTac](https://tna001-ai.github.io/tactile-lerobot-website/) project that motivated this code.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PyFlexiTac
|
|
2
2
|
|
|
3
3
|
Python interface for [FlexiTac](https://flexitac.github.io/) tactile sensors.
|
|
4
4
|
Allows you to easily [flash](#flexitac-flash) Arduino firmware and read framed sensor data over serial.
|
|
@@ -6,6 +6,10 @@ Allows you to easily [flash](#flexitac-flash) Arduino firmware and read framed s
|
|
|
6
6
|
Defaults target the standard FlexiTac 12x32 sensor (12 rows wired to mux
|
|
7
7
|
channels 4-15). Override `--rows`, `--cols`, and `--mux-offset` for variants.
|
|
8
8
|
|
|
9
|
+
Serial port permissions apply to both flashing and reading. If you hit
|
|
10
|
+
`Permission denied` with either `flexitac-flash` or read tools like
|
|
11
|
+
`flexitac-stream`/`flexitac-heatmap`, see the note in [`flexitac-flash`](#flexitac-flash).
|
|
12
|
+
|
|
9
13
|
## Install
|
|
10
14
|
|
|
11
15
|
```bash
|
|
@@ -118,6 +122,24 @@ flexitac-flash --rows 16 --cols 32 --mux-offset 0
|
|
|
118
122
|
flexitac-flash --port /dev/ttyUSB0 --fqbn arduino:avr:uno
|
|
119
123
|
```
|
|
120
124
|
|
|
125
|
+
If flashing fails with a serial `Permission denied` error:
|
|
126
|
+
|
|
127
|
+
- On Linux, add your user to the serial group, then re-login:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
sudo usermod -aG dialout "$USER"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- On macOS, permissions are usually managed automatically, but if needed you can
|
|
134
|
+
grant temporary read/write access to the device (replace with your actual port):
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
sudo chmod a+rw /dev/tty.usbmodem*
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
As a last-resort fallback, you can run `sudo chmod 666 /dev/tty...`,
|
|
141
|
+
but this is overly permissive.
|
|
142
|
+
|
|
121
143
|
Defaults: `rows=12`, `cols=32`, `baud=2000000`, `mux-offset=4` (standard
|
|
122
144
|
FlexiTac 12x32 sensor wired to mux channels 4-15). The firmware is generated
|
|
123
145
|
from `flexitac/firmware/template.ino` by substituting `ROW_COUNT`,
|
|
@@ -138,3 +160,23 @@ make format # ruff format + autofix
|
|
|
138
160
|
make static-checks # ruff + mypy
|
|
139
161
|
make test # pytest
|
|
140
162
|
```
|
|
163
|
+
|
|
164
|
+
## Citation
|
|
165
|
+
|
|
166
|
+
If you use this software in research or publications, please cite the repository.
|
|
167
|
+
On GitHub, use **Cite this repository**.
|
|
168
|
+
|
|
169
|
+
```bibtex
|
|
170
|
+
@misc{maa_pyflexitac_2026,
|
|
171
|
+
author = {Maa, Wesley},
|
|
172
|
+
title = {{PyFlexiTac}: Python runtime and flashing tools for FlexiTac tactile sensors},
|
|
173
|
+
year = {2026},
|
|
174
|
+
howpublished = {\url{https://github.com/WT-MM/PyFlexiTac}},
|
|
175
|
+
note = {Version 0.3.1},
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Acknowledgments
|
|
180
|
+
|
|
181
|
+
- [Binghao Huang](https://binghao-huang.github.io/), for the Arduino firmware template this project's firmware is derived from.
|
|
182
|
+
- [Naian Tao](https://tna001-ai.github.io/), for leading the [LeFlexiTac](https://tna001-ai.github.io/tactile-lerobot-website/) project that motivated this code.
|
|
@@ -61,6 +61,15 @@ def detect_board() -> tuple[str, str]:
|
|
|
61
61
|
raise FlashError(f"multiple boards detected; pass --port and --fqbn:\n{listing}")
|
|
62
62
|
|
|
63
63
|
|
|
64
|
+
def _require_arduino_cli() -> None:
|
|
65
|
+
if shutil.which("arduino-cli") is None:
|
|
66
|
+
raise FlashError(
|
|
67
|
+
"arduino-cli not found on PATH. Install it (e.g. `brew install arduino-cli`) and run "
|
|
68
|
+
"`arduino-cli core install arduino:avr`. See "
|
|
69
|
+
"https://arduino.github.io/arduino-cli/latest/installation/"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
64
73
|
def flash(
|
|
65
74
|
*,
|
|
66
75
|
port: str,
|
|
@@ -72,10 +81,7 @@ def flash(
|
|
|
72
81
|
verbose: bool = False,
|
|
73
82
|
) -> None:
|
|
74
83
|
"""Render firmware and upload it to ``port``."""
|
|
75
|
-
|
|
76
|
-
raise FlashError(
|
|
77
|
-
"arduino-cli not found on PATH. Install from https://arduino.github.io/arduino-cli/latest/installation/"
|
|
78
|
-
)
|
|
84
|
+
_require_arduino_cli()
|
|
79
85
|
|
|
80
86
|
rendered = render_template(rows=rows, cols=cols, baud=baud, mux_offset=mux_offset)
|
|
81
87
|
with tempfile.TemporaryDirectory(prefix="flexitac-") as tmp:
|
|
@@ -93,7 +99,7 @@ def _run(cmd: list[str], *, verbose: bool = False, capture: bool = False) -> sub
|
|
|
93
99
|
except FileNotFoundError as exc:
|
|
94
100
|
raise FlashError(f"command not found: {cmd[0]}") from exc
|
|
95
101
|
if result.returncode != 0:
|
|
96
|
-
msg = (result.stderr or result.stdout or "").strip()
|
|
102
|
+
msg = (result.stderr or result.stdout or "").strip() or "(see output above)"
|
|
97
103
|
raise FlashError(f"{' '.join(cmd)} failed: {msg}")
|
|
98
104
|
return result
|
|
99
105
|
|
|
@@ -118,12 +124,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
118
124
|
logger = configure_logging(verbose=args.verbose)
|
|
119
125
|
|
|
120
126
|
try:
|
|
121
|
-
|
|
122
|
-
raise FlashError(
|
|
123
|
-
"arduino-cli not found on PATH. Install it (e.g. `brew install arduino-cli`) and run "
|
|
124
|
-
"`arduino-cli core install arduino:avr`. See "
|
|
125
|
-
"https://arduino.github.io/arduino-cli/latest/installation/"
|
|
126
|
-
)
|
|
127
|
+
_require_arduino_cli()
|
|
127
128
|
|
|
128
129
|
port, fqbn = args.port, args.fqbn
|
|
129
130
|
if port is None or fqbn is None:
|
|
@@ -40,7 +40,27 @@ class FlexiTacSensor:
|
|
|
40
40
|
noise_scale: float = 30.0,
|
|
41
41
|
init_frames: int = 30,
|
|
42
42
|
read_timeout_s: float = 5.0,
|
|
43
|
+
baseline: NDArray[np.float32] | float | None = None,
|
|
43
44
|
) -> None:
|
|
45
|
+
"""Initialize a FlexiTac sensor.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
port: Serial device path (e.g. ``/dev/ttyUSB0``).
|
|
49
|
+
rows: Number of tactile rows (default 12).
|
|
50
|
+
cols: Number of tactile columns (default 32).
|
|
51
|
+
baud: Serial baud rate matching the flashed firmware (default 2_000_000).
|
|
52
|
+
threshold: Contact-detection threshold in ADC counts above baseline.
|
|
53
|
+
noise_scale: Divisor used to normalize readings below ``threshold``.
|
|
54
|
+
init_frames: Number of frames sampled during ``calibrate()`` (default 30).
|
|
55
|
+
Higher values give a more robust baseline at the cost of startup time.
|
|
56
|
+
read_timeout_s: Maximum time ``read()`` will wait for a full frame.
|
|
57
|
+
baseline: If provided, skips auto-calibration on first ``read()``. Pass a
|
|
58
|
+
``(rows, cols)`` array of per-pixel baselines, or a scalar applied to
|
|
59
|
+
every pixel. Typical resting ADC values land around 10-40 for an
|
|
60
|
+
unloaded sensor, so a scalar like ``20.0`` is a reasonable default
|
|
61
|
+
when you can't afford the startup delay of a full calibration. For
|
|
62
|
+
accurate contact detection, prefer letting ``calibrate()`` run.
|
|
63
|
+
"""
|
|
44
64
|
self.port = port
|
|
45
65
|
self.rows = rows
|
|
46
66
|
self.cols = cols
|
|
@@ -56,6 +76,9 @@ class FlexiTacSensor:
|
|
|
56
76
|
self._baseline: NDArray[np.float32] | None = None
|
|
57
77
|
self._seq = 0
|
|
58
78
|
|
|
79
|
+
if baseline is not None:
|
|
80
|
+
self._baseline = np.broadcast_to(np.float32(baseline), (rows, cols)).copy()
|
|
81
|
+
|
|
59
82
|
def open(self) -> FlexiTacSensor:
|
|
60
83
|
"""Open the serial port if not already open."""
|
|
61
84
|
if self._serial is None or not self._serial.is_open:
|
|
@@ -126,16 +149,24 @@ class FlexiTacSensor:
|
|
|
126
149
|
|
|
127
150
|
def _latest_buffered_frame(self) -> NDArray[np.uint8] | None:
|
|
128
151
|
latest: NDArray[np.uint8] | None = None
|
|
129
|
-
while
|
|
130
|
-
|
|
131
|
-
if idx < 0 or len(self._buf) - idx - 2 < self._frame_bytes:
|
|
132
|
-
break
|
|
133
|
-
del self._buf[: idx + 2]
|
|
134
|
-
payload = bytes(self._buf[: self._frame_bytes])
|
|
135
|
-
del self._buf[: self._frame_bytes]
|
|
136
|
-
latest = np.frombuffer(payload, dtype=np.uint8).reshape(self.rows, self.cols).copy()
|
|
152
|
+
while (frame := self._pop_frame()) is not None:
|
|
153
|
+
latest = frame
|
|
137
154
|
return latest
|
|
138
155
|
|
|
156
|
+
def _pop_frame(self) -> NDArray[np.uint8] | None:
|
|
157
|
+
"""Extract one frame from ``self._buf``; trim leading garbage if no marker."""
|
|
158
|
+
idx = self._buf.find(MARKER)
|
|
159
|
+
if idx < 0:
|
|
160
|
+
if len(self._buf) > 1:
|
|
161
|
+
del self._buf[:-1]
|
|
162
|
+
return None
|
|
163
|
+
if len(self._buf) - idx - 2 < self._frame_bytes:
|
|
164
|
+
return None
|
|
165
|
+
del self._buf[: idx + 2]
|
|
166
|
+
payload = bytes(self._buf[: self._frame_bytes])
|
|
167
|
+
del self._buf[: self._frame_bytes]
|
|
168
|
+
return np.frombuffer(payload, dtype=np.uint8).reshape(self.rows, self.cols).copy()
|
|
169
|
+
|
|
139
170
|
def _normalize(self, raw: NDArray[np.uint8]) -> NDArray[np.float32]:
|
|
140
171
|
assert self._baseline is not None
|
|
141
172
|
signal = raw.astype(np.float32) - self._baseline - self.threshold
|
|
@@ -158,18 +189,8 @@ class FlexiTacSensor:
|
|
|
158
189
|
if len(self._buf) > 50_000:
|
|
159
190
|
del self._buf[: len(self._buf) - 50_000]
|
|
160
191
|
|
|
161
|
-
|
|
162
|
-
if
|
|
163
|
-
|
|
164
|
-
del self._buf[:-1]
|
|
165
|
-
continue
|
|
166
|
-
|
|
167
|
-
if len(self._buf) - idx - 2 < self._frame_bytes:
|
|
168
|
-
continue
|
|
169
|
-
|
|
170
|
-
del self._buf[: idx + 2]
|
|
171
|
-
payload = bytes(self._buf[: self._frame_bytes])
|
|
172
|
-
del self._buf[: self._frame_bytes]
|
|
173
|
-
return np.frombuffer(payload, dtype=np.uint8).reshape(self.rows, self.cols).copy()
|
|
192
|
+
frame = self._pop_frame()
|
|
193
|
+
if frame is not None:
|
|
194
|
+
return frame
|
|
174
195
|
|
|
175
196
|
raise TimeoutError(f"timed out after {self.read_timeout_s:.2f}s waiting for a frame")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flexitac
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Python runtime and flashing tools for FlexiTac tactile sensors
|
|
5
5
|
Author-email: Wesley Maa <wesley.maa@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -22,7 +22,7 @@ Requires-Dist: flexitac[dev]; extra == "all"
|
|
|
22
22
|
Requires-Dist: flexitac[examples]; extra == "all"
|
|
23
23
|
Dynamic: license-file
|
|
24
24
|
|
|
25
|
-
#
|
|
25
|
+
# PyFlexiTac
|
|
26
26
|
|
|
27
27
|
Python interface for [FlexiTac](https://flexitac.github.io/) tactile sensors.
|
|
28
28
|
Allows you to easily [flash](#flexitac-flash) Arduino firmware and read framed sensor data over serial.
|
|
@@ -30,6 +30,10 @@ Allows you to easily [flash](#flexitac-flash) Arduino firmware and read framed s
|
|
|
30
30
|
Defaults target the standard FlexiTac 12x32 sensor (12 rows wired to mux
|
|
31
31
|
channels 4-15). Override `--rows`, `--cols`, and `--mux-offset` for variants.
|
|
32
32
|
|
|
33
|
+
Serial port permissions apply to both flashing and reading. If you hit
|
|
34
|
+
`Permission denied` with either `flexitac-flash` or read tools like
|
|
35
|
+
`flexitac-stream`/`flexitac-heatmap`, see the note in [`flexitac-flash`](#flexitac-flash).
|
|
36
|
+
|
|
33
37
|
## Install
|
|
34
38
|
|
|
35
39
|
```bash
|
|
@@ -142,6 +146,24 @@ flexitac-flash --rows 16 --cols 32 --mux-offset 0
|
|
|
142
146
|
flexitac-flash --port /dev/ttyUSB0 --fqbn arduino:avr:uno
|
|
143
147
|
```
|
|
144
148
|
|
|
149
|
+
If flashing fails with a serial `Permission denied` error:
|
|
150
|
+
|
|
151
|
+
- On Linux, add your user to the serial group, then re-login:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
sudo usermod -aG dialout "$USER"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- On macOS, permissions are usually managed automatically, but if needed you can
|
|
158
|
+
grant temporary read/write access to the device (replace with your actual port):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
sudo chmod a+rw /dev/tty.usbmodem*
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
As a last-resort fallback, you can run `sudo chmod 666 /dev/tty...`,
|
|
165
|
+
but this is overly permissive.
|
|
166
|
+
|
|
145
167
|
Defaults: `rows=12`, `cols=32`, `baud=2000000`, `mux-offset=4` (standard
|
|
146
168
|
FlexiTac 12x32 sensor wired to mux channels 4-15). The firmware is generated
|
|
147
169
|
from `flexitac/firmware/template.ino` by substituting `ROW_COUNT`,
|
|
@@ -162,3 +184,23 @@ make format # ruff format + autofix
|
|
|
162
184
|
make static-checks # ruff + mypy
|
|
163
185
|
make test # pytest
|
|
164
186
|
```
|
|
187
|
+
|
|
188
|
+
## Citation
|
|
189
|
+
|
|
190
|
+
If you use this software in research or publications, please cite the repository.
|
|
191
|
+
On GitHub, use **Cite this repository**.
|
|
192
|
+
|
|
193
|
+
```bibtex
|
|
194
|
+
@misc{maa_pyflexitac_2026,
|
|
195
|
+
author = {Maa, Wesley},
|
|
196
|
+
title = {{PyFlexiTac}: Python runtime and flashing tools for FlexiTac tactile sensors},
|
|
197
|
+
year = {2026},
|
|
198
|
+
howpublished = {\url{https://github.com/WT-MM/PyFlexiTac}},
|
|
199
|
+
note = {Version 0.3.1},
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Acknowledgments
|
|
204
|
+
|
|
205
|
+
- [Binghao Huang](https://binghao-huang.github.io/), for the Arduino firmware template this project's firmware is derived from.
|
|
206
|
+
- [Naian Tao](https://tna001-ai.github.io/), for leading the [LeFlexiTac](https://tna001-ai.github.io/tactile-lerobot-website/) project that motivated this code.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|