SolarFramework / SolARUnityPlugin

DEPRECATED - A Unity plugin allowing to load SolAR pipelines
Apache License 2.0
6 stars 1 forks source link

Fix Android plugin for release/0.10.0 #5

Closed jim-bcom closed 2 years ago

jim-bcom commented 2 years ago

Unity plugin does not work on Android for release/0.10.0.

By debugging the native pipeline library in Android Studio, I fell upon an error located here: https://github.com/SolarFramework/Sample-FiducialMarker/blob/release/0.10.0/SolARPipeline_FiducialMarker/src/PipelineFiducialMarker.cpp#L74

This returns null:

xpcf::utils::dynamic_pointer_cast<FiducialMarker>(trackable);

In this context, xpcf::utils::dynamic_pointer_cast is actually an alias for boost::dynamic_pointer_cast.

The issue https://github.com/android/ndk/issues/519 mentions a problem with dynamic_pointer_cast. It does not seem related to boost, but the errors might be fixed by updating libc++_shared.so found in the NDK. Maybe there is a lead here (replacing boost by std in xpcf for Android and use up to date libc++_shared.so)

jim-bcom commented 2 years ago

Need to investigate suggestion by @DanAlbert in previously mentioned issue regarding keyfunctions.

https://github.com/android/ndk/issues/519#issuecomment-335978813 https://github.com/android/ndk/issues/533#issuecomment-335977747

key functions

https://developer.android.com/ndk/guides/common-problems#rttiexceptions_not_working_across_library_boundaries

Seems to match the case, since both Trackable and Trackable2D appear as OBJECT WEAK.

$ Android/Sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-readelf.exe -sW Assets/Plugins/Android/libSolARFramework.so | Android/Sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-c++filt.exe | grep typeinfo | grep "for SolAR::datastructure::Trackable"
  9155: 000000000053ecb0    16 OBJECT  WEAK   DEFAULT   17 typeinfo for SolAR::datastructure::Trackable
  9291: 0000000000462330    34 OBJECT  WEAK   DEFAULT   10 typeinfo name for SolAR::datastructure::Trackable
  9469: 0000000000462300    37 OBJECT  WEAK   DEFAULT   10 typeinfo name for SolAR::datastructure::Trackable2D
 10269: 000000000053ecc0    40 OBJECT  WEAK   DEFAULT   17 typeinfo for SolAR::datastructure::Trackable2D
 27876: 000000000053ecb0    16 OBJECT  WEAK   DEFAULT   17 typeinfo for SolAR::datastructure::Trackable
 28012: 0000000000462330    34 OBJECT  WEAK   DEFAULT   10 typeinfo name for SolAR::datastructure::Trackable
 28190: 0000000000462300    37 OBJECT  WEAK   DEFAULT   10 typeinfo name for SolAR::datastructure::Trackable2D
 28990: 000000000053ecc0    40 OBJECT  WEAK   DEFAULT   17 typeinfo for SolAR::datastructure::Trackable2D

$ Android/Sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-readelf.exe -sW Assets/Plugins/Android/libSolARFramework.so | Android/Sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-c++filt.exe | grep typeinfo | grep "for SolAR::datastructure::FiducialMarker"
  6260: 00000000004622a0    40 OBJECT  GLOBAL DEFAULT   10 typeinfo name for SolAR::datastructure::FiducialMarker
 13144: 000000000053ec40    40 OBJECT  GLOBAL DEFAULT   17 typeinfo for SolAR::datastructure::FiducialMarker
 24981: 00000000004622a0    40 OBJECT  GLOBAL DEFAULT   10 typeinfo name for SolAR::datastructure::FiducialMarker
 31865: 000000000053ec40    40 OBJECT  GLOBAL DEFAULT   17 typeinfo for SolAR::datastructure::FiducialMarker
jim-bcom commented 2 years ago

Inspired from issue 533, I changed the the destructor of Trackable and Trackable2D as follows:

Trackable.h:

-        virtual ~Trackable() = default;
+        virtual ~Trackable();

Trackable.cpp:

+Trackable::~Trackable(){}

This made their typeinfo become GLOBAL

  1896: 00000000001b7c80    40 OBJECT  GLOBAL DEFAULT   19 typeinfo for SolAR::datastructure::ImageMarker
  3810: 0000000000184b2d    37 OBJECT  GLOBAL DEFAULT   12 typeinfo name for SolAR::datastructure::ImageMarker
 11040: 0000000000184b2d    37 OBJECT  GLOBAL DEFAULT   12 typeinfo name for SolAR::datastructure::ImageMarker
 12480: 00000000001b7c80    40 OBJECT  GLOBAL DEFAULT   19 typeinfo for SolAR::datastructure::ImageMarker

I had to recompile libSolARPipelineFiducialMarker.so as well to link against this new framework version, otherwise Trackable was still appearing as WEAK in this library. Now it appears as GLOBAL.

    24: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND typeinfo for SolAR::datastructure::Trackable
  1478: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND typeinfo for SolAR::datastructure::Trackable

Now the dynamic_pointer_cast seems to work, the application is running.

To be able to run the other pipelines, I recompiled the following modules as well:

But it seems other issues remain:

jim-bcom commented 2 years ago

This footnote mentions a compiler option in LLVM that may have helped: _LIBCXXABI_FORGIVING_DYNAMIC_CAST (the name has changed since the bog post. Unfortunately, it's off by default, and would require to rebuild clang.

jim-bcom commented 2 years ago

Another issue occured once the previous step manage to fix the crash: the apps are not crashing, but they are not working, i.e. no avatar is placed on the marker for Fiducial/NaturalImage-marker pipelines, and nothing seems to happen with SLAM pipeline. The cause seems to be that the camera calibration file is missing. Indeed, it has been removed by commit https://github.com/SolarFramework/SolARUnityPlugin/commit/204080cc64afdb6d6f10ece297fe92a2c7efd25b (probably by mistake).

When the calibration file is restored this seems to work fine.

There's still one thing though, I've used a json file (which is what was specified in the Unity project pipeline manager), but the last file known in git history was a yaml file. But when using a yaml file this does not seem to work (parsing error).

Need to decide whether to use this json file or understand why the yaml file failed to load and fix it.

granger35 commented 2 years ago

We have now move to a json file for camera calibration parameters. need to be added to be able to run the demo.