Log in or register to post comments

Call a java function from onUpdate callback

April 25, 2013 - 2:21am #1

Hi. 

I have modified the FrameMarkers sample application to fit my purposes and I have few questions for you. 

I want to detect markers and to return informations on those markers to a java function. 
I didn't want to display the camera on the screen so I've modified the application to use UpdateCallback. 

Instead using the onDraw callback to call the native methode renderFrame I have registered UpdateCallback 

JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_FrameMarkers_FrameMarkers_onQCARInitializedNative(JNIEnv *, jobject)
{
    QCAR::registerCallback(&updateCallback);
}

I call the onQCARInitializedNative function when I initialize my application. 

I understand that each time a marker is detected from the camera, the onUpdate function from the updateCallback class is called.

In onUpdate function I want to get the id of the markers detected, their positions, etc... I am building an array of string (one string for each marker) and I want to use those infos in a java method.

How can I do that ? 

I know how to send the informations from a C++ JNI function but the onUpdate function is not called by a java method so I have to find a way to send the infos somehow...

Thanks for your help.

Call a java function from onUpdate callback

April 26, 2013 - 2:24am #6

Hi, I cannot give exact instructions here, as this is very much about application logic,

however, what i would suggest is to try to use synchronization and multi-threading mechanisms that Java offers,

i.e. try to syncrhonize on the Java side rather than on the native C++ side.

That would be much easier.

Call a java function from onUpdate callback

April 25, 2013 - 8:03am #5

So I have more questions to ask :D

I have changed the behaviour of the app. Instead of calling a java function from the onUpdate method I want to :

-> Execute onUpdate each time the state is modified

-> Store the # of the marker I detect (and their x, y position on screen)

-> Every x seconds I want to call a getData function from java. 

-> And display the result. 

To give your a better view of the situation, there is some code snippets. 

The onUpdate method

class ImageTargets_UpdateCallback : public QCAR::UpdateCallback
{
    virtual void QCAR_onUpdate(QCAR::State& state)
    {
        int size = state.getNumTrackableResults();

        data.clear();
        jstring stringobj;
        std::stringstream ss;
        // Did we find any trackables this frame?
        for(int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++)
        {
            // Get the trackable:
            const QCAR::TrackableResult* trackableResult = state.getTrackableResult(tIdx);
            QCAR::Matrix44F modelViewMatrix =
                QCAR::Tool::convertPose2GLMatrix(trackableResult->getPose());

            // Check the type of the trackable:
            assert(trackableResult->getType() == QCAR::TrackableResult::MARKER_RESULT);
            const QCAR::MarkerResult* markerResult = static_cast<
                                        const QCAR::MarkerResult*>(trackableResult);
            const QCAR::Marker& marker = markerResult->getTrackable();

            const float* mat = &modelViewMatrix.data[0];
            ss <<  marker.getMarkerId() << ";" << mat[3*4+1] << ";" << mat[3*4]  << ";"<< mat[3*4+2];

            data.push_back(ss.str());
            //LOG(ss.str().c_str());
            ss.str("");
            ss.clear();
        }
    }
};

 

The getData function :

 

JNIEXPORT jobjectArray JNICALL
Java_com_qualcomm_QCARSamples_FrameMarkers_FrameMarkers_getData(JNIEnv *env, jobject obj)
{
    jobjectArray arrayString;
    arrayString = env->NewObjectArray(data.size(), env->FindClass("java/lang/String"), env->NewStringUTF(""));
    if (arrayString == NULL) {
        return NULL; /* out of memory error thrown */
    }
    jstring stringobj;

    //DECOMMENTER TOUT CI DESSOUS
    std::vector<std::string>::iterator it;
    int i = 0;
    for ( it = data.begin() ; it != data.end(); ++it)
    {
    	stringobj = env->NewStringUTF(it->c_str());
    	env->SetObjectArrayElement(arrayString, i, stringobj);
    	++i;
    }
    return arrayString;
}

A call to a Timer to execute getMarkersData()

Timer timer = new Timer();
 timer.schedule(new getMarkersData(), 1000);

 

The declaration of the native function getData. I cast the Object[] into a String[] to display it in log.

 

public native Object[] getData();

 
 
Do I have to worry about a concurrent access to the data std::vector<std::string> in onUpdate and getData in my C++ file. If yes, how can I avoid it ? 
I tried including <mutex> but ndk-build show me this error :  fatal error: mutex: No such file or directory
I guess I would have to use a flag when "compiling" with ndk-build but which one ?
 
What can go wrong here ? If I don't try to call the timer and just log results from onUpdate everything is fine... 
Thanks for your answer. 
 

Call a java function from onUpdate callback

April 25, 2013 - 4:23am #4

you're welcome.

Call a java function from onUpdate callback

April 25, 2013 - 4:19am #3

 

Hi AlessandroB. 

Thank you for the explanations. I avoided implementing a tedious solution thanks to you. I'll try some things and post a message if I find a solution. 

Call a java function from onUpdate callback

April 25, 2013 - 3:34am #2

Hi, one note:

the updateCallback is called for every update of the State (i.e. for every new frame essentially), not just when the marker is detected.

Then, you may want to check this article which explains something similar to what you am for:

https://developer.vuforia.com/resources/dev-guide/open-web-site-and-display-toast-target-detection

 

Log in or register to post comments