So you have a couple options.
1
EDIT: I didn't see tryan answer while I was writing, they explain this first option... Use <xacro:arg/>
tags to allow passing in arguments via xacro. This Answer explains that process.
2
You can also load a yaml file as a dictionary that can be accessed within a xacro. This allows you to put all your variables in a single file, and load it as a single argument to the xacro (as compared to having an argument for every variable you want to set). Then to change configurations, just load a different yaml.
For an example of this method, consider a package with the following structure:
test_pkg
|-- launch
| |-- description.launch
|-- params
| |-- parameters.yaml
|-- xacro
|-- test_model.xacro
description.launch
<?xml version="1.0"?>
<launch>
<!-- Build the robot description for a xacro and parameter(yaml) file, serve it up for consumption -->
<!-- Note: params_path will be passed into the xacro and accessible as a dictionary for procedural generation of model features -->
<arg name="model_path" default="$(find test_pkg)/xacro/test_model.xacro"/>
<arg name="params_path" default="$(find test_pkg)/params/parameters.yaml"/>
<!-- Load the robot_description on the ROS param server using xacro to generate the model description -->
<param name="robot_description" command="$(find xacro)/xacro $(arg model_path) params_path:=$(arg params_path) " />
<!-- Start nodes for serving the model description and joint states-->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
</launch>
parameters.yaml
name: 'center'
position:
x: 0
y: 0
z: 5
tire:
mass: 1.0
width: 0.5
radius: 0.75
test_model.xacro
<?xml version="1.0"?>
<robot name="test_model" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- This is the top level xacro for generating a model from a parameter file -->
<!-- Arg: params_path - The path to the parameter (yaml) file -->
<xacro:property name="PI" value="3.1415926535897931" />
<!--
Kinda stupid way to import external parameters, open to better options.
The xacro:arg "params_path" exposes the arg to launch file.
The xacro:property "params_path" is required to get the evaluated
symbol into xacro before "load_yaml"
The xacro:proterty "mp" (which stands for "model parameters") gets the
dictionary from "params_path" and is accessed using ${mp['key_name']}
which will evaluate to the key value
The xacro:arg and xacro:property "params_path" shares a name but does
not seem to clobber eachother.
They are not required to have the same name, it was just convenient
-->
<!-- Need argument to get from launch file -->
<xacro:arg name="params_path" default="../params/parameters.yaml"/>
<!-- Need seperate property for xacro inorder processing -->
<xacro:property name="params_path" value="$(arg params_path)"/>
<!-- Read in the yaml dict as mp (short for model parameters) -->
<xacro:property name="mp" value="${load_yaml(params_path)}"/>
<!-- Required Base Link -->
<link name="base_link"/>
<!-- A body to act as a stand -->
<link name="body_link ...
(more)