[ros-users] Integrating ROS node subscriber with X-Plane plugin
Clayton Morrison
clayton at cs.arizona.edu
Sun Aug 1 01:26:41 UTC 2010
Hi,
Brief description: I'm attempting to integrate a simple ROS node with the X-Plane ( http://www.x-plane.com/ ) flight simulator plugin facility (in C++). I want to add to the plugin a subscriber that will listen on a topic and when a message arrives, send a command to X-Plane. Whenever I get to the point of calling ros::init() the plugin crashes (well, X-Plane crashes, which I assume is from the plugin). (I did look through the archives -- I'm obviously new here -- but couldn't find anything related to my issue addressed; apologies in advance if I just missed it!)
Some immediate hunches (but not sure how to verify/fix) and questions:
(1) xplane is a 32bit application. Could my build process (described below) be inadvertently using 64bit versions of compiled ROS libs?
(2) I am calling ros::init() in a non-main fn, so I'm using the version based on map<string,string>. I'm sending in an empty map b/c I have no params to remap. Am I doing this wrong? (source for XP_ROS_Plugin.cpp below; I did verify in an separate, non-X-Plane-related build that I can use ros::init() in this way without crashing...)
(3) Generally: how does one go about debugging a setup like this (on mac, ros inside a plugin inside another app)? How can I get more details about what is going on when ros::init() is called?
Any help/suggestions/pointers are appreciated. Details below.
Platform: Mac OS X Snow Leopard
gcc: i686-apple-darwin10-gcc-4.2.1
ROS: cturtle (I'm just using ros core for now, given known problems with other packages on the mac, such a gazebo and wx*); I installed ROS core fresh on July 26. I've been able to work through the simple roscpp for the publisher/subscriber and simple adding service and those work fine on my mac.
X-Plane version: 9.06rc2
-- free demo app that can run the plugin available here:
http://www.x-plane.com/pg_downloads.html
-- run updater 2.05 from this same page to get the latest.
Downloading the X-Plane plugin SDK: I'm using the X-Plane SDK 2.0.1:
http://www.xsquawkbox.net/xpsdk/mediawiki/Download
-- Only need the contents under SDK/CHeaders (more on this below)
ROS package setup:
I created a simple ros package that depends on roscpp and std_msgs. Under src I placed another directory called xplane_sdk/ that contains the _contents_ of the X-Plane SDK/CHeaders/ directory (i.e., the Widgets, Wrapper and XPLM directories).
At the end of this email is the CMakeLists.txt I modified for building this package.
The file src/XP_ROS_Plugin.cpp contains the code to interface with the X-Plane plugin architecture -- I also list it below. (Near the top of the file is a log fn that uses XPlane's logging facilities to add log messages to the file <X-Plane-9 root>/Log.txt after running XPlane with the plugin; messages related to the XP_ROS_Plugin.xpl plugin all begin with '>>>'.)
The BUILD, INSTALL and RUN process:
After placing the files/directories in a ros package as described above, do rosmake. All going well, the file XP_ROS_Plugin.xpl is generated under <pkg-root>/lib.
After building, put the plugin XP_ROS_Plugin.xpl in the X-Plane plugin folder:
<X-Plane-9 root>/Resources/plugins/
You can then launch X-Plane. (If running the demo or you don't have the X-Plane CD, you will get a message about X-Plane going into demo mode, this is expected and unrelated to the plugin...)
Line 82 of src/XP_ROS_Plugin.cpp is the culprit -- this is where ros::init() is called. In the listing below it is commented-out. If building the plugin in this state and installing (putting the generated .xpl in the X-Plane plugin directory), then launching X-Plane (double-click) succeeds. (To verify the plugin has loaded properly: In X-Plane, go to the Plugins -> Plugin Admin -> Plugin Information and you'll see the plugin description text for "XP_ROS_Plugin"). Also, inspecting the X-Plane Log.txt includes logged lines starting with >>>, progressing beyond tick 2.
However, uncommenting line 82, buiding, installing, and then launching X-Plane results in early X-Plane crash. The X-Plane Log.txt gets up to:
>>> XPluginStart: calling ros::init() tick 2
------------------
XP_ROS_Plugin.cpp:
------------------
#include "XPLMProcessing.h"
#include "XPLMUtilities.h"
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <stdio.h>
#include <string>
#include <sstream>
#include <map>
using namespace std;
static int t;
static float tickPeriod;
void log(char *logString)
{
stringstream ss;
ss << ">>> " << logString << " tick " << t++ << endl;
XPLMDebugString(ss.str().c_str());
}
PLUGIN_API void XPluginStop(void)
{ }
PLUGIN_API void XPluginDisable(void)
{ }
PLUGIN_API int XPluginEnable(void)
{
return 1;
}
PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFromWho,
long inMessage,
void * inParam)
{ }
void rosCallback(const std_msgs::String::ConstPtr& msg)
{
const char *constMsg = msg->data.c_str();
char *msg1 = new char[strlen(constMsg)];
strcpy(msg1, constMsg);
log(msg1);
}
XPLM_API float MyFlightLoopCallback(float inElapsedSinceLastCall,
float inElapsedTimeSinceLastFlightLoop,
int inCounter,
void * inRefcon)
{
log("ROSListenerNode Called");
return tickPeriod;
}
PLUGIN_API int XPluginStart(char * outName,
char * outSig,
char * outDesc)
{
strcpy(outName, "XP_ROS_Plugin");
strcpy(outSig, "edu.au.xprosplugin");
strcpy(outDesc, "An XPlane plugin implementing a ROS node");
t = 0;
tickPeriod = 1.0;
log("XPluginStart: defining map<string,string>");
map<string, string> m;
log("XPluginStart: defining map<string,string> DONE");
log("XPluginStart: calling ros::init()");
// ros::init(m, "XP_Plugin_Node");
log("XPluginStart: ros::init() CALLED");
XPLMRegisterFlightLoopCallback(MyFlightLoopCallback,
tickPeriod,
NULL);
return 1;
}
---------------
CMakeLists.txt:
---------------
cmake_minimum_required(VERSION 2.4.6)
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
# Set the build type. Options are:
# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage
# Debug : w/ debug symbols, w/o optimization
# Release : w/o debug symbols, w/ optimization
# RelWithDebInfo : w/ debug symbols, w/ optimization
# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries
#set(ROS_BUILD_TYPE RelWithDebInfo)
rosbuild_init()
#set the default path for built executables to the "bin" directory
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#set the default path for built libraries to the "lib" directory
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
#uncomment if you have defined messages
#rosbuild_genmsg()
#uncomment if you have defined services
#rosbuild_gensrv()
#common commands for building c++ executables and libraries
#rosbuild_add_library(${PROJECT_NAME} src/example.cpp)
#target_link_libraries(${PROJECT_NAME} another_library)
#rosbuild_add_boost_directories()
#rosbuild_link_boost(${PROJECT_NAME} thread)
#rosbuild_add_executable(example examples/example.cpp)
#target_link_libraries(example ${PROJECT_NAME})
# project(XP_ROS_Plugin)
message(">>> PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
set(XPLANE_SDK_ROOT "${PROJECT_SOURCE_DIR}/src/xplane_sdk")
message(">>> XPLANE_SDK_ROOT: ${XPLANE_SDK_ROOT}")
set(OS_COMPILE_FLAGS "-D APL -m32")
set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup")
include_directories("${XPLANE_SDK_ROOT}/Widgets")
include_directories("${XPLANE_SDK_ROOT}/XPLM")
set(CMAKE_C_FLAGS "${OS_COMPILE_FLAGS} -D XPLM200 -D XPLM=1")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
file(GLOB SRC_FILES "src/*.cpp")
message(">>> SRC_FILES: ${SRC_FILES}")
rosbuild_add_library(XP_ROS_Plugin ${SRC_FILES})
target_link_libraries(XP_ROS_Plugin ${OSX_LIBRARIES})
set_target_properties(XP_ROS_Plugin PROPERTIES PREFIX "" SUFFIX ".xpl")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osuosl.org/pipermail/ros-users/attachments/20100731/c2f5b492/attachment-0002.html>
More information about the ros-users
mailing list