Utils

Notes on useful SDK operations, configuration examples & more

Additional operations

The following operations you should have a valid and initialized Notch network.

Shut down notches

You can programmatically send the turn off signal to all of the notches. NotchSerice.shutDown(...)

Coloring notches

Notches have a built in LED light that can be lit programmatically. You can interact with them and color all of them or color them individually.

  • Color each member of the Notch Network according to the Workout configuration: NotchService.color(...)

  • Color the whole network to a specific NotchColor for a specific time: NotchService.colorSingle(...)

  • Color a specific Notch to a specific NotchColor for a specific time: NotchService.colorSingle(device:color:timeMillis:success:failure:progress:cancelled)

Channels

Sometimes more than one notch network is operating in bluetooth range in the same time. The solution to evade interference between the different measurements is that notches can operate in several radio frequencies.

In practice first you have to turn on and connect to the notches that will be separate from the others. Then set a unique notch channel to them. Check out NotchService.changeChannel(...)

If you have different channels, any init call will find notches only in one channel. Check out NotchService.initWithChannelAndWorkout(...)

NotchChannel

The channels are represented with an enum value that can be represented with any value from the english alphabet A-Z. e.g:

  • NotchChannel.A
  • NotchChannel.H

Load workout configuration

The configuration file is a JSON file which is parsed during the measurement initialization. Here is the 3 notch measurement’s config file:

{
    "bones": [
        {
            "name": "ChestBottom",
            "color1": "Blue",
            "color2": "Blue",
            "frequency": 20
        },
        {
            "name": "RightUpperArm",
            "color1": "Red",
            "color2": "Red",
            "frequency": 20
        },
        {
            "name": "RightForeArm",
            "color1": "Green",
            "color2": "Green",
            "frequency": 20
        }
    ],
    "master_bone": "ChestBottom",
    "special": {
        "bone": "ChestBottom",
        "orientation": "Front"
    },
    "constraints": [
        {
            "type": "INTERP",
            "target": "Tummy",
            "source": "ChestBottom",
            "f": 0.5
        },
        {
            "type": "INTERP",
            "target": "ChestTop",
            "source": "Hip",
            "f": -0.42
        }
    ]
}

The following objects are obligatory:

  1. bones represent the bone-notch connections.
    • You must specify which bone is measured by its name. See all available bone
    • The default skeleton we use skeleton_male.js file is available in our template applications.
    • Set up the corresponding notch’s color (color1, color2 can be used to alternately light up)
    • Set up the frequency of the recording (use the same frequency)
  2. master_bone is one of the measured bones, which directly connects to the phone/tablet and manages the communication with the other devices. It is recommended to select a notch with good ‘visibility’ to the other notches for good connection, for example the the notch on the Chest if measured.
  3. special_bone is one of the measured bones which indicates the initial orientation of the person in the steady pose. Along with the steady measurement this is required to determine to exact placement of the notches on your body.
    • The notch should be placed on the selected body part (bone) with a pre-defined orientation.
    • This can be one of the following:
      • Front, Back, Left, Right which means that the notches top (white) side faces to the persons front, left, etc. side in the steady
      • LEDFront, LEDLeft, LEDBack, LEDRight which means that the LED of the notches faces to the corresponding direction.

Other options:

  1. constraints represent connection between bones if they are not measured specifically. In our example we set an interpolation between Tummy & ChestBottom also the ChestTop & Hip to move the target as the source with the given factor.
    • f: The given factor for some of the constraint type
    • type: The type of the constraint tells how to mimic the target bone to the source
      • INTERP: Interpolates between the 2 notches by the given factor
      • COPY: Copies the source
      • MIRROR: Mirrors the source
      • FIXEND: Fixes the end point
      • WALK: Helps with those movement where walk is involved. Turns of the steady root position to acquire more detailed movement. Can not be used in real time captures.
        Target & Source should be ‘Root’.
      • RUNNING: Helps with those movement where running is involved. Turns of the steady root position to acquire more detailed movement. Can not be used in real time captures.
        Target & Source should be ‘Root’.

Loading the skeleton

  • 
              
        Skeleton loadSkeleton() throws Exception {
            return Skeleton.from(
                    new InputStreamReader(
                            mApplicationContext.getResources().openRawResource(R.raw.skeleton_male), "UTF-8"));
        }
            
  • 
            
        func loadSkeleton() -> NotchSkeleton? {
            guard let file = Bundle.main.path(forResource: "skeleton_male.js", ofType: nil) else { return nil }
            do {
                let config = try String(contentsOf: URL(fileURLWithPath: file))
                return try NotchSkeleton.from(configJsonString: config)
            } catch {
                return nil
            }
        }
          

Loading the workout

  • 
              
        String readWorkoutConfig() throws IOException {
            return IOUtil.readAll(
                    new InputStreamReader(
                            mApplicationContext.getResources().openRawResource(R.raw.config_1_chest)));
        }
    
        Workout workout = Workout.from(
            "Demo_config",
            loadSkeleton(),
            readWorkoutConfig();
            
  • 
            
        func readWorkoutConfig() -> String? {
            guard let file = Bundle.main.path(forResource: "chest_config.js", ofType: nil) else { return nil }
            do {
                return try String(contentsOf: URL(fileURLWithPath: file))
            } catch {
                return nil
            }
        }
    
        let workout = NotchWorkout.from(
            name: "The name of the measurement",
            skeleton: loadSkeleton(),
            configString: readWorkoutConfig())
          

Prepare for capture
Template Applications