I believe there is an API that allows you to start and stop directly, which would probably be a cleaner approach. I pinged Tim who should be able to help you out. 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 > >