proposed_position_encoding - diglet48/restim GitHub Wiki

On this page I will introduce a proposed format for specifying individual pulses on a high-level.

The main concept is to specify the pulse at the electrode level rather than the channel level. Rather than specifying current flow between electrode A and B (and C and D), we simply specify the sum of current flow through the A electrode per pulse group. A dimensionality-reduced format is used that extracts sensation intensity as an independent variable.

This has various advantages:

  • Sensation intensity and location can be specified independently, greatly simplifying scripting.
  • Position vector concept closely corresponds with sensations felt by user.
  • Only N values required for N electrodes instead of N!/2 with channel specification.
  • Straightforward calibration by user.
  • Device-independent, works on stereostim as well as pulse-based.

Disadvantages:

  • With 4 or more electrodes the precise current paths are implementation defined and cannot be specified. This is problematic when different current paths result in different sensations.

Open questions:

  • I'm not entirely sure specifying monophasic pulses is useful. It can be argued that alternating pulses or fully charge-balanced pulses are what you want 99% of the time. But it can also be argued a protocol should support monophasic pulses because it is useful in a minority of situations.

Two electrodes

The case for two electrodes is trivial. The position vector is 1 value between -1 and 1.

1 specifies current flow. -1 specifies reverse current flow.
0 specifies a pulse with zero net current flow (biphasic). The subjective intensity of this pulse must be the same as +1 or -1 pulse (requires calibration).

For all values inbetween, hardware smoothly interpolates between these pulses.

Three electrodes

With three electrodes, the mental model is that of a threephase motor.

img

By flowing current through the coils, a magnetic field is induced. The position vector is the direction of the resulting magnetic field: a 2D vector.

When the position is [1, 0], the magnetic field is aligned with the A pole. This generates a sensation that can be felt strongest in the A electrode. For other positions with norm == 1, the magnetic field is rotated. This moves the sensation location smoothly.
For position [0, 0], there is no net magnetic field, hardware should generate a pulse that stimulates all electrodes equally.

For all possible positions, the subjective intensity is the same (requires calibration).

Implementation note

Restim + stereostim uses a simpler coordinate system because it can only generate biphasic pulses, half of the position space is redundant. This simplification is only possible with 2 or 3 electrodes.

Four electrodes

With four electrodes, the coils are placed in a 3D space with the coils arranged in the pattern of a tetrahedron. The position is a 3D vector.

With four electrodes, there is a problem: multiple current paths exist that result in exactly the same magnetic net field. The precise current path is implementation dependent.

More than 4 electrodes

This concept can be expanded to any number of electrodes.

Data format

This is merely a suggestion. For four electrodes (3D position vector). Overlapping pulses are not allowed. Signal intensity has arbitrary units.

[
  {
    "at" : 1000,
    "volume" : 1.0,
    "position" : [1.0, 0, 0]
  },
  {
    "at" : 1010,
    "volume" : 1.0,
    "position" : [0.5, 0.5, 0.5]
  },
  {
    "at" : 1020,
    "volume" : 0.9,
    "position" : [0.5, 0.5, 0.5]
  },  
]

Implementations

For stereostim, signal generation for 3-electrode has been implemented in Restim, most of the work for 4 and 5-electrode configs is done.

For pulse-based, no work has been done.

Calibration

TODO. Not part of the protocol. Expected to be relatively easy with this protocol specification.

Upscaling

With this specification there is potential for using scripts designed for 3-electrodes with 4-electrode configs, or higher. To do this the 4 basis vectors need to be projected on a 2D space.

Appendix

Basis vectors

Basis vectors for 2 electrode configs:

v1 = [1] 
v2 = [-1]
v1 + v2 == 0

Basis vectors for 3 electrode configs:

v1 = [1, 0]
v2 = [-0.5, sqrt(3) / 2]
v3 = [-0.5, -sqrt(3) / 2]
v1 + v2 + v3 == 0

Basis vectors for 4 electrode configs:

COEF_1 = 1
COEF_2 = sqrt(8) / 3        # sqrt(1 - coef_1**2/3)
COEF_3 = sqrt(2) / sqrt(3)  # sqrt(1 - coef_1**2/3 - coef_2**2/2)

v1 = [COEF_1, 0, 0]
v2 = [-COEF_1 / 3, COEF_2, 0]
v3 = [-COEF_1 / 3, -COEF_2 / 2, COEF_3]
v4 = [-COEF_1 / 3, -COEF_2 / 2, -COEF_3]
v1 + v2 + v3 + v4 == 0

Basis vectors for 5 electrode configs:

COEF_1 = 1
COEF_2 = sqrt(15) / 4       # sqrt(1 - coef_1**2/4)
COEF_3 = sqrt(5) / sqrt(6)  # sqrt(1 - coef_1**2/4 - coef_2**2/3)
COEF_4 = sqrt(5) / sqrt(8)  # sqrt(1 - coef_1**2/4 - coef_2**2/3 - coef_3**2/2)

v1 = [COEF_1, 0, 0, 0]
v2 = [-COEF_1 / 4, COEF_2, 0, 0]
v3 = [-COEF_1 / 4, -COEF_2 / 3, COEF_3, 0]
v4 = [-COEF_1 / 4, -COEF_2 / 3, -COEF_3 / 2, COEF_4]
v5 = [-COEF_1 / 4, -COEF_2 / 3, -COEF_3 / 2, -COEF_4]
v1 + v2 + v3 + v4 + v5 == 0

Easy to extend to any number of electrodes.

Position-to-signal decoding

Example for 4 electrodes, norm 1. Easy to generalize to any number of electrodes.

position = [0.5, 0.5, 1/sqrt(2)]
assert(norm(position) == 1)

e1 = dot(v1, position)  # 0.5
e2 = dot(v2, position)  # 0.30473785412436505
e3 = dot(v3, position)  # 0.17498134212744332
e4 = dot(v4, position)  # -0.9797191962518084
# e1 + e2 + e3 + e4 == 0
# hardware should generate a pulse in which current flows from e1/2/3 to e4
# or if hardware is incapable of such a pulse, a group of pulses that
# best replicates the sensation.

TODO: 4 electrodes, norm != 1

Maybe abs(e1) = abs(dot(v1, position)) * r + (1 - r)

Restim uses abs(e1) = norm(v1 * (1 - r/2) + position/2), this specification only works for threephase biphasic.