Skip to content

Demo Showcase: Scripted actions

A simple showcase of the telerobotic platform working, in which the Youbionic Half performs a scripted movement.

Showcase Video


Demo walkthrough

This demo intends to show how the platform operates. For this task, a simple client is used to control the Youbionic Half robot, and perform a series of scripted movements that resemble the action of looking towards your hand, opening and closing it, and then get back to your original position.

Server Connection

The first part of the cpp script, available on the next section, creates a client that connects to a given IP at the predefined port 57573:

/* Start connection */
Client c(ip);
    usleep(500000);

Robot Selection

Then the script selects the robot it wants to control, in this case Maroon - the ID used by the Youbionic Half robot in our setup, using the connectToMCU() function:

/* Select the mcu to control */
std::cout<<c.connectToMCU("Maroon") <<"\n";
    usleep(2500000); // Wait 2.5 seconds

Movement Configuration and Execution

For each movement, the client needs to generate a std::vector<int> in which to store the desired movements. For this client implementation, a uint32_t flag bitmask is also needed. This flag serves as an efficient way of indicating moveServos() the IDs of the servos that we want to move.

/* Combined movement 1 - Rise hand towards face, tilt head */
std::vector<int> pV1;{
    flag=0;
    pV1.push_back(0); // rotate palm towards face
    flag = (flag | (1<<13)); 
    pV1.push_back(0); // flex arm towards face
    flag = (flag | (1<<15)); 
    pV1.push_back(100); // Rotate arm towards body
    flag = (flag | (1<<17)); 
    pV1.push_back(179); // Tilt head towards hand
    flag = (flag | (1<<25)); 
    pV1.push_back(141); // Rotate head towards hand
    flag = (flag | (1<<26)); 
}
Lastly, the moveServos() function is used to send the movement order to the server, which will validate it and provide a two-step response (assuming it passes validation). The first ACK will be "intercepted" by moveServos(), which confirms that the order is valid, and that it will be sent to the robot for execution. The second response is read by the readServerResponse(), and it corresponds to the movement confirmation by the robot MCU.

std::cout<<c.moveServos(flag,pV1) <<" - Servo movemet confirmation\n";
std::cout<<c.readServerResponse() <<" - MCU confirmation of movement\n";
    usleep(1500000); // Wait 1.5 seconds

After every code section, the function usleep() is used to introduce a delay between instructions. While during normal usage this might not be required, in this script it comes in handy to force a minor pause between each block execution - making the individual movements much more obvious and deliberate.


Code for the Demo

Below is the main.cpp used for the demo. The complete source files for the client can be found in the TestClient dir of this github repo.

main.cpp
#include "Client.h"

#include <iostream>
#include <thread>
#include <unistd.h>


int main(int argc, char const *argv[]){

    uint32_t flag=0;

    /* Start connection */
    Client c(ip);
        usleep(500000);

    /* Select the mcu to control */
    std::cout<<c.connectToMCU("Maroon") <<"\n";
        usleep(2500000); // Wait 2.5 seconds


    /* Combined movement 1 - Rise hand towards face, tilt head */
    std::vector<int> pV1;{
        flag=0;
        pV1.push_back(0); // rotate palm towards face
        flag = (flag | (1<<13)); 
        pV1.push_back(0); // flex arm towards face
        flag = (flag | (1<<15)); 
        pV1.push_back(100); // Rotate arm towards body
        flag = (flag | (1<<17)); 
        pV1.push_back(179); // Tilt head towards hand
        flag = (flag | (1<<25)); 
        pV1.push_back(141); // Rotate head towards hand
        flag = (flag | (1<<26)); 
    }
    std::cout<<c.moveServos(flag,pV1) <<" - Servo movemet comprobation\n";
    std::cout<<c.readServerResponse() <<" - MCU confirmation of movement\n";
        usleep(1500000); // Wait 1.5 seconds

    /* Combined movement 3 - Close hand */
    std::vector<int> pV3;{
        flag=0;
        pV3.push_back(0); // Thumb
        flag = (flag | (1<<6)); 
        pV3.push_back(0); // Index
        flag = (flag | (1<<7)); 
        pV3.push_back(0); // Middle
        flag = (flag | (1<<8)); 
        pV3.push_back(0); // Ring
        flag = (flag | (1<<9)); 
        pV3.push_back(0); // Little
        flag = (flag | (1<<10));     }
    std::cout<<c.moveServos(flag,pV3) <<" - Servo movemet comprobation\n";
    std::cout<<c.readServerResponse() <<" - MCU confirmation of movement\n";
        usleep(1500000); // Wait 1.5 seconds

    /* Combined movement 4 - rest hand */
    std::vector<int> pV4;{
        flag=0;
        pV4.push_back(90); // Thumb
        flag = (flag | (1<<6)); 
        pV4.push_back(90); // Index
        flag = (flag | (1<<7)); 
        pV4.push_back(90); // Middle
        flag = (flag | (1<<8)); 
        pV4.push_back(90); // Ring
        flag = (flag | (1<<9)); 
        pV4.push_back(90); // Little
        flag = (flag | (1<<10)); 
    }
    std::cout<<c.moveServos(flag,pV4) <<" - Servo movemet comprobation\n";
    std::cout<<c.readServerResponse() <<" - MCU confirmation of movement\n";
        usleep(1500000); // Wait 1.5 seconds

    /* Combined movement 5 - Move arm and head back to "resting" position */
    std::vector<int> pV5;{
        flag=0;
        pV5.push_back(90); // rotate palm towards face
        flag = (flag | (1<<13)); 
        pV5.push_back(60); // flex arm towards face
        flag = (flag | (1<<15)); 
        pV5.push_back(70); // Rotate arm towards body
        flag = (flag | (1<<17)); 
        pV5.push_back(126); // Tilt head towards hand
        flag = (flag | (1<<25)); 
        pV5.push_back(100); // Rotate head towards hand
        flag = (flag | (1<<26)); 
    }
    std::cout<<c.moveServos(flag,pV5) <<" - Servo movemet comprobation\n";
    std::cout<<c.readServerResponse() <<" - MCU confirmation of movement\n";
        usleep(2500000); // Wait 2.5 seconds

}