#ifdef JAVA #include "java_functions.h" #include "cmake_java_config.h" //#include "user_realtime.h" #include // version of the JDK #define JNI_VERSION JNI_VERSION_1_6 // path to the jar file containing mbsyspad bynary code //#define JAR_PATH ROBOTRAN_SOURCE_DIR"/mbsyspad/MBsysPad.jar" #define START_VIEWPOINT 0 ///< default initial viewpoint /*! \brief instantiate a java virtual machine so as to access to the 3D animation facilities of MBSysPad * * \return JNI environment */ JNIEnv* create_vm() { int res; JavaVM* jvm; JNIEnv* env; JavaVMInitArgs args; JavaVMOption options[2]; // the following parameter should be adapted depending on the version of the JDK args.version = JNI_VERSION; // number of argument to pass to the jvm args.nOptions = 2; // path to the jar file containing mbsyspad bynary code options[0].optionString = "-Djava.class.path="JAR_PATH; // path to the folder containing additional libraries, in particular the java3D native file (libj3dcore-ogl.so for linux) options[1].optionString = "-Djava.library.path="J3D_PATH; args.options = options; args.ignoreUnrecognized = JNI_FALSE; res = JNI_CreateJavaVM(&jvm, (void **)&env, &args); if (res < 0) { switch ( res ) { case -1: fprintf(stderr, "/* unknown error */\n"); break; case -2: fprintf(stderr, "/* thread detached from the VM */\n"); break; case -3: fprintf(stderr, "/* JNI version error */\n"); break; case -4: fprintf(stderr, "/* not enough memory */\n"); break; case -5: fprintf(stderr, "/* VM already created */\n"); break; case -6: fprintf(stderr, "/* invalid arguments */\n"); break; default: fprintf(stderr, "Can't create Java VM\n"); } exit(1); } return env; } /*! \brief initialize the JNI structure * * \param[in] nb_q number of joints in the .mbs file * \param[in] q_vec vector of size nb_q with the initial values for q * \param[in] mbs_file path and name of the .mbs file used for visualization * \return JNI structure */ JNI_struct* init_jni(int nb_q, double *q_vec, char *mbs_file, int start_viewpoint) { JNI_struct *jni_struct; // - - - - - - - - - - - - - - - - - // declaration for 3D view with JNI jclass animFrameClass, PadModelClass, MbsModelJ3DClass; jmethodID constructor; jmethodID loadMethod, setLocMethod; jmethodID getModelMethod, getMbs3DMethod, setVpMethod; jobject model, model3D; jstring mbsFilename; jdoubleArray doubleArrayArg; JNIEnv* env; jmethodID updateJointMethod; jobject obj; // - - - - - - - - - - - - - - - - - - - - - - - // initialise jni variable for 3D visualisation env = create_vm(); animFrameClass = (*env)->FindClass(env, "be/robotran/test/LiveSimAnimFrame"); // get the reference to the constructor of this class constructor = (*env)->GetMethodID(env, animFrameClass, "", "()V"); // get the reference to the load method which load the *.mbs file loadMethod = (*env)->GetMethodID(env, animFrameClass, "load", "(Ljava/lang/String;)V"); // get the reference to the updateJoints method which update the 3D view during simulation updateJointMethod = (*env)->GetMethodID(env, animFrameClass, "updateJoints", "([D)V"); // get the reference to the setLocation method setLocMethod = (*env)->GetMethodID(env, animFrameClass, "setLocation", "(II)V"); // create a jni string containing the path to the *.mbs file to load mbsFilename = (*env)->NewStringUTF(env, mbs_file); // create an instance of the 3D view obj = (*env)->NewObject(env, animFrameClass, constructor); // load the mbsfilename (*env)->CallObjectMethod(env, obj, loadMethod, mbsFilename); // Viewpoint // get the reference to the class PadModelClass = (*env)->FindClass(env, "be/robotran/mbsyspad/PadModel"); MbsModelJ3DClass = (*env)->FindClass(env, "be/robotran/mbs3Dviewer/j3Dviewer/MbsModelJ3D"); // get the reference to the methods getModelMethod = (*env)->GetMethodID(env, animFrameClass, "getModel", "()Lbe/robotran/mbsyspad/PadModel;"); getMbs3DMethod = (*env)->GetMethodID(env, PadModelClass, "getMbs3D", "()Lbe/robotran/mbs3Dviewer/viewerInterface/MbsModel3D;"); setVpMethod = (*env)->GetMethodID(env, MbsModelJ3DClass, "setViewpoint", "(I)V"); model = (*env)->CallObjectMethod(env, obj, getModelMethod); model3D = (*env)->CallObjectMethod(env, model, getMbs3DMethod); (*env)->CallObjectMethod(env, model3D, setVpMethod, -1); // move the frame (*env)->CallObjectMethod(env, obj, setLocMethod, 100,100); // instantiate a jni array of double doubleArrayArg = (*env)->NewDoubleArray(env, nb_q); // copy the current values of q_vec to the jni array (*env)->SetDoubleArrayRegion(env, doubleArrayArg, 0 , nb_q, q_vec); // adapt the viewpoint (*env)->CallObjectMethod(env, model3D, setVpMethod, start_viewpoint); // update the 3D view (*env)->CallObjectMethod(env, obj, updateJointMethod, doubleArrayArg); // JNI structure jni_struct = (JNI_struct*) malloc(sizeof(JNI_struct)); jni_struct->env = env; jni_struct->updateJointMethod = updateJointMethod; jni_struct->obj = obj; jni_struct->setVpMethod = setVpMethod; jni_struct->model3D = model3D; return jni_struct; } /*! \brief Release memory * * \param[out] jni_struct JNI structure to release */ void free_jni(JNI_struct *jni_struct) { free(jni_struct); } /*! \brief update the Java visualization * * \param[in,out] realtime real-time structure */ void update_java(Simu_realtime *realtime) { Realtime_java *java; MbsData* mbs_data; java = realtime->ext->java; mbs_data = realtime->ext->mbs_data; mbs_data->fct.user.user_realtime_visu(mbs_data, java->nb_q, java->cur_q); if (java->visu_past_flag) { java->visu_past_flag = 0; java->last_past_q_flag = 1; update_jni(java->jni_struct, java, java->nb_q, java->past_q); } else if (java->change_viewpoint) { if (java->last_past_q_flag) { update_jni(java->jni_struct, java, java->nb_q, java->past_q); } else { update_jni(java->jni_struct, java, java->nb_q, java->cur_q); } } else { java->last_past_q_flag = 0; update_jni(java->jni_struct, java, java->nb_q, java->cur_q); } } /*! \brief update the 3D view with JNI * * \param[in] jni_struct JNI structure * \param[in] java Java real-time structure * \param[in] nb_q number of joints to update for the visualization * \param[in] q_vec vector of size nb_q with the current values to plot */ void update_jni(JNI_struct *jni_struct, Realtime_java *java, int nb_q, double *q_vec) { // variables declarationb jdoubleArray doubleArrayArg; JNIEnv* env; env = jni_struct->env; // instantiate a jni array of double doubleArrayArg = (*env)->NewDoubleArray(env, nb_q); // copy the current values of q_vec to the jni array (*env)->SetDoubleArrayRegion(env, doubleArrayArg, 0 , nb_q, q_vec); // adapt the viewpoint if (java->change_viewpoint) { java->change_viewpoint = 0; java->cur_viewpoint++; if (java->cur_viewpoint >= java->nb_viewpoints) { java->cur_viewpoint = START_VIEWPOINT; } (*env)->CallObjectMethod(env, jni_struct->model3D, jni_struct->setVpMethod, java->cur_viewpoint); } // update the 3D view (*env)->CallObjectMethod(env, jni_struct->obj, jni_struct->updateJointMethod, doubleArrayArg); } #endif