pcl_assembler_client.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2008, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 #include <cstdio>
00036 #include <ros/ros.h>
00037 #include<ros/time.h>
00038 
00039 // Services
00040 #include "laser_assembler/AssembleScans2.h"
00041 
00042 // Messages
00043 #include "sensor_msgs/PointCloud2.h"
00044 #include"dynamixel_msgs/JointState.h"
00045 #include"std_msgs/Time.h"
00046 
00047 /* This is a modified periodic_snapshotter.cpp file that acts both as a timer and subscriber, depending on the value of the
00048 assembled_cloud_mode parameter.  It defaults to subscriber.  The node calls a service from the point_cloud2_assembler node
00049 from the laser_assembler package to create the compiled point cloud and then publishes the result.
00050 Timer:
00051 As a timer, the node performs its function every 5 seconds.  To use this function, the assembled_cloud_mode parameter must
00052 be set to time.
00053 Subscriber:
00054 As a subscriber, the node subscribes to start and end times published while tilting the motor and sends those as necessary
00055 to the compilation service to put all of the point clouds together.  One cloud is published for each complete sweep
00056 (i.e. -90 -> +90 -> -90).  This is the default setting of the node.*/
00057 
00058 using namespace laser_assembler;
00059 
00060 //global variables
00061 ros::Time start;
00062 ros::Time end;
00063 ros::Time init;
00064 int go = 0;
00065 std::string assembled_cloud_mode;
00066 double scan_time;
00067 
00068 //call back for start time, saves in global variable
00069 void startTime(const std_msgs::Time &msg) {
00070     start = msg.data;
00071 }
00072 
00073 //callback for end time, saves in global variable and updates go to start compilation
00074 void endTime(const std_msgs::Time &msg) {
00075     end = msg.data;
00076     go = 1;
00077 }
00078 
00079 //compilation class created by combine_clouds with modifications to remove timer and work with motor times
00080 class PeriodicSnapshotter {
00081 
00082     public:
00083 
00084     PeriodicSnapshotter() {
00085         // Create a publisher for the clouds that we assemble
00086         pub_ = n_.advertise<sensor_msgs::PointCloud2> ("assembled_cloud", 1);
00087 
00088         // Create the service client for calling the assembler
00089         client_ = n_.serviceClient<AssembleScans2>("assemble_scans2");
00090 
00091         // Start the timer that will trigger the processing loop (timerCallback)
00092         timer_ = n_.createTimer(ros::Duration(scan_time), &PeriodicSnapshotter::timerCallback, this);
00093 
00094         // Need to track if we've called the timerCallback at least once
00095         first_time_ = true;
00096     }
00097 
00098     void compile() {
00099         // Populate our service request based on motor times
00100         AssembleScans2 srv;
00101         srv.request.begin = start;
00102         srv.request.end   = end;
00103 
00104         // Make the service call
00105         if (client_.call(srv)) {
00106             //ROS_INFO_STREAM("Published Cloud") ;
00107             pub_.publish(srv.response.cloud);
00108         }
00109         else {
00110             //ROS_ERROR("Error making service call\n") ;
00111         } 
00112     }
00113 
00114     void timerCallback(const ros::TimerEvent& e) {
00115     // We don't want to build a cloud the first callback, since we we
00116     //   don't have a start and end time yet
00117         if (first_time_) {
00118             first_time_ = false;
00119 
00120         // Populate our service request based on our timer callback times
00121         AssembleScans2 srv;
00122         srv.request.begin = init;
00123         srv.request.end   = e.current_real;
00124 
00125         // Make the service call
00126         if (client_.call(srv)) {
00127             //ROS_INFO("Published Cloud");
00128             pub_.publish(srv.response.cloud);
00129         }
00130 
00131         else {
00132             //ROS_ERROR("Error making service call\n") ;
00133         }
00134 
00135             return;
00136         }
00137 
00138         // Populate our service request based on our timer callback times
00139         AssembleScans2 srv;
00140         srv.request.begin = e.last_real;
00141         srv.request.end   = e.current_real;
00142 
00143         // Make the service call
00144         if (client_.call(srv)) {
00145             //ROS_INFO("Published Cloud") ;
00146             pub_.publish(srv.response.cloud);
00147         }  
00148 
00149         else {
00150             //ROS_ERROR("Error making service call\n") ;
00151         }
00152 
00153         //ROS_ERROR_STREAM(scan_time);
00154     }
00155 
00156     private:
00157     ros::NodeHandle n_;
00158     ros::Publisher pub_;
00159     ros::ServiceClient client_;
00160     ros::Timer timer_;
00161     bool first_time_;
00162 } ;
00163 
00164 //main
00165 int main(int argc, char **argv)
00166 {
00167     //initialize and wait for necessary services, etc.
00168     ros::init(argc, argv, "Cloud_Compiler");
00169     ros::NodeHandle n;
00170     //ROS_INFO("Waiting for [build_cloud] to be advertised");
00171     
00172     //parameter for timer vs. subscriber and length of timer
00173     n.param<std::string>("assembled_cloud_mode", assembled_cloud_mode, "subscriber");
00174     n.param<double>("scan_time", scan_time, 5);
00175 
00176     //Wait for build cloud service to init
00177     ros::service::waitForService("build_cloud");
00178     //ROS_INFO_STREAM("Found build_cloud! Starting the Cloud Compiler");
00179 
00180     //SUBSCRIBER intialization
00181     if (assembled_cloud_mode == "subscriber")
00182     {
00183         //Wait for dynamixel servo to init by waiting for /state topic
00184         ros::topic::waitForMessage<dynamixel_msgs::JointState>("/tilt_controller/state", ros::Duration(20));   
00185         
00186         //subscribes to start and end time published by tilting motor
00187         ros::Subscriber sub_1=n.subscribe("/time/start_time", 1, &startTime);
00188         ros::Subscriber sub_2=n.subscribe("/time/end_time", 1, &endTime);
00189     }
00190 
00191     PeriodicSnapshotter snapshotter;
00192     init = ros::Time::now();
00193     
00194     //SUBSCRIBER MAIN LOOP
00195     if (assembled_cloud_mode == "subscriber")
00196     {
00197         while(ros::ok())
00198         {
00199             //when an end time comes in (which only occurs after start time is updated) run the compiler
00200             if(go==1)
00201             {
00202                 snapshotter.compile();
00203                 go = 0;
00204             }
00205 
00206             //wait for messages when not compiling
00207             else
00208             {
00209                 ros::spinOnce();
00210             }
00211   
00212         //pause to save computing power
00213         ros::Duration(0.01).sleep();
00214         }
00215     }
00216 
00217     //TIMER main loop
00218     else if (assembled_cloud_mode == "time")
00219     {
00220         //wait for timer to begin service call
00221         ros::spin();
00222     }
00223 
00224 return 0;
00225 
00226 }


spin_hokuyo
Author(s):
autogenerated on Sat Jun 8 2019 20:41:35