mavlink / MAVSDK-Java

MAVSDK client for Java.
71 stars 41 forks source link

System.Shell.send(String command) not working #62

Closed divyanshupundir closed 3 years ago

divyanshupundir commented 3 years ago

Hello.

First of all, I'd like to say that the MAVSDK team has done an incredible job, especially with MAVSDK-Java.

I have been trying to use the vehicle's system shell to send and receive commands. The setup is as follows:

We have a physical drone running PX4 over NuttX. The telemetry module is connected to my laptop. I am using Mavlink Router to route MavLink messages to QGC, which is running on the same laptop, and my phone, which is connected to the same Wi-Fi network as the laptop.

Now, when I use QGC's MavLink shell to send a command (eg. echo "Hello"), I am able to receive its response on the app through System.Shell.receive(). But when I send a command using System.Shell.send(String command), nothing happens, on both QGS and the app.

Everything else is working fine.

julianoes commented 3 years ago

Hi! Thanks for the words, always nice to hear!

There was once a problem when there was no newline, so you could try to send echo "Hello"\n.

If that's not it then I would suspect something wrong with the routing of the mavlink messages, or some bug in the MAVSDK-Java wrapper. I'll do some tests to see if I can reproduce it.

divyanshupundir commented 3 years ago

There was once a problem when there was no newline, so you could try to send echo "Hello"\n.

I did try this: send(command + "\n")

And even:

send(command)
send("\n")

But neither worked.

something wrong with the routing of the mavlink messages

I'll try to alter the setup and see if that works or not.

divyanshupundir commented 3 years ago

So, now I simply connected the telemetry to my phone, removing the MavLink Router, and still, I'm not getting any response for the commands that I'm sending (with and without adding the newline).

I don't know if it's still the problem of message routing because all the other things (telemetry data reception, actions, mission upload, etc.) are working perfectly.

julianoes commented 3 years ago

Ok, so we can exclude routing. And sending multiple commands and then receiving answers does not work either? I just had that with Python where the first one didn't see to work but the second one.

divyanshupundir commented 3 years ago

Ok, so we can exclude routing.

I think yes, we can exclude routing.

And sending multiple commands and then receiving answers does not work either?

So in the setup in which the telemetry is directly attached to my phone, I've tried the following and neither worked:

Shell shell = drone.getShell();
  1. Without newline:

    shell.send(command);
  2. With newline in the same command

    shell.send(command + "\n");
  3. Newline as a separate command

    shell.send(command);
    shell.send("\n");
  4. Both

    
    shell.send(command + "\n");
    shell.send("\n");


> I just had that with Python where the first one didn't see to work but the second one.

I'll try to use MAVSDK-Python on my PC to see if it's a problem with the telemetry module or not, and then I'll let you know if it works.
divyanshupundir commented 3 years ago

Actually, I tried sending commands from the QGC app on my phone, and it is working fine.

Do you think it could be a problem with the MAVSDK-Server on Android?

JonasVautherin commented 3 years ago

Do you think it could be a problem with the MAVSDK-Server on Android?

I guess the next thing will be to check what's happening on the mavsdk_server side indeed. I would suggest the following setup:

  1. Run mavsdk_server from your computer (not from Android), connecting it to your drone
  2. Connect MAVSDK-Java from Android to that mavsdk_server (by setting the ip and port correctly)
  3. Try to run the same code from Android, and see if that works (so it will go Android <---> mavsdk_server on computer <---> drone)

I expect that it will behave the same as what you are seeing now. But from that setup, we'll be able to add some debug output to mavsdk_server and see if the messages are sent and received correctly.

Does that make sense?

divyanshupundir commented 3 years ago

Does that make sense?

Yes, that does make sense. And I tried it just a few minutes ago, but the result was the same as before.

But after this, I tried running the mavsdk_server on my PC alongside MAVSDK-Python and QGC connected through the mavlink router. And just as @julianoes had mentioned, it worked well (I had to add \n at the end to make it work). I was able to see the response on both QGC and the terminal running the Python code.

I guess it is a problem with the send() method of Java wrapper and not the Android mavsdk server. What do you think?

Here's the Python code that I had used:

import asyncio
from mavsdk import System

async def run():
    drone = System(mavsdk_server_address="localhost", port=48881)
    await drone.connect()

    await drone.shell.send("echo 2000000000\n")

    async for receive in drone.shell.receive():
        print(receive)

if __name__ == "__main__":
    asyncio.ensure_future(run())
    asyncio.get_event_loop().run_forever()
JonasVautherin commented 3 years ago

I guess it is a problem with the send() method of Java wrapper and not the Android mavsdk server. What do you think?

Yes it does sound like it... Could it be that the \n is escaped in Java? Like should we use \\n or something? :thinking:

divyanshupundir commented 3 years ago

Like should we use \\n or something?

I tried this just now, still didn't work. Could it be that the Java wrapper is doing some kind of a trim() operation that removes the newline at the end?

Apart from this, I did another test:

  1. I ran only mavsdk server on an android app and not MAVSDK Java.
  2. The server was running on my phone connected to the physical drone.
  3. MAVSDK Python running on my PC was connected to the server on my phone.

And again, the Python code worked. I guess I'm pretty sure that it's not the android mavsdk server that is causing the problem.

JonasVautherin commented 3 years ago

So the C++ shell implementation does add a \n if it's missing: https://github.com/mavlink/MAVSDK/blob/develop/src/plugins/shell/shell_impl.cpp#L44-L47

The best would be to compile mavsdk_server and add some debug output there to see what's coming from Java...

divyanshupundir commented 3 years ago

The best would be to compile mavsdk_server and add some debug output there to see what's coming from Java...

I did this and couldn't see any logs generated while using Java, but Python was working fine.

So, on having a closer look at my code, I found that the bug was from my side :sweat_smile:.

What I was doing wrong was that I wasn't subscribing the to Completable returned by System.Shell.send() method. It's working now.

Sorry about that. And thanks a lot @julianoes and @JonasVautherin for the suggestions and help.

JonasVautherin commented 3 years ago

Hehe, no worries. Good that it works now :smile:.

BTW, would you mind writing a shell example for Java? Next to the other ones (here)?

divyanshupundir commented 3 years ago

Sure. What would you like in that? Any specific commands?

divyanshupundir commented 3 years ago

I made one that simply reads and sends the commands till the user enters "exit".

JonasVautherin commented 3 years ago

Yes that's perfect