Closed jjcetraro closed 2 years ago
It is not known, it actually sounds like a regression.
Would you be willing to contribute a fix for that? I'm happy to help/review :blush:.
It is not known, it actually sounds like a regression.
Would you be willing to contribute a fix for that? I'm happy to help/review 😊.
I can try :D
Ok, I did a bit of research.. The last release without the bug is 'io.mavsdk:mavsdk-server:0.10.0'.. So, this bug was introduced in 'io.mavsdk:mavsdk-server:0.11.0'.
I saw the differences between both versions, and I think the change that introduced the bug was in the file 'mavsdk_server/build.gradle', and the problem is that you changed the mavsdk_server version you use, from v0.43.0 to v0.48.0.
I mean, with mavsdk_server_release v0.43.0 the code works, and with the v0.48.0 it doesn't.
I also saw the difference in the stop method between those two versions, and I saw that the difference is the following:
// v0.43.0
void stop() { _server->stop(); }
// v0.48.0
void stop()
{
_connection_initiator.cancel();
if (_server != nullptr) {
_server->stop();
}
}
do you know why this _connection_initiator.cancel() was introduced to the code? can we remove it to verify if it is the problem?
best regards!
I think that's because now, start()
will block until the remote System is discovered. If you try to stop before that, then stop()
has to cancel that blocking call.
BTW you mention "Closed connection on serial port 0". Are you using a serial connection on Android? Did you try with a UDP connection, just to see if that's different?
The SITL I am using for testing, only exposes TCP endpoints to connect. I don't know why it says "serial" in the message, because I was connecting from the Android device using TCP.
Anyway, I tested using UPD instead of TCP. Because the SITL does not expose any UDP endpoint, I had to use mavproxy. So, I used mavproxy to redirect the telemetry from TCP to UDP. In my deploy, I have one computer with the SITL (192.168.250.147), and the Android device (192.168.250.148). My first try was to expose the telemetry (with mavproxy) using the SITL ip address, and try to connect from the android device to the SITL ip address using mavsdk_server. This didn't work:
2022-04-26 17:47:32.710 28124-28124/com.ksi.missionkeeper I/Mavsdk: MAVSDK version: v1.2.0
2022-04-26 17:47:32.711 28124-28124/com.ksi.missionkeeper D/MAVSDK-Server: Running mavsdk_server with connection url: udp://192.168.250.147:14540
2022-04-26 17:47:32.711 28124-28124/com.ksi.missionkeeper I/Mavsdk: Waiting to discover system on udp://192.168.250.147:14540...
2022-04-26 17:47:32.712 28124-28124/com.ksi.missionkeeper D/Mavsdk: Initializing connection to remote system...
Then I tried to redirect the telemetry to the android device ip, and connect with mavsdk_server using udp://:14540. This second try worked:
2022-04-26 17:54:36.644 30202-30202/com.ksi.missionkeeper I/Mavsdk: MAVSDK version: v1.2.0
2022-04-26 17:54:36.645 30202-30202/com.ksi.missionkeeper D/MAVSDK-Server: Running mavsdk_server with connection url: udp://:14540
2022-04-26 17:54:36.645 30202-30202/com.ksi.missionkeeper I/Mavsdk: Waiting to discover system on udp://:14540...
2022-04-26 17:54:36.765 30202-30429/com.ksi.missionkeeper I/Mavsdk: New system on: 192.168.250.147:41636 (with sysid: 1)
2022-04-26 17:54:36.765 30202-30429/com.ksi.missionkeeper D/Mavsdk: New: System ID: 1 Comp ID: 1
2022-04-26 17:54:36.765 30202-30429/com.ksi.missionkeeper D/Mavsdk: Component Autopilot (1) added.
2022-04-26 17:54:37.358 30202-30429/com.ksi.missionkeeper D/Mavsdk: Discovered 1 component(s)
2022-04-26 17:54:37.359 30202-30428/com.ksi.missionkeeper I/Mavsdk: System discovered
2022-04-26 17:54:37.363 30202-30202/com.ksi.missionkeeper I/Mavsdk: Server started
2022-04-26 17:54:37.363 30202-30202/com.ksi.missionkeeper I/Mavsdk: Server set to listen on 0.0.0.0:46567
2022-04-26 17:54:37.363 30202-30202/com.ksi.missionkeeper D/MAVSDK-Server: mavsdk_server is now running, listening on port 46567
2022-04-26 17:54:37.515 30202-30429/com.ksi.missionkeeper W/Mavsdk: command unsupported (512).
After this, I tried to stop the mavsdk_server and connect again, and I receive the following error:
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper I/Mavsdk: MAVSDK version: v1.2.0
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper D/MAVSDK-Server: Running mavsdk_server with connection url: udp://:14540
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper I/Mavsdk: Waiting to discover system on udp://:14540...
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper E/Mavsdk: bind error: Address already in use
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper E/Mavsdk: Connection failed: Bind error
All this executions were using the version 1.1.1. After this, I made the same test using version 0.7.0, and with this old version I can connect and disconnect all the times I want (so the stop method works fine in this old version using udp too).
So is it that _connection_initiator.cancel();
does not return correctly when you stop()
?
I don't really know because right now I only executed the android-client project, so I can't debug that part of the code.. I will try to execute the mavsdk_server in my laptop to see if I can debug that line and see what is happening there.. thanks!
Another question.. I am trying to build the mavsdk_server, and I am using this command:
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_MAVSDK_SERVER=ON -Bbuild/default -H.
cmake --build build/default -j8
https://mavsdk.mavlink.io/main/en/cpp/guide/build_mavsdk_server.html
Where should I execute it? in /MAVSDK or in /MAVSDK/src/mavsdk_server?
In the root of the repo (where the root CMakeLists.txt is), so what I guess you mean by "/MAVSDK" :+1:
Thats what I thought... Have you ever seen this error?
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink
[ 12%] Performing download step (git clone) for 'mavlink'
Cloning into 'mavlink'...
fatal: reference is not a tree: 3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2
CMake Error at /home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink/mavlink/tmp/mavlink-gitclone.cmake:49 (message):
Failed to checkout tag: '3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2'
CMakeFiles/mavlink.dir/build.make:97: recipe for target 'mavlink/src/mavlink-stamp/mavlink-download' failed
make[2]: *** [mavlink/src/mavlink-stamp/mavlink-download] Error 1
CMakeFiles/Makefile2:82: recipe for target 'CMakeFiles/mavlink.dir/all' failed
make[1]: *** [CMakeFiles/mavlink.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2
CMake Error at third_party/cmake/build_target.cmake:51 (message):
/home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink
failed to build!
Call Stack (most recent call first):
third_party/CMakeLists.txt:31 (build_target)
-- Configuring incomplete, errors occurred!
See also "/home/dronedojo/github_repos/MAVSDK/build/default/CMakeFiles/CMakeOutput.log".
Seems like there is something wrong with the main
branch. I'll have a look tomorrow :+1:
A fix is coming here: https://github.com/mavlink/MAVSDK/pull/1758
I cloned the repo again and I am having the same error when I try to build the code.. do you think that maybe it is because of the ubuntu version I am using? (16.04.7 LTS)
Oh really? It solved the problem for me :thinking:. Is that a clean clone, or did you have the build/ folder remaining from the previous tries?
No no, I remove the folder and clone the repo again using "git clone https://github.com/mavlink/MAVSDK.git"
After that, I enter to folder using "cd MAVSDK", and then I executed the command for linux:
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_MAVSDK_SERVER=ON -Bbuild/default -H.
And you get the exact same issue? Can you try to edit that line (the one I removed) and change it to GIT_SHALLOW FALSE
then?
I added GIT_SHALLOW FALSE in that file and I have the same error :(
Would you mind removing the folder again, cloning again (and setting GIT_SHALLOW FALSE), then running cmake again and copy-pasting the error?
My question is whether the hash is the same: 3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2. Because that hash does exist in the repo, so unless it is a shallow clone, it should be there :thinking:.
I recorded the whole process :)
https://www.youtube.com/watch?v=2JM-nwhAqc0
the error is the same I posted 8 days ago
I suspect it's related to the version of CMake you are using (it's quite old with Ubuntu 16). Can you update CMake? It should be on snap, for instance.
but I am using the last version, 3.23.1 haha.. do you think it is not compatible with ubuntu 16? ... Which ubuntu version are you using?
Wait...
the error is the same I posted 8 days ago
What you posted back then said:
Cloning into 'mavlink'...
fatal: reference is not a tree: 3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2
CMake Error at /home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink/mavlink/tmp/mavlink-gitclone.cmake:49 (message):
Failed to checkout tag: '3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2'
What I see in your video is:
ImportError: No module named 'future'
Am I missing something? At least you should solve that error, which is a python dependency that needs to be installed.
@jjcetraro did you read this line in the README?
@jjcetraro @JonasVautherin, I saw this issue just today. I'm not sure if it is due to the new API changes. Please let me know if you've figured it out. Otherwise, I'll rewrite the android-client example.
@divyanshu1234 thanks for contacting.. I saw that line, and I tried to stop the mavsdk_server using that example, but that didn't work.
It is really easy to test.. if you use an old version, you can stop and reconnect the mavsdk_server anytime you want. With the last version, if you stop the mavsdk_server, when you try to reconnect it, you receive an error that says that the port is busy, so the stop method is not working.
Can you test it and see if you can fix it? :)
@jjcetraro, sure I'll go through the example. But please give me some time. I've been having quite busy weeks for some time.
This comment is just a suggestion based on my experience with using this library to build a GCS for over a year. I'll try to tell you why we designed our GCS as something vastly different from the android-client example.
The System
and MavsdkServer
objects shouldn't be owned by an Activity:
You should keep them as singletons and pass them around in repositories using DI frameworks like Hilt. This is because you may need them in several Activities.
Tie the life cycles of these objects to that of the Application:
You can use a foreground Service
to achieve this. Running and stopping the MavsdkServer
and System
objects again and again may cause an overhead. You'll also have to handle too many clean ups.
While flying a drone, the pilot isn't going to put the GCS in the background for a long time.
Try to avoid maintaing any drone related state in your application: The MAVSDK Server is really well designed and maintains important states quite well. Just try to understand the library in depth and use the power of RxJava for complex operations and data buffering at the ViewModel layer.
Thanks for the suggestion. The truth is we are not developing a GCS, we are only using the mavsdk lib to get the drone telemetry. Anyway, this suggestion is very relevant for our project.
Are you planning to update the android-client example to use the last version of the mavsdk lib?
I am not hurry about this, just need to know if you are planning to update that project. That would be really really helpful for me :)
Thanks!
@jjcetraro Sorry for not being able to respond. I'll try to have a look at the android-client in a few days.
I am trying to solve the problem, is it possible to see the c++ mavsdk_server logs
One easy way I like for debugging is to run mavsdk_server
on my laptop and connect MAVSDK-Java
to it from the phone :+1:
Even I tried to find and fix the issue from Java side and couldn't. Looks like it's a problem with the C++ server.
Can someone fix this bug? and Update the java SDK?
So what's happening, exactly? When you call mavsdkServer.stop()
, does it return, or does it hang? Did you try with a more recent of mavsdk_server
, e.g. v1.4.2?
I tried to stop from C++, and it seems to work. Also the swift example app uses mavsdk_server_stop()
and it seems fine there :thinking:.
I‘m use tcp connection ,After successful connection, exit app, enter, The bug can appear
It would be interesting to get a stack trace of where it hangs.
I‘m use tcp connection ,After successful connection, exit app, enter, The bug can appear
What is the bug? Does it crash? Does it hang? Does it just not stop mavsdk_server?
Ok, I will try to give you all the info you need to reproduce the bug:
bind error: Address already in use Connection failed: Bind error
I forgot to tell that for testing I am using a sim_vehicle in a laptop, and I am using mavproxy in the same laptop to redirect the telemetry from the laptop to the android device.
For all these tests I created a new branch called jjcetraro in the cloned repo. I leave a link to download it in case you think it could be useful:
Hi! Any update? 😄
I'm trying to run your test app. I'm not very familiar with Android and how to run things in it. Are you using it in an x64 emulator, or on an arm device?
It's crashing for me, any idea? (I'm not very familiar with this stuff)
E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.mavsdk.androidclient, PID: 22933
java.lang.RuntimeException: Unable to start activity ComponentInfo{io.mavsdk.androidclient/io.mavsdk.androidclient.MapsActivity}: java.lang.SecurityException: getDataNetworkTypeForSubscriber
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3778)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3940)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:109)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2345)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:233)
at android.os.Looper.loop(Looper.java:344)
at android.app.ActivityThread.main(ActivityThread.java:8210)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
Caused by: java.lang.SecurityException: getDataNetworkTypeForSubscriber
at android.os.Parcel.createExceptionOrNull(Parcel.java:2441)
at android.os.Parcel.createException(Parcel.java:2425)
at android.os.Parcel.readException(Parcel.java:2408)
at android.os.Parcel.readException(Parcel.java:2350)
at com.android.internal.telephony.ITelephony$Stub$Proxy.getNetworkTypeForSubscriber(ITelephony.java:9300)
at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:2990)
at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:2954)
at com.mapbox.android.telemetry.TelemetryUtils.obtainCellularNetworkType(TelemetryUtils.java:165)
at com.mapbox.mapboxsdk.module.telemetry.PhoneState.<init>(PhoneState.java:39)
at com.mapbox.mapboxsdk.module.telemetry.TelemetryImpl.onAppUserTurnstileEvent(TelemetryImpl.java:46)
at com.mapbox.mapboxsdk.maps.MapView.onCreate(MapView.java:303)
at io.mavsdk.androidclient.MapsActivity.onCreate(MapsActivity.java:77)
at android.app.Activity.performCreate(Activity.java:8129)
at android.app.Activity.performCreate(Activity.java:8109)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1344)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3747)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3940)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:109)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2345)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:233)
at android.os.Looper.loop(Looper.java:344)
at android.app.ActivityThread.main(ActivityThread.java:8210)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
Ok, I got around that by adding this line to app/build.gradle
implementation 'com.mapbox.mapboxsdk:mapbox-android-telemetry:6.1.0'
Now, as soon as I press the Run button I see this:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.mavsdk.androidclient, PID: 24596
java.lang.NullPointerException: Attempt to invoke virtual method 'long com.mapbox.mapboxsdk.plugins.annotation.Annotation.getId()' on a null object reference
at com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager.delete(AnnotationManager.java:164)
at io.mavsdk.androidclient.MapsActivity.onClickButtonRunStop(MapsActivity.java:268)
at io.mavsdk.androidclient.MapsActivity.lambda$onCreate$1$MapsActivity(MapsActivity.java:85)
at io.mavsdk.androidclient.-$$Lambda$MapsActivity$-XliznwkB4ydfom4cAvnKRDe22g.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:7488)
at android.view.View.performClickInternal(View.java:7464)
at android.view.View.access$3700(View.java:841)
at android.view.View$PerformClick.run(View.java:28905)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:233)
at android.os.Looper.loop(Looper.java:344)
at android.app.ActivityThread.main(ActivityThread.java:8210)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
Ok, I fixed that by changing:
diff --git a/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java b/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java
index 77bf594..75ff4cc 100644
--- a/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java
+++ b/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java
@@ -265,8 +265,10 @@ public class MapsActivity extends AppCompatActivity implements OnMapReadyCallbac
}
});
- symbolManager.delete(currentPositionMarker);
- currentPositionMarker = null;
+ if (currentPositionMarker != null) {
+ symbolManager.delete(currentPositionMarker);
+ currentPositionMarker = null;
+ }
// change mIsMavsdkServerRunning value
mIsMavsdkServerRunning = false;
Now I can reproduce it:
I/Quality: Skipped: false 2 cost 37.492622 refreshRate 16666666 processName io.mavsdk.androidclient
I/Mavsdk: MAVSDK version: v1.2.0
D/MAVSDK-Server: Running mavsdk_server with connection url: udp://:14540
I/Mavsdk: Waiting to discover system on udp://:14540...
E/Mavsdk: bind error: Address already in use
E/Mavsdk: Connection failed: Bind error
I/Quality: Skipped: false 1 cost 27.680754 refreshRate 16666666 processName io.mavsdk.androidclient
It took me a while to be able to make manual changes to mavsdk_server and have that deployed to my phone without having to do maven releases (which I probably can't). Eventually I figured that out using the instructions here: https://stackoverflow.com/questions/9744721/relative-project-dependencies-in-gradle.
What I found is that when you do stop it might stop the gRPC server (although I'm not 100% sure there) but it certainly won't stop the MavsdkServer
and won't destruct Mavsdk
, so the connection is still there and will cause the bind error next time you try to start it.
I came up with this fix for it: https://github.com/mavlink/MAVSDK/pull/1877 I doubt it's the right way but I'll leave it to @JonasVautherin to comment on it.
@jjcetraro this is how I tested it: https://github.com/mavlink/MAVSDK-Java/pull/104
Incredible work what you did @julianoes ! Let's wait @JonasVautherin can authorize the merge 😄
@JonasVautherin @divyanshu1234 any news? 😃
Yes, @JonasVautherin is back and commented. Let's see.
@jjcetraro does this fix your issue? Just out of curiosity, doesn't it also work to call destroy()
after calling stop()
? My feeling is that it should have the same effect :thinking: (regarding the bind error: Address already in use
).
Still, I agree that stop()
should stop MAVSDK, but I'm not sure if I agree with https://github.com/mavlink/MAVSDK/pull/1877 :innocent:
Hi @JonasVautherin! thanks for your support. I didn't test this new code, but I trust @julianoes that he test it and it works. Destroying the activity is not enough. I tested it many times, and the problem persists. The only thing that seems to work is to close the app, but that is unlikely.
One thing I saw is that when you execute the run method for the first time, a lot of threads are created:
The thing is that when you stop it, the threads are still there. I tried to destoy them manually, but with no success. I think that another way to unbind the port without closing the app, would be killing those threads, but I do not know how to do that. Thread.interrupt() doesn't work haha.
What are we waiting to release a new version of the library with the fix made by julianoes? 😃
I was testing the android-client example, and the mavsdkServer.stop() call in the onPause of the MapsActivity works fine. I mean, I am testing with a sim_vehicle, and I can see on the console that when I connect to the vehicle I see "New connection on serial port 0" on the console, and when I leave the MapsActivity, I see "Closed connection on serial port 0".
This example is using:
I tried to update to the last version (1.1.1), and the connection to the sim_vehicle works fine, but with this last version what is not working is the stop method. When I leave tha activity, I don't see the "Closed connection on serial port 0" on the console, and I have to close the app to see this message. I am using the same code, the only thing I did was to update the version of the mavsdk and the mavsdk-server.
Thanks!