ros nodehandle在JNI回调中
我需要在Spring Boot应用程序中接收ROS消息。为此,我设置了一些JNI课程。它有效,但是一旦我创建了一个节点,我就无法再用一个普通的sigint关闭该应用程序,就需要一个sigkill。
这是代码:
cppbridge.java
public class CppBridge {
static {
System.load(new File("backend/src/main/cpp/libcppbridge.so").getAbsolutePath());
}
public native void start();
}
cppbridge.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_ifremer_rospipe_CppBridge */
#ifndef _Included_org_ifremer_rospipe_CppBridge
#define _Included_org_ifremer_rospipe_CppBridge
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_ifremer_rospipe_CppBridge
* Method: start
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_ifremer_rospipe_CppBridge_start
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
cppbridge.cpp
JNIEXPORT void JNICALL Java_org_ifremer_rospipe_CppBridge_start(JNIEnv* env, jobject obj)
{
// Init ROS:
int argc = 0;
ros::init(argc, nullptr, "ifr_mimosa_bridge");
// Create the NodeHandle, this causes SIGINT to hang:
ros::NodeHandle nh("~");
}
rospipe.java,
@Component
public class RosPipe {
private final CppBridge mCppBridge = new CppBridge();
@PostConstruct()
public void onStart() {
mCppBridge.start();
}
}
为什么创建NodeHandle会阻止Cppbridge实例的破坏?
I need to receive ROS messages inside a Spring Boot application. For that I have setup some JNI classes. It works but as soon as I create a NodeHandle, I can no longer close the app with a normal SIGINT, it requires a SIGKILL.
Here's the code:
CppBridge.java
public class CppBridge {
static {
System.load(new File("backend/src/main/cpp/libcppbridge.so").getAbsolutePath());
}
public native void start();
}
CppBridge.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_ifremer_rospipe_CppBridge */
#ifndef _Included_org_ifremer_rospipe_CppBridge
#define _Included_org_ifremer_rospipe_CppBridge
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_ifremer_rospipe_CppBridge
* Method: start
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_ifremer_rospipe_CppBridge_start
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
CppBridge.cpp
JNIEXPORT void JNICALL Java_org_ifremer_rospipe_CppBridge_start(JNIEnv* env, jobject obj)
{
// Init ROS:
int argc = 0;
ros::init(argc, nullptr, "ifr_mimosa_bridge");
// Create the NodeHandle, this causes SIGINT to hang:
ros::NodeHandle nh("~");
}
RosPipe.java
@Component
public class RosPipe {
private final CppBridge mCppBridge = new CppBridge();
@PostConstruct()
public void onStart() {
mCppBridge.start();
}
}
Why does the creation of a NodeHandle blocks the destruction of the CppBridge instance?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,内部ROS拦截了Sigint信号,因此Spring不再接收它。因此,按下CTRL-C时,C ++过程在Java保持活力时优雅地终止。
为了修复它,我覆盖了ROS Sigint处理,以便在ROS终止后通知Spring:
在Java侧:
Turned out that internally ROS intercepts the SIGINT signal, and thus Spring no longer receives it. So when pressing CTRL-C the C++ process terminates gracefully while the Java stays alive.
To fix it I overrode ROS SIGINT handling in order to notify Spring after ROS is terminated:
In the Java side: