insert_pioneer_arm.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 
00003 #***********************************************************
00004 #* Software License Agreement (BSD License)
00005 #*
00006 #* Copyright (c) 2011, A.M.Howard, S.Williams
00007 #* All rights reserved.
00008 #* 
00009 #* Redistribution and use in source and binary forms, with or without
00010 #* modification, are permitted provided that the following conditions are met:
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 copyright
00014 #*       notice, this list of conditions and the following disclaimer in the
00015 #*       documentation and/or other materials provided with the distribution.
00016 #*     * Neither the name of the <organization> nor the
00017 #*       names of its contributors may be used to endorse or promote products
00018 #*       derived from this software without specific prior written permission.
00019 #*  
00020 #* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00021 #* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00022 #* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00023 #* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00024 #* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00025 #* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026 #* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00027 #* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028 #* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 #* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 #***********************************************************
00031 
00032 ##\author Stephen Williams
00033 ##\brief WRITE THIS
00034 
00035 import roslib
00036 roslib.load_manifest('pioneer_arm_description')
00037 import rospy
00038 
00039 import sys
00040 import argparse
00041 import subprocess
00042 import tempfile
00043 from xml.dom.minidom import parse, parseString
00044 
00045 
00046 def xacro_function_evaluator(file, xacro=None, robot=None, pairs=None):
00047     
00048     # Generate an XML stub for xacro.py to execute
00049     xacro_xml  = '<?xml version="1.0" ?>\n'
00050     xacro_xml += '<robot '
00051     # insert robot name if provided
00052     if robot:
00053         xacro_xml += 'name="%s" ' % robot
00054     xacro_xml += 'xmlns:xacro="http://ros.org/wiki/xacro">\n'
00055     xacro_xml += '\t<include filename="%s" />\n' % file
00056     
00057     # Insert the xacro call, if provided
00058     if xacro:
00059         xacro_xml += '\t<xacro:%s ' % xacro
00060         # Loop through name-value pairs and insert as arguments
00061         for pair in pairs:
00062             xacro_xml += '%s="%s" ' % (pair[0], pair[1])
00063         xacro_xml += '/>\n'
00064     
00065     # Close root node
00066     xacro_xml += '</robot>\n'
00067 
00068     # Save the XML stub to a temporary file
00069     temp = tempfile.NamedTemporaryFile(mode='w+', suffix='.xml')
00070     temp.write(xacro_xml)
00071     temp.seek(0)
00072     
00073     # Execute xacro.py on temporary file
00074     p = subprocess.Popen(["rosrun", "xacro", "xacro.py", temp.name], stdout=subprocess.PIPE)#, stderr="/dev/null")
00075     output = p.communicate()[0]
00076     
00077     # Close the temporary file. This will cause a deletion
00078     temp.close()
00079     
00080     # write model XML back to the parameter server
00081     return output
00082 
00083 
00084 def model_inserter(xml1, xml2):
00085 
00086     # Parse xml1 string as xml
00087     try:
00088         model1_dom = parseString(xml1)
00089     except:
00090         raise Exception("Unable to parse model1")
00091     
00092     # Parse xml2 string as xml
00093     try:
00094         model2_dom = parseString(xml2)
00095     except:
00096         raise Exception("Unable to parse model2")
00097     
00098     # Insert model2 into the end of model1
00099     node = model2_dom.documentElement.firstChild
00100     while node:
00101         if node.nodeType == node.ELEMENT_NODE:
00102             model1_dom.documentElement.appendChild(node.cloneNode(deep=True))
00103         node = node.nextSibling
00104     
00105     # Output the modified model1 DOM
00106     return model1_dom.toprettyxml(indent="  ")
00107 
00108 
00109 if __name__ == "__main__":
00110     
00111     # Parse command line arguments
00112     parser = argparse.ArgumentParser(description='Insert Pioneer Arm model into an existing URDF/robot_description. The output will be streamed to stdout.')
00113     parser.add_argument('-f', '--file', required=True, help='xml/xacro file descriping the parent model')
00114     parser.add_argument('-l', '--link', required=True, help='link name in the parent model to attach the Pioneer Arm')
00115     parser.add_argument('-x', '--x', type=float, default=0.0, help='X-offset from link origin')
00116     parser.add_argument('-y', '--y', type=float, default=0.0, help='Y-offset from link origin')
00117     parser.add_argument('-z', '--z', type=float, default=0.0, help='Z-offset from link origin')
00118     parser.add_argument('-R', '--roll', type=float, default=0.0, help='Roll-offset from link origin')
00119     parser.add_argument('-P', '--pitch', type=float, default=0.0, help='Pitch-offset from link origin')
00120     parser.add_argument('-Y', '--yaw', type=float, default=0.0, help='Yaw-offset from link origin')
00121     
00122     args, unknown_args = parser.parse_known_args()
00123     
00124     # Load parent model
00125     parent_xml = xacro_function_evaluator(file=args.file, robot='robot')
00126     
00127     # Create Pioneer Arm urdf from supplied parameters
00128     arm_xml = xacro_function_evaluator(file='$(find pioneer_arm_description)/urdf/pioneer_arm.urdf.xacro', xacro='pioneer_arm_urdf', pairs=[['parent', args.link], ['robot_description', 'robot_description'], ['x', args.x], ['y', args.y], ['z', args.z], ['roll', args.roll], ['pitch', args.pitch], ['yaw', args.yaw]])
00129 
00130     # Insert Pioneer Arm into Parent Model
00131     robot_xml = model_inserter(parent_xml, arm_xml)
00132     
00133     # Output robot model    
00134     sys.stdout.write(robot_xml)
00135     


pioneer_arm_description
Author(s): Stephen Williams
autogenerated on Wed Nov 27 2013 12:12:23