It was exactly the problem I had (not respond to SIGINT) but fork()/exec() seems to work in my case. But I'll take a look at rxbag's Recorder class. Thx Gautier Le 31/08/2010 19:53, Kaijen Hsiao a écrit : > I would recommend against using fork()/exec() to run "rosbag record", > actually--I tried to do so myself not long ago, and found that the > forked process wouldn't respond to SIGINT, and so I couldn't close any > of the bagfiles being recorded. Although maybe you'll have better > luck (or maybe Tim knows of a trick to make that work--I'm certainly > no expert at using fork/exec). > > rxbag's Recorder class, on the other hand, was fairly easy to extend > for my needs. > > -Kaijen > > On Tue, Aug 31, 2010 at 3:39 PM, Tim Field wrote: >> Hi Gautier, >> One option is rxbag's Recorder class, >> i.e. https://code.ros.org/svn/ros/stacks/ros/tags/cturtle/tools/rxbag/src/rxbag/recorder.py. >> Here's some code to get you started: >> >> import roslib; roslib.load_manifest('rxbag') >> from rxbag.recorder import Recorder >> r = Recorder('altimeter.bag', topics=['/fake_alti']) >> r.start() >> r.pause() >> r.unpause() >> r.stop() >> >> If that's too slow to record your data (ROS message serialization is slow in >> Python), I'd follow Josh's suggestion and fork()/exec() a process to run >> "rosbag record". >> For Diamondback, rosbag will have a ROS API for recording and playback. >> Tim >> On Tue, Aug 31, 2010 at 12:06 PM, Gautier Dumonteil >> wrote: >>> Hi users, >>> >>> In our reseach project, we would like to be able to record bags >>> "automatically" (e.g recording when our UAV is flying). >>> So, I'm trying to write a simple node (recorder_interface) with two >>> services "start_record" and "stop_record", where "start_record" callback >>> launch the rosbag::recorder::run() in a child process using fork(). The >>> "stop_record" callback just sends the SIGINT signal to recorder PID to stop >>> recording ... but nothing happen. It seems that the ROS node forked doesn't >>> handle SIGINT signals. >>> >>> Also, when checking available nodes with "rosnode list", I've only the >>> recorder_interface node. I should have also something like >>> "record_1283279499007996727", which is the rosbag record node. >>> >>> I'm wondering if a node can launch others nodes?? >>> >>> Here, the console output and code: >>> >>> [ INFO] [1283279481.648585599]: Recorder_interface spinning: ready to >>> record. >>> [ INFO] [1283279499.006083281]: Request to record topics: test >>> [ INFO] [1283279499.007996722]: Child: pid = 10497 >>> >>> [ INFO] [1283279499.008979878]: Subscribing to /fake_alti >>> [ INFO] [1283279499.009749320]: Recording to test_2010-08-31-14-31-39.bag. >>> >>> #include >>> #include "ros/ros.h" >>> #include "recorder_interface/rec_interface.h" >>> #include "rosbag/recorder.h" >>> #include "rosbag/exceptions.h" >>> >>> bool recording; >>> int recorder_exit_code; >>> pid_t rosbag_pid; >>> >>> void rosbagRecord (rosbag::RecorderOptions opts) >>> { >>> char ** argv = NULL; >>> int argc=0; >>> ros::init(argc, argv, "record", ros::init_options::AnonymousName); >>> >>> // **** Run the recorder >>> rosbag::Recorder recorder(opts); >>> recorder_exit_code = recorder.run(); >>> ROS_INFO("recorder_exit_code: %d\n",recorder_exit_code); >>> } >>> >>> bool startRec(recorder_interface::rec_interface::Request&req, >>> recorder_interface::rec_interface::Response&res) >>> { >>> if(!recording) >>> { >>> recording=true; >>> ROS_INFO("Request to record topics: %s", req.topics.c_str ()); >>> >>> // **** Fill rosbag options >>> rosbag::RecorderOptions opts; >>> opts.record_all = false; >>> opts.quiet = true; >>> opts.prefix = req.prefix; >>> opts.append_date = true; >>> opts.topics.push_back("/fake_alti"); >>> >>> rosbag_pid = fork(); >>> if(rosbag_pid == -1) >>> { >>> // **** ouch, fork() failed >>> perror("fork"); >>> exit(-1); >>> } >>> else if(rosbag_pid == 0) >>> { >>> // **** child >>> ROS_INFO("Child: pid = %d\n", (int)getpid()); >>> rosbagRecord(opts); >>> exit(-1); >>> } >>> } >>> else >>> { >>> ROS_WARN("Already recording!"); >>> } >>> return true; >>> } >>> >>> >>> bool stopRec(recorder_interface::rec_interface::Request&req, >>> recorder_interface::rec_interface::Response&res) >>> { >>> if(recording) >>> { >>> int err = kill(rosbag_pid, SIGINT); >>> ROS_INFO("err = %d\n",err); >>> if(err==0) >>> { >>> res.ans=recorder_exit_code; >>> recording=false; >>> } >>> } >>> else >>> { >>> ROS_WARN("Not recording!"); >>> } >>> return true; >>> } >>> >>> int main(int argc, char **argv) >>> { >>> recording=false; >>> >>> ros::init(argc, argv, "recorder_interface"); >>> ros::NodeHandle n; >>> >>> ros::ServiceServer serviceStart,serviceStop; >>> serviceStart = n.advertiseService("start_record", startRec); >>> serviceStop = n.advertiseService("stop_record", stopRec); >>> ROS_INFO("Recorder_interface spinning: ready to record."); >>> ros::spin(); >>> return 0; >>> } >>> >>> >>> >>> _______________________________________________ >>> ros-users mailing list >>> ros-users@code.ros.org >>> https://code.ros.org/mailman/listinfo/ros-users >>> >> >> _______________________________________________ >> ros-users mailing list >> ros-users@code.ros.org >> https://code.ros.org/mailman/listinfo/ros-users >> >> > _______________________________________________ > ros-users mailing list > ros-users@code.ros.org > https://code.ros.org/mailman/listinfo/ros-users