mavlink / MAVSDK-Java

MAVSDK client for Java.
76 stars 44 forks source link

Running the MAVSDK server in UDP client mode #141

Open Zxr1230 opened 1 year ago

Zxr1230 commented 1 year ago

I am trying to run the Mavsdk in the android-client example with the UDP client mode. I tried mavsdkServer.run("udp://192.168.42.129:14552", 50051); mavsdkServer.run("udp://192.168.42.129:14550", 50051); and mavsdkServer.run("udp://192.168.42.129:14540", 50051); but no one get to the next line -- drone = new System(BACKEND_IP_ADDRESS, mavsdkServerPort);

I wonder if I am doing it correctly. Thank you!

image

JonasVautherin commented 1 year ago

What are 14552, 14550 and 14540? Are they the port on which the autopilot listens for MAVLink (so MAVSDK should send to 14552, etc), or are they the port to which the autopilot sends MAVLink?

I would guess it's the latter, in which case you want to try udp://:14552.

Zxr1230 commented 1 year ago

What are 14552, 14550 and 14540? Are they the port on which the autopilot listens for MAVLink (so MAVSDK should send to 14552, etc), or are they the port to which the autopilot sends MAVLink?

I would guess it's the latter, in which case you want to try udp://:14552.

Thanks for replying! I saw the MAVSDK default is 14540 or 14550, and I found the port number might be 14552. I tried run("udp://:14540", 50051); run("udp://:14550", 50051); and run("udp://:14552", 50051); before but none works.

JonasVautherin commented 1 year ago

What is your setup? What does the autopilot expect? Does the autopilot send MAVLink messages over the network? It depends on your setup, you need to provide more details if you want us to help :see_no_evil:.

Zxr1230 commented 1 year ago

What is your setup? What does the autopilot expect? Does the autopilot send MAVLink messages over the network? It depends on your setup, you need to provide more details if you want us to help 🙈.

I installed the Android example app in the Herelink ground controller and I am trying to control my ArduPilot drone. I didn't make any changes in settings so everything should be default. Let me know if you need anything, and any details. Thank you very much for helping!

JonasVautherin commented 1 year ago

Are you sure that Ardupilot sends MAVLink to 14550? Doesn't MAVSDK have to initiate the connection to Ardupilot on a port like 5760? I am not sure but I think you need to check that. If MAVSDK needs to initiate the connection, then it's udp://<ip_of_ardupilot>:<port_of_ardupilot>.

Zxr1230 commented 1 year ago

Are you sure that Ardupilot sends MAVLink to 14550? Doesn't MAVSDK have to initiate the connection to Ardupilot on a port like 5760? I am not sure but I think you need to check that. If MAVSDK needs to initiate the connection, then it's udp://<ip_of_ardupilot>:<port_of_ardupilot>.

I found that Herelink creates a UDP client that emits data to the 14550 port. By default, the MAVSDK server creates a UDP server using the 14550 port. So if MAVSDK needs to initiate the connection, I should do something like run("udp://192.168.42.129:5760", 50051); right? Thank you!

JonasVautherin commented 1 year ago

Oh, on Herelink I think you should listen on 14551: udp://:14551. See here for instance. You can also edit the mavlink-router configuration file.

Does QGC work on Herelink? If you run it, does it get MAVLink messages?

Zxr1230 commented 1 year ago

Oh, on Herelink I think you should listen on 14551: udp://:14551. See here for instance. You can also edit the mavlink-router configuration file.

Does QGC work on Herelink? If you run it, does it get MAVLink messages?

Thank you! The QGC works fine on Herelink. Do I need to use 5760 to initiate the connection?

JonasVautherin commented 1 year ago

Try to stop/kill QGC and run MAVSDK with udp://:14551 first, I would say.

Zxr1230 commented 1 year ago

Try to stop/kill QGC and run MAVSDK with udp://:14551 first, I would say.

Thank you! It went to the next line. However, it went to the next line whether the drone is powered on or not. Should it go to the next line only when it gets the flight controller's heartbeat?

JonasVautherin commented 1 year ago

Oh right, that is a problem. I believe it is because the Herelink air unit sends MAVLink messages with a different system_id, and MAVSDK-Java expects exactly one system (the drone). If MAVSDK-Java receives the Herelink heartbeat before the drone heartbeat, then it is screwed and you have to restart the app :see_no_evil:.

It is fixed in C++, but I had not made a MAVSDK-Java release with the fix. I'll try to do that in the next few days.

In the meantime, make sure that the flight controller is already running when you start your app, and if the app doesn't receive e.g. telemetry, assume that it is not connected to the right system and restart it. That's a bit inconvenient, but in my experience most of the time it picks up the autopilot. Again, a proper fix is coming in the next MAVSDK-Java release :see_no_evil:.

Zxr1230 commented 1 year ago

Oh right, that is a problem. I believe it is because the Herelink air unit sends MAVLink messages with a different system_id, and MAVSDK-Java expects exactly one system (the drone). If MAVSDK-Java receives the Herelink heartbeat before the drone heartbeat, then it is screwed and you have to restart the app 🙈.

It is fixed in C++, but I had not made a MAVSDK-Java release with the fix. I'll try to do that in the next few days.

In the meantime, make sure that the flight controller is already running when you start your app, and if the app doesn't receive e.g. telemetry, assume that it is not connected to the right system and restart it. That's a bit inconvenient, but in my experience most of the time it picks up the autopilot. Again, a proper fix is coming in the next MAVSDK-Java release 🙈.

Thank you! How can I tell if the app receives telemetry information? When the drone is off, it also goes through these lines of code. image

JonasVautherin commented 1 year ago

The RxJava subscription will happen no matter what. But if you receive e.g. positions, then the onNext callback will receive events. This one:

position -> {
    [...]
    viewModel.currentPositionLiveData.postValue(latLng);
}
Zxr1230 commented 1 year ago

The RxJava subscription will happen no matter what. But if you receive e.g. positions, then the onNext callback will receive events. This one:

position -> {
    [...]
    viewModel.currentPositionLiveData.postValue(latLng);
}

Thank you! When the app is started after the drone is powered on, it skips viewModel.currentPositionLiveData.postValue(latLng); this line like the drone is off. Is it right? Did it receive positions? image

JonasVautherin commented 1 year ago

Not sure I understand the question. If you receive positions, then .postValue will trigger, so from your currentPositionLiveData you can check that :thinking:.

Zxr1230 commented 1 year ago

Not sure I understand the question. If you receive positions, then .postValue will trigger, so from your currentPositionLiveData you can check that 🤔.

I started the app after the drone was on. It skips over line viewModel.currentPositionLiveData.postValue(latLng); It seems like it didn't trigger right? Thank you!

JonasVautherin commented 1 year ago

Are you familiar with RxJava? You are basically registering a callback, which won't be triggered at the moment where you register it, but at a later time, right?

Zxr1230 commented 1 year ago

Oh, right. I am sorry. I got it now. The drone displays the flight mode as LOIT but the app displays the flight mode as unknown. Is this normal? Thank you! image image

JonasVautherin commented 1 year ago

Hmm I think it should receive something (both with PX4 and Ardupilot) :thinking:. Do you receive any telemetry at all, like position or battery updates?

Zxr1230 commented 1 year ago

Hmm I think it should receive something (both with PX4 and Ardupilot) 🤔. Do you receive any telemetry at all, like position or battery updates?

Thank you! I think it got the position. Where are battery updates? image

JonasVautherin commented 1 year ago

Battery is defined here, in Java it will result in something like drone.getTelemetry().getBattery() :+1:.

Zxr1230 commented 1 year ago

Battery is defined here, in Java it will result in something like drone.getTelemetry().getBattery() 👍.

Thank you! For battery, I got this. It looks right. I always need to run the QGC first, then it can receive the drone heartbeat. Otherwise, it keeps receiving the Herelink heartbeat and no telemetry information can be received.
image image