I was launching the techman robot on ros using the demo.launch. The first time when I launched it on rviz I could able to see the camera under by topic and I can see the video output. So I edited the moveit setup and added some poses to the robot. so when I launched again. now I could not find a camera under by topic. And I am very new to ros.
and the following was my demo.launch file
<launch>
<!-- specify the planning pipeline -->
<arg name="pipeline" default="ompl" />
<!-- By default, we do not start a database (it can be large) -->
<arg name="db" default="false" />
<!-- Allow user to specify database location -->
<arg name="db_path" default="$(find new_techman)/default_warehouse_mongo_db" />
<!-- By default, we are not in debug mode -->
<arg name="debug" default="false" />
<!-- By default, we will load or override the robot_description -->
<arg name="load_robot_description" default="true"/>
<!-- Set execution mode for fake execution controllers -->
<arg name="execution_type" default="interpolate" />
<!--
By default, hide joint_state_publisher's GUI
MoveIt!'s "demo" mode replaces the real robot driver with the joint_state_publisher.
The latter one maintains and publishes the current joint configuration of the simulated robot.
It also provides a GUI to move the simulated robot around "manually".
This corresponds to moving around the real robot without the use of MoveIt.
-->
<arg name="use_gui" default="false" />
<arg name="use_rviz" default="true" />
<!-- If needed, broadcast static tf for robot root -->
<!-- We do not have a robot connected, so publish fake joint states -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" unless="$(arg use_gui)">
<rosparam param="source_list">[move_group/fake_controller_joint_states]</rosparam>
</node>
<node name="joint_state_publisher" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" if="$(arg use_gui)">
<rosparam param="source_list">[move_group/fake_controller_joint_states]</rosparam>
</node>
<!-- Given the published joint states, publish tf for the robot links -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="true" output="screen" />
<!-- Run the main MoveIt! executable without trajectory execution (we do not have controllers configured by default) -->
<include file="$(find new_techman)/launch/move_group.launch">
<arg name="allow_trajectory_execution" value="true"/>
<arg name="fake_execution" value="true"/>
<arg name="execution_type" value="$(arg execution_type)"/>
<arg name="info" value="true"/>
<arg name="debug" value="$(arg debug)"/>
<arg name="pipeline" value="$(arg pipeline)"/>
<arg name="load_robot_description" value="$(arg load_robot_description)"/>
</include>
<!-- Run Rviz and load the default config to see the state of the move_group node -->
<include file="$(find new_techman)/launch/moveit_rviz.launch" if="$(arg use_rviz)">
<arg name="rviz_config" value="$(find new_techman)/launch/moveit.rviz"/>
<arg name="debug" value="$(arg debug)"/>
</include>
<!-- If database loading was enabled, start mongodb as well -->
<include file="$(find new_techman)/launch/default_warehouse_db.launch" if="$(arg db)">
<arg name="moveit_warehouse_database_path" value="$(arg db_path)"/>
</include>
</launch>
and when I launch the gazebo.launch that was created by the moveit setup assistant I can see the camera from the gazebo platform into rviz
Have you launched Gazebo before or after launching your demo.launch? Try doing it the other way around!
It seems that Gazebo provides your camera-simulation. Rviz itself doesn't create the camera view, it just listens to a topic where a different engine (normally a robot, in your case the robot-simulation of Gazebo) publishes the images and then shows these images to you.
Rviz and Gazebo sometimes have trouble communicating based on which is started first.
Related
created a launch file where my robot should open on the gazebo world and when in try to run the launch file using roslaunch i get the following error
redefining global symbol: pi
when processing file: /home/akash/project/src/techman_robot_ros-master/tm_grasp_description/urdf/tm700.urdf.xacro
included from: /home/akash/project/src/techman_robot_ros-master/tm_grasp_description/urdf/tm700_robot.urdf.xacro
xacro.py is deprecated; please use xacro instead
started roslaunch server http://akash:37109/
still i can see my gazebo world but cannot see the robot imported.
and this was the launch file
<launch>
<arg name="eih" default="false" />
<arg name="limited" default="false"/>
<group unless="$(arg eih)">
<param unless="$(arg limited)" name="robot_description" command="$(find xacro)/xacro.py '$(find tm_grasp_description)/urdf/tm700_robot.urdf.xacro'" />
<param if="$(arg limited)" name="robot_description" command="$(find xacro)/xacro.py '$(find tm_grasp_description)/urdf/tm700_robot_joint_limited.urdf.xacro'" />
</group>
<group if="$(arg eih)">
<param unless="$(arg limited)" name="robot_description" command="$(find xacro)/xacro.py '$(find tm_grasp_description)/urdf/tm700_robot_eih.urdf.xacro'" />
<param if="$(arg limited)" name="robot_description" command="$(find xacro)/xacro.py '$(find tm_grasp_description)/urdf/tm700_robot_joint_limited_eih.urdf.xacro'" />
</group>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="true"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
<arg name="world_name"
value="$(find tm700_moveit_config)/launch/gg.world"/>
</include>
</launch>
Since ROS Jade Xacro internally uses functions and constants from Python math module such as pi when converting a Xacro to a URDF robot description. It seems like tm700.urdf.xacro (and several other Xacro-files in the package) for some reason has pi defined in line 8
<property name="pi" value="3.14159265" />
which is in conflict with the existing definition from the math module. Therefore the generation of your robot description fails. Delete all the definitions of pi from the Xacro-files, then it should work.
I have written a custom launch file for my custom gazebo world. When I roslaunch the .launch file, only an empty world opens. Could you tell me where am I wrong?
This is my launch file
<launch>
<arg name="x_pos" default="-1.0"/>
<arg name="y_pos" default="-1.0"/>
<arg name="z_pos" default="-1.0"/>
<!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
<arg name="model" value="burger" doc="model type [burger, waffle, waffle_pi]"/>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="~/catkin_ws/src/cse340a3_gazebo/worlds/cse340a3.world"/>
<!-- more default parameters can be changed here -->
</include>
<!-- <param name="robot_description" value="~/catkin_ws/src/cse340a3_description/urdf/turtlebot3_burger.urdf.xacro" /> -->
<!-- <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-urdf -model turtlebot3 -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description" /> -->
</launch>
This works for some reason (I put in the full path)
<launch>
<arg name="x_pos" default="-1.0"/>
<arg name="y_pos" default="-1.0"/>
<arg name="z_pos" default="-1.0"/>
<!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
<arg name="model" value="burger" doc="model type [burger, waffle, waffle_pi]"/>
<include file="/home/vishwad/catkin_ws/src/cse340a3_gazebo/launch/empty_world.launch">
<arg name="world_name" value="/home/vishwad/catkin_ws/src/cse340a3_gazebo/worlds/cse340a3.world"/>
<!-- more default parameters can be changed here -->
</include>
<!-- <param name="robot_description" value="~/catkin_ws/src/cse340a3_description/urdf/turtlebot3_burger.urdf.xacro" /> -->
<!-- <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-urdf -model turtlebot3 -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description" /> -->
</launch>
I'm using ros kinetic and Ubuntu 16.04
I'm trying to do run this project but not running inside a Docker container.
After, I had done
user#user-HP-Pavilion-15-Notebook-PC:~/gym-gazebo/gym_gazebo/envs/installation/catkin_ws$ catkin_make
user#user-HP-Pavilion-15-Notebook-PC:~/gym-gazebo/gym_gazebo/envs/installation$ bash setup_kinetic.bash
user#user-HP-Pavilion-15-Notebook-PC:~/gym-gazebo/gym_gazebo/envs/installation$ bash turtlebot_setup.bash
user#user-HP-Pavilion-15-Notebook-PC:~/gym-gazebo/examples/turtlebot$ python circuit2_turtlebot_lidar_qlearn.py
Then, it comes out the following error:
... logging to /home/user/.ros/log/3ac6e572-28a3-11e8-9aba-142d27dccbb5/roslaunch-user-HP-Pavilion-15-Notebook-PC-6853.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://user-HP-Pavilion-15-Notebook-PC:37855/
ros_comm version 1.12.12
SUMMARY
========
PARAMETERS
* /rosdistro: kinetic
* /rosversion: 1.12.12
NODES
auto-starting new master
process[master]: started with pid [6864]
ROS_MASTER_URI=http://user-HP-Pavilion-15-Notebook-PC:11311/
setting /run_id to 3ac6e572-28a3-11e8-9aba-142d27dccbb5
process[rosout-1]: started with pid [6884]
started core service [/rosout]
Roscore launched!
Gazebo launched!
... logging to /home/user/.ros/log/3ac6e572-28a3-11e8-9aba-142d27dccbb5/roslaunch-user-HP-Pavilion-15-Notebook-PC-6908.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
while processing /home/user/gym-gazebo/gym_gazebo/envs/installation/catkin_ws/src/turtlebot_simulator/turtlebot_gazebo/launch/includes/kobuki.launch.xml:
Invalid <param> tag: Cannot load command parameter [robot_description]: command [/opt/ros/kinetic/lib/xacro/xacro --inorder '/home/user/gym-gazebo/gym_gazebo/envs/installation/catkin_ws/src/turtlebot/turtlebot_description/robots/kobuki_hexagons_asus_xtion_pro.urdf.xacro'] returned with code [2].
Param xml is <param command="$(arg urdf_file)" name="robot_description"/>
The traceback for the exception was written to the log file
And the kobuki.launch.xml :
<launch>
<arg name="base" />
<arg name="stacks" />
<arg name="3d_sensor" />
<arg name="urdf_file" default="$(find xacro)/xacro --inorder '$(find turtlebot_description)/robots/$(arg base)_$(arg stacks)_$(arg 3d_sensor).urdf.xacro'" />
<param name="robot_description" command="$(arg urdf_file)" />
<!-- Gazebo model spawner -->
<node name="spawn_turtlebot_model" pkg="gazebo_ros" type="spawn_model" args="$(optenv ROBOT_INITIAL_POSE) -unpause -urdf -param robot_description -model mobile_base" />
<!-- Velocity muxer -->
<node pkg="nodelet" type="nodelet" name="mobile_base_nodelet_manager" args="manager" />
<node pkg="nodelet" type="nodelet" name="cmd_vel_mux" args="load yocs_cmd_vel_mux/CmdVelMuxNodelet mobile_base_nodelet_manager">
<param name="yaml_cfg_file" value="$(find turtlebot_bringup)/param/mux.yaml" />
<remap from="cmd_vel_mux/output" to="mobile_base/commands/velocity" />
</node>
<!-- Bumper/cliff to pointcloud (not working, as it needs sensors/core messages) -->
<include file="$(find turtlebot_bringup)/launch/includes/kobuki/bumper2pc.launch.xml" />
</launch>
This is what I get after run xacro --inorder /home/user/gym-gazebo/gym_gazebo/envs/installation/catkin_ws/src/turtlebot/turtlebot_description/robots/kobuki_hexagons_asus_xtion_pro.urdf.xacro
option --inorder not recognized
Usage: xacro.py [-o <output>] <input>
xacro.py --deps Prints dependencies
xacro.py --includes Only evalutes includes
I'm still new with ROS. Did I miss something?
The Error Your Getting From Xacro Is Actually From A --inorder tag Which Is Mostly Used In ROS Indigo(To My best of knowledge) And I Don't Think U Need It In ROS Kinetic (But I'm Not Sure Cause I'm Still On Indigo Myself) I Suggest U Try It Without The --inorder Argument And If U ran Into Problems Try Replacing it With -i As Said In The xacro Changelog In Their Github
source /opt/ros/kinetic/setup.bash
The above command solved the issue for me.
The error says cannot load command parameter [robot_description] from
/opt/ros/kinetic/lib/xacro/xacro --inorder '/home/user/gym-gazebo/gym_gazebo/envs/installation/catkin_ws/src/turtlebot/turtlebot_description/robots/kobuki_hexagons_asus_xtion_pro.urdf.xacro'
The problem you're seeing is because of the single quote characters in the command line of the xacro file. Line 6 is where param name is given as robot description, and it isnt getting loaded as urdf path hasn't been read properly in the previous line because of the single quotes. In order to load the file remove the single quotes in line 5.
Change line 5 which is
<arg name="urdf_file" default="$(find xacro)/xacro --inorder '$(find turtlebot_description)/robots/$(arg base)_$(arg stacks)_$(arg 3d_sensor).urdf.xacro'" />
to the following
<arg name="urdf_file" default="$(find xacro)/xacro --inorder $(find turtlebot_description)/robots/$(arg base)_$(arg stacks)_$(arg 3d_sensor).urdf.xacro" />
The xml file should look like
<launch>
<arg name="base" />
<arg name="stacks" />
<arg name="3d_sensor" />
<arg name="urdf_file" default="$(find xacro)/xacro --inorder $(find turtlebot_description)/robots/$(arg base)_$(arg stacks)_$(arg 3d_sensor).urdf.xacro" />
<param name="robot_description" command="$(arg urdf_file)" />
<!-- Gazebo model spawner -->
<node name="spawn_turtlebot_model" pkg="gazebo_ros" type="spawn_model" args="$(optenv ROBOT_INITIAL_POSE) -unpause -urdf -param robot_description -model mobile_base" />
<!-- Velocity muxer -->
<node pkg="nodelet" type="nodelet" name="mobile_base_nodelet_manager" args="manager" />
<node pkg="nodelet" type="nodelet" name="cmd_vel_mux" args="load yocs_cmd_vel_mux/CmdVelMuxNodelet mobile_base_nodelet_manager">
<param name="yaml_cfg_file" value="$(find turtlebot_bringup)/param/mux.yaml" />
<remap from="cmd_vel_mux/output" to="mobile_base/commands/velocity" />
</node>
<!-- Bumper/cliff to pointcloud (not working, as it needs sensors/core messages) -->
<include file="$(find turtlebot_bringup)/launch/includes/kobuki/bumper2pc.launch.xml" />
</launch>
I'm trying to pass values from the launch file to the xacro model, so I can, for example, launch two robots in a single world but using different topic names or material colors. Is there a way to do this?
I've tried this unsuccessfully: https://answers.ros.org/question/38956/pass-parameters-to-xacro-in-launch-file/
It gives an error: xxx.launch requires the 'ns' arg to be set.
I also see this here: http://wiki.ros.org/roslaunch/XML/arg But that only shows how to send parameters from one launch file to another.
Here is my launch file:
<launch>
<!-- these are the arguments you can pass this launch file, for example paused:=true -->
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
<arg name="ctopic" default="/stupid/test" />
<!-- Load the URDF into the ROS Parameter Server -->
<param name="robot_description"
command="$(find xacro)/xacro.py '$(find mybot_description)/urdf/mybot.xacro' ctopic:=$(arg ns) "/>
<!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find mybot_gazebo)/worlds/mybot.world"/>
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>
<!-- Run a python script to the send a service call to gazebo_ros to spawn a URDF robot -->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model mybot -param robot_description"/>
<!-- Run RVIZ
<node name="$(anon rviz)" pkg="rviz" type="rviz" args="$(find mybot_gazebo)/mybot.rviz" output="screen"/>-->
<!-- ros_control mybot launch file -->
<include file="$(find mybot_control)/launch/mybot_control.launch" />
</launch>
I've tried this in my xacro file:
$(arg ctopic)
and
<xacro:property name="ctopic" value="$(arg ctopic)" />
Thanks
Trying to make a multilingual installer - the process is working in general, but seems to be failing for localised files that are to be installed.
Each of the localised installers works fine as a standalone and installs the localised files like the eula.pdf.
I'm hoping that I'm just missing a flag on the transform generation step (or maybe using the wrong tool?)
Process being to start by having a bunch of installers 1 for each language.
To build each installer we are 'lighting' using -b "folder" and -loc "folder" option to specify each language which includes some alternate file content such as the licence.pdf.
The files to be localised have a common source name
<File Id='License.pdf' Name='eula.pdf' Source='License(EULA).pdf' KeyPath='yes'/>
<WixVariable Id="WixUILicenseRtf" Value="License.rtf" />
Folders for example being
en-US/License(EULA).pdf
en-US/License.rtf
en-US/Product.wxl
fr-FR/License(EULA).pdf
fr-FR/License.rtf
fr-FR/Product.wxl
There are also some files such as binary.dll and binary.exe which are not localised and are the same for all msi - don't expect to see them in MST.
Following the next step in the process is creating an MST diff between a base language (english) and each of the other languages. Using Windows\v7.1\Bin\MsiTran.exe from the Window SDK
The MST seem a bit small for the change in content.
Merging all the MST files into a single installer using the Windows\v7.1\Samples\sysmgmt\msi\scripts\wisubstg.vbs
Installing in a language other than english shows the whole installer UI including rtf version of the licence as being localised, but the eula.pdf on disk is always the base english.
Using the Ant-dotnet tasks to run the build (in case it makes a difference)
The msi build task
<wix mode="light" target="${outlocation}\${lang.folder}\my.msi" wixHome="${wixhome}">
<lightArg line="-b "${location}""/> <!-- provide the location of the signable binaries -->
<lightArg line="-b "${msiwixsource}\Localisation\${lang.folder}""/> <!-- provide the location of the localisation -->
<lightArg line="-sice:ICE57"/>
<lightArg line="-cultures:${lang.culture}"/>
<lightArg line="-loc "${msiwixsource}\Localisation\${lang.folder}\Product.wxl""/>
<lightArg line="-ext "${wixhome}\WixUtilExtension.dll""/>
<lightArg line="-ext "${wixhome}\WixUIExtension.dll""/>
<lightArg line="-ext "${wixhome}\WixFirewallExtension.dll""/>
<lightArg line="-ext "${wixhome}\WixNetFxExtension.dll""/>
<sources dir="${msiwixobjects}">
<include name="*.wixobj"/>
</sources>
<moresources dir="${msiwixsource}\Localisation\${lang.folder}">
<include name="*"/>
</moresources>
<moresources dir="${location}">
<include name="binary.dll,binary.exe"/>
</moresources>
</wix>
The transform task
<exec executable="${windowsSDKBin}">
<arg value="-g"/>
<arg value="${outlocation}\en-US\my.msi"/>
<arg value="${outlocation}\${lang.folder}\my.msi"/>
<arg value="${outlocation}\${lang.folder}\my.mst"/>
</exec>
The repack task
<exec executable="cscript">
<arg value="${windowsSDKMsi}"/>
<arg value="${outlocation}\my.msi"/>
<arg value="${outlocation}\${lang.folder}\my.mst"/>
<arg value="${lang.id}"/>
</exec>
Product/#Language="!(loc.Lang)" specified in Product.wxl
for English base we listed all 1033,1028,1029,1031,1036,1040,1041,1043,1045,1046,2052,3082 for other languages just the specific such as 1036 for fr-FR
Ok, so after a couple of days of searching I found an article that describes the issue.
How To Localize the Setup GUI and Deliver Localized Files Using a MST.
The issue being that MST doesn't include '_Streams' table elements which is where the CAB files are stored.
You could go several ways from that -
1) make multiple file & component entries for the different languages with conditional inclusion based on language or culture
This means changing your wxs if you want to change which languages are supported.
<Component Directory="INSTALLDIR" Id='EULADoc' Guid='***'>
<Condition><![CDATA[(ProductLanguage = "1033")]]></Condition>
<File Id='License.pdf' Name='!(loc.EULA)' Source='en-US\License(EULA).pdf' KeyPath='yes'/>
</Component>
<Component Directory="INSTALLDIR" Id='EULADoc' Guid='***'>
<Condition><![CDATA[(ProductLanguage = "1046")]]></Condition>
<File Id='License.pdf' Name='!(loc.EULA)' Source='pt-BR\License(EULA).pdf' KeyPath='yes'/>
</Component>
... add a new block each time you add a language, changes to files have to be duplicated for every block.
Which in turn means recompiling instead of just relinking the wxl. You still need to repack the mst files.
2) manually adjust the localised MSI
As per the How To Localize the Setup GUI and Deliver Localized Files Using a MST.
3) automated split the localised items into a seperate CAB with a localised name
Rather than recompile this is then relinking and extra process for managing the CAB files.
Extra process to -
* extract the CAB file(s) along with generating the mst,
* then when merging the mst also add the cab files.
Add an extra media which has a localised name - I'm using the lang id as it is convenient
<Media Id="2" Cabinet="localised_!(loc.LANG).cab" EmbedCab="yes" />
Change the localised files/components to come from the new media
<Component Directory="INSTALLDIR" Id='EULADoc' Guid='***' DiskId='2'>
<File Id='License.pdf' Name='!(loc.EULA)' Source='License(EULA).pdf' KeyPath='yes'/>
</Component>
When generating the transforms using MSITran.exe also export the localised CAB files using MsiDb.Exe
When merging the transforms into the base MSI using WiSubStg.vbs also add the CAB files to the _Streams using WiStram.vbs
I've gone with option 3
I hope somebody else finds this useful.
Note:
I don't write alot of ANT so feel free to offer suggestions
we build an unsigned for testing and signed version for release so need to adjust the input/output locations to find binaries and msi.
and the ant build looks something like the following.
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="buildjars"/>
<taskdef name="for" classname="net.sf.antcontrib.logic.ForTask" classpathref="buildjars"/>
<taskdef name="wix" classname="org.apache.ant.dotnet.wix.WixTask" classpathref="buildjars"/>
<property name="wixhome" value="C:\Program Files (x86)\Windows Installer XML v3.5\bin"/>
<property name="binarieslocation" value="build"/>
<property name="msiwixsource" value="install"/>
<property name="msiwixobjects" value="${msiwixsource}\obj\x64\Release"/>
<!-- <dirname property="windowsSDK" file="C:\Program Files\Microsoft SDKs\Windows\v7.1\"/> Ant doesn't like path segments with . -->
<property name="windowsSDKBin" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\MsiTran.exe"/>
<property name="windowsSDKCab" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\MsiDb.Exe"/>
<property name="windowsSDKMsiStorage" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiSubStg.vbs"/>
<property name="windowsSDKMsiStream" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiStream.vbs"/>
<property name="windowsSDKMsiLanguages" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiLangId.vbs"/>
<property name="cultureBase" value="en-US:en-US:1033"/>
<property name="cultures" value="pt-BR:pt-BR:1046,cs-CZ:en-US:1029"/>
<target name="installer">
<echo>Building ${culture} msi using binaries in "${location}"...</echo>
<propertyregex property="lang.folder" input="${culture}" regexp="(.*):(.*):(.*)" select="\1"/>
<propertyregex property="lang.culture" input="${culture}" regexp="(.*):(.*):(.*)" select="\2"/>
<wix mode="light" target="${outlocation}\${lang.folder}\my.msi" wixHome="${wixhome}">
<lightArg line="-b "${location}""/> <!-- provide the location of the signable binaries -->
<lightArg line="-b "${msiwixsource}\Localisation\${lang.folder}""/> <!-- provide the location of the localisation -->
<lightArg line="-sice:ICE57"/>
<lightArg line="-cultures:${lang.culture}"/>
<lightArg line="-loc "${msiwixsource}\Localisation\${lang.folder}\Product.wxl""/>
<lightArg line="-ext "${wixhome}\WixUtilExtension.dll""/>
<lightArg line="-ext "${wixhome}\WixUIExtension.dll""/>
<sources dir="${msiwixobjects}">
<include name="*.wixobj"/>
</sources>
<moresources dir="${msiwixsource}\Localisation\${lang.folder}">
<include name="*"/>
</moresources>
<moresources dir="${location}">
<include name="binary.dll,binary.exe"/>
</moresources>
</wix>
</target>
<target name="checkTransform" depends="installer">
<uptodate property="transform.notRequired" targetfile="${outlocation}\${culture}\my.mst" >
<srcfiles dir= "${outlocation}\en-US\" includes="my.msi"/>
<srcfiles dir= "${outlocation}\${lang.culture}\" includes="my.msi"/>
</uptodate>
</target>
<target name="transform" depends="checkTransform" unless="transform.notRequired">
<echo>Building ${culture} mst ...</echo>
<propertyregex property="lang.folder" input="${culture}" regexp="(.*):(.*):(.*)" select="\1"/>
<propertyregex property="lang.id" input="${culture}" regexp="(.*):(.*):(.*)" select="\3"/>
<!-- Generate the mst 'diff' file - this does not include exporting the language specific cab file to match -->
<exec executable="${windowsSDKBin}">
<arg value="-g"/>
<arg value="${outlocation}\en-US\my.msi"/>
<arg value="${outlocation}\${lang.folder}\my.msi"/>
<arg value="${outlocation}\${lang.folder}\my.mst"/>
</exec>
<!-- Exporting the language specific cab file to match -->
<delete file="localised_${lang.id}.cab" />
<delete file="${outlocation}\${lang.folder}\localised_${lang.id}.cab" />
<exec executable="${windowsSDKCab}">
<arg value="-d"/>
<arg value="${outlocation}\${lang.folder}\my.msi"/>
<arg value="-x"/>
<arg value="localised_${lang.id}.cab"/>
</exec>
<move file="localised_${lang.id}.cab" tofile="${outlocation}\${lang.folder}\localised_${lang.id}.cab"/>
</target>
<!-- Target to build MSIs using unsigned binaries -->
<target name="MSIs">
<!-- we always need english as it is the base multilingual -->
<antcall target="installer">
<param name="culture" value="${cultureBase}" />
<param name="location" value="${location}" />
<param name="outlocation" value="${outlocation}" />
</antcall>
<!-- build the different cultures and make transforms
parallel="true" sometimes fails-->
<for list="${cultures}" param="culture" >
<sequential>
<antcall target="transform">
<param name="culture" value="#{culture}" />
<param name="location" value="${location}" />
<param name="outlocation" value="${outlocation}" />
</antcall>
</sequential>
</for>
</target>
<!-- depends="transform" -->
<target name="transformRepack" >
<echo>Packing ${culture} mst into multilingual installer...</echo>
<propertyregex property="lang.folder" input="${culture}" regexp="(.*):(.*):(.*)" select="\1"/>
<propertyregex property="lang.id" input="${culture}" regexp="(.*):(.*):(.*)" select="\3"/>
<exec executable="cscript">
<arg value="${windowsSDKMsiStream}"/>
<arg value="${outlocation}\my.msi"/>
<arg value="${outlocation}\${lang.folder}\localised_${lang.id}.cab"/>
<arg value="localised_${lang.id}.cab"/>
</exec>
<exec executable="cscript">
<arg value="${windowsSDKMsiStorage}"/>
<arg value="${outlocation}\my.msi"/>
<arg value="${outlocation}\${lang.folder}\my.mst"/>
<arg value="${lang.id}"/>
</exec>
</target>
<target name="MSIMulti" depends="MSIs">
<echo>Making multilingual installer...</echo>
<copy file="${outlocation}\en-US\my.msi" todir="${outlocation}"/>
<for list="${cultures}" param="culture">
<sequential>
<antcall target="transformRepack">
<param name="culture" value="#{culture}" />
<param name="location" value="${location}" />
<param name="outlocation" value="${outlocation}" />
</antcall>
</sequential>
</for>
<!-- report what was packed -->
<propertyregex property="lang.ids" input="${cultures}" regexp="([^:,]*):([^:]*):([^,]*)" replace="\3" global="true" defaultvalue="failed"/>
<echo/>
<echo>Multilingual installer should include transform language ids </echo>
<echo>${lang.ids}</echo>
<echo>Multilingual installer reports transform language ids...</echo>
<exec executable="cscript">
<arg value="${windowsSDKMsiStorage}"/>
<arg value="${outlocation}\my.msi"/>
</exec>
<exec executable="cscript">
<arg value="${windowsSDKMsiLanguages}"/>
<arg value="${outlocation}\my.msi"/>
<arg value="Package"/>
<arg value="1033,${lang.ids}"/>
</exec>
</target>
<target name="UnsignedMSIMulti" >
<antcall target="MSIMulti">
<param name="location" value="${binarieslocation}" />
<param name="outlocation" value="${binarieslocation}" />
</antcall>
</target>