Controlling robot via VM

That’s great to hear, what exactly solved the issue? To start moving the robot with the launch file you can use:

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

ROS navigation tutorials are a place you can start for high-level control such as the ones given by the construct guys ROS Navigation.

If the ROS node is working then you can safely ignore the example_walk as in the back-end they are both communicating in the same way!

I believe that your A1 was one of the earlier versions and the IP standard was not set at that time. Therefore it had different ones.

I followed your instructions regarding the catkin_make commands. That did the job. Very grateful for your help.

I was able to control the robot now with the keyboard using teleop, which is great :slight_smile:

It would be great if we could run the example_dance file. Do you know how we could do that? Our goals is to run a file that we preconfigured/coded like example_dance or example_walk. We don’t necessarily need precise control over the robot.

Thank you and best regards

1 Like

It is possible to perform pre-configured tasks with ROS for A1, for running the examples try running

sudo su
./example_walk

Unfortunately this didn’t work. These are the steps i did:

  1. Start robot, connect to wifi and SSH into nvidia board
  2. cd into unitree_legged_sdk
  3. sudo su
  4. ./example_walk

Here is the error message:
image

I checked the file and my first thought was that maybe the IP in there is not correct? I tried changing it from 161 to 12 in the example_walk.cpp file and remake the build folder. This however did not work either and i resetted it again to 161.

This is the example walk file:

class Custom
{
public:
// Custom(uint8_t level): safe(LeggedType::A1), udp(8090, “192.168.123.11”, 8082, sizeof(HighCmd), sizeof(HighState)){
Custom(uint8_t level): safe(LeggedType::A1), udp(8090, “192.168.123.161”, 8082, sizeof(HighCmd), sizeof(HighState)){
udp.InitCmdData(cmd);
udp.SetDisconnectTime(dt, 1);
// udp.SetDisconnectTime(0, 0);
}
void UDPRecv();
void UDPSend();
void RobotControl();

Safety safe;
UDP udp;
HighCmd cmd = {0};
HighState state = {0};
int motiontime = 0;
float dt = 0.002;     // 0.001~0.01

};

void Custom::UDPRecv()
{
udp.Recv();
}

void Custom::UDPSend()
{
udp.Send();
}

void Custom::RobotControl()
{
motiontime += 2;
udp.GetRecv(state);

// printf("%f %f %f %f %f\n", state.imu.rpy[1], state.imu.rpy[2], state.position[0], state.position[1], state.velocity[0]);

cmd.mode = 0;
cmd.gaitType = 0;
cmd.speedLevel = 0;
cmd.footRaiseHeight = 0;
cmd.bodyHeight = 0;
cmd.euler[0]  = 0;
cmd.euler[1] = 0;
cmd.euler[2] = 0;
cmd.velocity[0] = 0.0f;
cmd.velocity[1] = 0.0f;
cmd.yawSpeed = 0.0f;


if(motiontime > 0 && motiontime < 1000){
    cmd.mode = 1;
    cmd.euler[0] = -0.3;
}
if(motiontime > 1000 && motiontime < 2000){
    cmd.mode = 1;
    cmd.euler[0] = 0.3;
}
if(motiontime > 2000 && motiontime < 3000){
    cmd.mode = 1;
    cmd.euler[1] = -0.2;
}
if(motiontime > 3000 && motiontime < 4000){
    cmd.mode = 1;
    cmd.euler[1] = 0.2;
}
if(motiontime > 4000 && motiontime < 5000){
    cmd.mode = 1;
    cmd.euler[2] = -0.2;
}
if(motiontime > 5000 && motiontime < 6000){
    cmd.mode = 1;
    cmd.euler[2] = 0.2;
}
if(motiontime > 6000 && motiontime < 7000){
    cmd.mode = 1;
    cmd.bodyHeight = -0.2;
}
if(motiontime > 7000 && motiontime < 8000){
    cmd.mode = 1;
    cmd.bodyHeight = 0.1;
}
if(motiontime > 8000 && motiontime < 9000){
    cmd.mode = 1;
    cmd.bodyHeight = 0.0;
}
if(motiontime > 9000 && motiontime < 11000){
    cmd.mode = 5;
}
if(motiontime > 11000 && motiontime < 13000){
    cmd.mode = 6;
}
if(motiontime > 13000 && motiontime < 14000){
    cmd.mode = 0;
}
if(motiontime > 14000 && motiontime < 18000){
    cmd.mode = 2;
    cmd.gaitType = 2;
    cmd.velocity[0] = 0.4f; // -1  ~ +1
    cmd.yawSpeed = 2;
    cmd.footRaiseHeight = 0.1;
    // printf("walk\n");
}
if(motiontime > 18000 && motiontime < 20000){
    cmd.mode = 0;
    cmd.velocity[0] = 0;
}
if(motiontime > 20000 && motiontime < 24000){
    cmd.mode = 2;
    cmd.gaitType = 1;
    cmd.velocity[0] = 0.2f; // -1  ~ +1
    cmd.bodyHeight = 0.1;
    // printf("walk\n");
}

if(motiontime>24000 ){
    cmd.mode = 1;
}

udp.SetSend(cmd);

}

int main(void)
{
std::cout << “Communication level is set to HIGH-level.” << std::endl
<< “WARNING: Make sure the robot is standing on the ground.” << std::endl
<< “Press Enter to continue…” << std::endl;
std::cin.ignore();

Custom custom(HIGHLEVEL);
// InitEnvironment();
LoopFunc loop_control("control_loop", custom.dt,    boost::bind(&Custom::RobotControl, &custom));
LoopFunc loop_udpSend("udp_send",     custom.dt, 3, boost::bind(&Custom::UDPSend,      &custom));
LoopFunc loop_udpRecv("udp_recv",     custom.dt, 3, boost::bind(&Custom::UDPRecv,      &custom));

loop_udpSend.start();
loop_udpRecv.start();
loop_control.start();

while(1){
    sleep(10);
};

return 0; 

}

Please execute it from the computer system in which the install script has been run.

Yes, I ran it where I ran the install script. It always says Error: Bind client ip&port failed.

@Tahir, maybe you have some insights on this!

@nvmten Can you ping the robot and check ports if they are open or not on which you are receiving and sending data?
Usually in VMs have network issues. I will suggest do everything from plain Ubuntu install.

Thank you for your reply Tahir.

On Nvidia (192.168.123.12) these are the open connections:

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0    200 nx:ssh                  192.168.123.153:60719   ESTABLISHED
udp   213248      0 nx:8090                 192.168.123.161:8082    ESTABLISHED
udp        0      0 localhost:57397         localhost:domain        ESTABLISHED

These are the open connections when i netstat the raspberry pi (192.168.123.161):

Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0     36 192.168.123.161:ssh     192.168.123.153:60765   ESTABLISHED
udp        0      0 192.168.123.161:8008    192.168.123.10:8007     ESTABLISHED
udp     1536      0 192.168.123.161:8009    192.168.123.10:8007     ESTABLISHED

I tried to use the sdk on the robot without VM and it has the same problem.
My guess is that the IP and port is configured wrong? My nvidia board and raspberry pi have different static IP’s than the ones in the docs (they are reversed compared to those on docs.quadruped.de). If the unitree_legged_sdk works with standard IP’s, maybe it malfunctions due to this?

I appreciate your help on this.

Have you tried switching the IP?

Also, can you verify that the LCM has been built for the unitree_legged_sdk?

What is the best way to do that? I tried switching the adress defined in the example_walk.cpp file but that didn’t work.

With LCM built you mean the lcm files in the build folder?

Exactly, though the script should have already built it in the catkin_ws/utils/lcm-1.4.0/build. Please check if the example_wirelessHandle.cpp is working? Also can you tell the method of how you are connecting to the robot? is it via WiFi or LAN?

Also please connect to the A1 using your mobile phone and check the firmware version of the A1.

In lib/udp.h change the port according to the ones that are open for udp and build the build the folder as instructed in the readme.md of the unitree_legged_sdk

Then rerun the example.

Dear Sohail,

It worked! I rebuilt the lcm in the catkin_ws/utils/ folder. However, it only works when I run the example_walk file inside the unitree_legged_sdk-3.2.0 folder.

Is there any way I can make it work with the sdk 3.3.1? I copied the 3.3.1 version into the catkin_ws/utils directory and tried to run it but it gave me the ip&port error.

So I compared the working 3.2 version with the 3.3.1 version and here is what I found:

  • udp.h file is identical
  • example_walk.cpp is not the same. In the connection section, the 3.2.0 example_walk.cpp file (which works) has this:
public:
    Custom(uint8_t level): safe(LeggedType::A1), udp(level){
        udp.InitCmdData(cmd);
    }
    void UDPRecv();
    void UDPSend();
    void RobotControl();

    Safety safe;
    UDP udp;
    HighCmd cmd = {0};
    HighState state = {0};
    int motiontime = 0;
    float dt = 0.002;     // 0.001~0.01
};

The 3.3.1 example_walk.cpp file has this:

public:
    Custom(uint8_t level): safe(LeggedType::A1), udp(8090, "192.168.123.161", 8082, sizeof(HighCmd), sizeof(HighState)){
        udp.InitCmdData(cmd);
    }
    void UDPRecv();
    void UDPSend();
    void RobotControl();

    Safety safe;
    UDP udp;
    HighCmd cmd = {0};
    HighState state = {0};
    int motiontime = 0;
    float dt = 0.002;     // 0.001~0.01
};

I ran the example_walk file again after I changed that part. It seems to have connected, but the robot isn’t moving.

1 Like

Dear @nvmten,

Great to hear that, I believe that v3.2 works with specific firmware of the A1. v3.3.1 requires a different perhaps an updated firmware but I will to confirm that and get back to you!

Hi @Sohail, do you have an update for me?

Thank you and best regards
tenzin

Pardon the late reply, I’ve contacted the manufacturers and they have reached the same conclusion that it may be due to a firmware mismatch.

The app can be downloaded from the docs. Also if possible please send a screenshot of the error.

You can check the firmware of your robot via the mobile app or by running this command.

cd /home/unitree/Unitree/keep_program_alive
./bin/A1_sport_1 -v