MapExtractorServer.java
Go to the documentation of this file.
00001 /* \file MapExtractorServer.java
00002  * \brief The local 2d map extraction service implementation
00003  *
00004  * The MapExtractorServer listens to ROS service calls in order to create 2d 
00005  * maps using the 2d map extractor tool (MapExtractor.cpp).
00006  * 
00007  * This file is part of the RoboEarth ROS package re_2dmap_extractor.
00008  * 
00009  * It was originally created for <a href="http://www.roboearth.org/">RoboEarth</a>.
00010  * The research leading to these results has received funding from the 
00011  * European Union Seventh Framework Programme FP7/2007-2013 
00012  * under grant agreement no248942 RoboEarth.
00013  *
00014  * Copyright (C) 2012 by 
00015  * <a href=" mailto:perzylo@cs.tum.edu">Alexander Perzylo</a>
00016  * Technische Universitaet Muenchen
00017  * 
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted provided that the following conditions are met:
00020  * 
00021  *    <UL>
00022  *     <LI> Redistributions of source code must retain the above copyright
00023  *       notice, this list of conditions and the following disclaimer.
00024  *     <LI> Redistributions in binary form must reproduce the above copyright
00025  *       notice, this list of conditions and the following disclaimer in the
00026  *       documentation and/or other materials provided with the distribution.
00027  *     <LI> Neither the name of Willow Garage, Inc. nor the names of its
00028  *       contributors may be used to endorse or promote products derived from
00029  *       this software without specific prior written permission.
00030  *    </UL>
00031  * 
00032  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00033  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00034  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00035  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00036  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00037  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00038  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00039  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00040  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00041  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00042  * POSSIBILITY OF SUCH DAMAGE.
00043  *
00044  * \author Alexander Perzylo
00045  * \version 1.0
00046  * \date 2012
00047  * \image html http://www.roboearth.org/sites/default/files/RoboEarth.org_logo.gif
00048  * \image latex http://www.roboearth.org/sites/default/files/RoboEarth.org_logo.gif
00049  */
00050 
00051 package roboearth.wp5.maps;
00052 
00053 import java.io.BufferedOutputStream;
00054 import java.io.BufferedReader;
00055 import java.io.File;
00056 import java.io.FileInputStream;
00057 import java.io.FileNotFoundException;
00058 import java.io.FileOutputStream;
00059 import java.io.IOException;
00060 import java.io.InputStream;
00061 import java.io.InputStreamReader;
00062 
00063 import ros.NodeHandle;
00064 import ros.Ros;
00065 import ros.RosException;
00066 import ros.ServiceServer;
00067 import ros.pkg.re_2dmap_extractor.srv.RequestLocMap;
00068 import ros.pkg.re_2dmap_extractor.srv.RequestNavMap;
00069 import ros.pkg.re_msgs.msg.RosFile;
00070 
00071 public class MapExtractorServer {
00072 
00073         protected Ros ros;
00074         protected NodeHandle n;
00075         
00076         protected static String packagePath;
00077         protected static String tmpPath;
00078         protected static String binPath;
00079         
00080         public MapExtractorServer(Ros ros, NodeHandle n) throws RosException {
00081                 
00082                 this.ros = ros;
00083                 this.n = n;
00084                 
00085                 this.n.advertiseService("/re_2dmap_extractor/request_loc_map", new RequestLocMap(), new RequestLocMapCallback());
00086                 this.n.advertiseService("/re_2dmap_extractor/request_nav_map", new RequestNavMap(), new RequestNavMapCallback());
00087                 
00088                 ros.logInfo("Waiting for service calls.");
00089                 
00090         }
00091 
00099         class RequestLocMapCallback implements ServiceServer.Callback<RequestLocMap.Request, RequestLocMap.Response> {
00100 
00101                 @Override
00102                 public RequestLocMap.Response call(RequestLocMap.Request req) {
00103 
00104                         RequestLocMap.Response res = new RequestLocMap.Response();
00105                         res.success = false;
00106 
00107                         if (writeRosFile(tmpPath, req.octoMap)) {
00108 
00109                                 ProcessBuilder pb = new ProcessBuilder("./extract2dMap",
00110                                                 "-z", ""+req.z,
00111                                                 "-o", tmpPath + req.octoMap.name,
00112                                                 "-n", tmpPath + req.targetMapName);
00113                                 
00114                                 pb = pb.directory(new File(binPath));
00115                                 
00116                                 try {
00117                                         Process p = pb.start();
00118                                         if (p.waitFor() == 0) {
00119 
00120                                                 String mapName = req.targetMapName + ".pgm";
00121                                                 String metaName = req.targetMapName + ".yaml";
00122                                                 
00123                                                 byte[] mapBytes = readFile(new File(tmpPath + mapName));
00124                                                 byte[] metaBytes = readFile(new File(tmpPath + metaName));
00125                                                 
00126                                                 if (mapBytes != null && metaBytes != null) {
00127                                                         res.locMap.data = mapBytes;
00128                                                         res.locMap.name = mapName;
00129                                                         res.locMeta.data = metaBytes;
00130                                                         res.locMeta.name = metaName;
00131                                                         res.success = true;
00132                                                 }
00133 
00134                                         }
00135                                 } catch (IOException e) {
00136                                         e.printStackTrace();
00137                                 } catch (InterruptedException e) {
00138                                         e.printStackTrace();
00139                                 }
00140                                 
00141                         } else {
00142                                 System.out.println("Couldn't write Octomap '"+req.octoMap.name
00143                                                 + "' to path '" + tmpPath + "'.");
00144                         }
00145                         
00146                         if (res.success) {
00147                                 ros.logInfo("RequestLocMap (octomap '" + req.octoMap.name + "'): Done");
00148                         } else {
00149                                 ros.logInfo("RequestLocMap (octomap '" + req.octoMap.name + "'): Failed");
00150                         }
00151 
00152                         return res;
00153 
00154                 }
00155 
00156         }
00157 
00165         class RequestNavMapCallback implements ServiceServer.Callback<RequestNavMap.Request, RequestNavMap.Response> {
00166 
00167                 @Override
00168                 public RequestNavMap.Response call(RequestNavMap.Request req) {
00169 
00170                         RequestNavMap.Response res = new RequestNavMap.Response();
00171                         res.success = false;
00172 
00173                         if (writeRosFile(tmpPath, req.octoMap)) {
00174                                 
00175                                 ProcessBuilder pb = new ProcessBuilder("./extract2dMap",
00176                                                 "-z", ""+req.minZ,
00177                                                 "-Z", ""+req.maxZ,
00178                                                 "-o", tmpPath + req.octoMap.name,
00179                                                 "-n", tmpPath + req.targetMapName);
00180                                 
00181                                 pb.directory(new File(binPath));
00182                                 
00183                                 try {
00184                                         Process p = pb.start();
00185                                         if (p.waitFor() == 0) {
00186 
00187                                                 String mapName = req.targetMapName + ".pgm";
00188                                                 String metaName = req.targetMapName + ".yaml";
00189                                                 
00190                                                 byte[] mapBytes = readFile(new File(tmpPath + mapName));
00191                                                 byte[] metaBytes = readFile(new File(tmpPath + metaName));
00192                                                 
00193                                                 if (mapBytes != null && metaBytes != null) {
00194                                                         res.navMap.data = mapBytes;
00195                                                         res.navMap.name = mapName;
00196                                                         res.navMeta.data = metaBytes;
00197                                                         res.navMeta.name = metaName;
00198                                                         res.success = true;
00199                                                 }
00200 
00201                                         }
00202                                 } catch (IOException e) {
00203                                         e.printStackTrace();
00204                                 } catch (InterruptedException e) {
00205                                         e.printStackTrace();
00206                                 }
00207                                 
00208                         } else {
00209                                 System.out.println("Couldn't write Octomap '"+req.octoMap.name
00210                                                 + "' to path '" + tmpPath + "'.");
00211                         }
00212                         
00213                         if (res.success) {
00214                                 ros.logInfo("RequestNavMap (octomap '" + req.octoMap.name + "'): Done");
00215                         } else {
00216                                 ros.logInfo("RequestNavMap (octomap '" + req.octoMap.name + "'): Failed");
00217                         }
00218 
00219                         return res;
00220 
00221                 }
00222 
00223         }
00224 
00225         public static String getLocalPackagePath(String packageName) {
00226 
00227                 String dir = null;
00228 
00229                 try {   
00230 
00231                         // try to find package using rospack
00232                         String line;
00233                         String rospack = System.getenv().get("ROS_ROOT")+"/bin/rospack";
00234                         Process get_path = new ProcessBuilder( rospack, "find", packageName).start();
00235 
00236                         try {
00237                                 BufferedReader pathreader = new BufferedReader(new InputStreamReader(get_path.getInputStream(), "UTF-8"));
00238 
00239                                 if( (line = pathreader.readLine()) != null) {
00240                                         dir = line+File.separator;
00241                                 }
00242                         } finally {
00243                                 if (get_path != null) {
00244                                         get_path.getInputStream().close();      
00245                                 }
00246                         }
00247 
00248                 } catch (IOException e) {
00249                         e.printStackTrace(System.err);
00250                 }
00251 
00252                 return dir;
00253 
00254         }
00255         
00256         public static byte[] readFile(File file) {
00257             
00258             byte[] data = null;
00259                 
00260             if (file == null) {
00261                 System.out.println("Error while trying to get file content: file is null");
00262                 return data;
00263             }
00264             
00265             long length = file.length();
00266             if (length > Integer.MAX_VALUE) {
00267                         System.out.println("  File '"+file.getName()+"' is too big! Operation canceled.");
00268             } else {
00269 
00270                 InputStream is = null;
00271                 
00272                 try {
00273 
00274                         is = new FileInputStream(file);
00275                             data = new byte[(int)length];
00276 
00277                             int offset = 0;
00278                             int numRead = 0;
00279                             while (offset < data.length
00280                                    && (numRead=is.read(data, offset, data.length-offset)) >= 0) {
00281                                 offset += numRead;
00282                             }
00283 
00284                             if (offset < data.length) {
00285                                 data = null;
00286                                 System.out.println("  Could not completely read file "+file.getName());
00287                             }
00288                         
00289                 } catch (FileNotFoundException e) {
00290                                 System.out.println("  Couldn't find file '"+ file.getName() +
00291                                                 "'! Operation canceled.");
00292                         } catch (IOException e) {
00293                                 System.out.println("  IOException occurred, while reading " +
00294                                                 "from file '"+file.getName()+"'! Operation canceled.");
00295                         } finally {
00296                         if (is != null) {
00297                                 try {
00298                                                 is.close();
00299                                         } catch (IOException e) {
00300                                         }       
00301                         }
00302                 }
00303                     
00304             }
00305             
00306             return data;
00307             
00308         }
00309         
00310         public static boolean writeRosFile(String targetPath, RosFile content) {
00311 
00312                 boolean ok = false;
00313 
00314                 if (content != null && targetPath != null && targetPath.length() > 0 
00315                                 && content.name != null && content.name.length() > 0) {
00316 
00317                         BufferedOutputStream bos = null;
00318 
00319                         if (!targetPath.endsWith(File.separator)) {
00320                                 targetPath += File.separator;
00321                         }
00322                         
00323                         try {
00324                                 FileOutputStream fos;
00325                                 fos = new FileOutputStream(new File(targetPath+content.name));
00326                                 bos = new BufferedOutputStream(fos);
00327                                 bos.write(content.data);
00328                                 bos.flush();
00329                                 ok = true;
00330                         } catch (Exception e) {
00331                                 e.printStackTrace();
00332                         } finally {
00333                                 if (bos != null) {
00334                                         try {
00335                                                 bos.close();
00336                                         } catch (Exception e) {
00337                                         }
00338                                 }
00339                         }
00340                         
00341                 }
00342 
00343                 return ok;
00344 
00345         }
00346         
00347         public static void main(String[] args) {
00348 
00349                 // Get local paths
00350                 packagePath = getLocalPackagePath("re_2dmap_extractor");
00351                 if (packagePath == null) {
00352                         System.out.println("Couldn't determine local package path.");
00353                         return;
00354                 }
00355                 tmpPath = packagePath + "tmp" + File.separator;
00356                 binPath = packagePath + "bin" + File.separator;
00357                 
00358                 // Initialize rosjava 
00359                 Ros ros = Ros.getInstance();
00360                 ros.init("re_2dmap_extractor_server");
00361 
00362                 // Create a NodeHandle
00363                 NodeHandle n = ros.createNodeHandle();
00364                 
00365                 // Start map extractor server 
00366                 try {
00367                         
00368                         new MapExtractorServer(ros, n);
00369                         
00370                 } catch (Exception e) {
00371 
00372                         ros.logFatal("Fatal error occurred. Shutting down!");   
00373                         
00374                         if (n != null) {
00375                                 n.shutdown();   
00376                         }
00377                         
00378                         e.printStackTrace();
00379                         return;
00380                         
00381                 }
00382                 
00383                 ros.spin();
00384 
00385         }
00386 
00387 }


re_2dmap_extractor
Author(s): Alexander Perzylo
autogenerated on Sun Jan 5 2014 11:28:08