Skip to content

Commit

Permalink
Added vendor installation support for Jazzy and Rolling (#87)
Browse files Browse the repository at this point in the history
Support for ROS 2 vendor packages installing Gazebo.

---------

Signed-off-by: Saurabh Kamat <[email protected]>
Co-authored-by: Jose Luis Rivero <[email protected]>
  • Loading branch information
sauk2 and j-rivero authored Oct 10, 2024
1 parent c4cd4fb commit a30dfaf
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 58 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,31 @@ jobs:
source /opt/ros/humble/setup.bash
ros2 pkg list | grep ros_gz
ign gazebo --version | grep 'version 6.*'
test_install_ros_gz_vendor:
name: 'Install Harmonic on Jazzy through vendor packages'
env:
ROS_DISTROS: 'jazzy'
runs-on: ubuntu-latest
container:
image: ubuntu:noble
steps:
- uses: actions/checkout@v4
- uses: actions/[email protected]
with:
node-version: '20.x'
- name: 'Install ROS 2 Jazzy'
uses: ros-tooling/[email protected]
with:
required-ros-distributions: ${{ env.ROS_DISTROS }}
- name: 'Install Gazebo with ros_gz'
uses: ./
with:
required-gazebo-distributions: 'harmonic'
install-ros-gz: ${{ env.ROS_DISTROS }}
- name: Test Jazzy ros_gz installation
run: |
source /opt/ros/jazzy/setup.bash
! [ $(apt list --installed gz-harmonic) ]
ros2 pkg list | grep ros_gz
gz sim --version | grep 'version 8.[0-9*].[0-9*]'
66 changes: 36 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ This workflow shows how to use binaries from [pre-release] or [nightly] Gazebo r

This workflow shows how to install ROS 2 using the GitHub action `ros-tooling/setup-ros` along with Gazebo installed using `setup-gazebo`. The `ros-gz` package can be installed by setting the input parameter `install-ros-gz` to the required ROS 2 distributions.

Starting with ROS 2 Jazzy, Gazebo is also available to be installed from ROS packages via [vendor packages]. When using `install-ros-gz` this action will check for availability of these Gazebo vendor packages and install them if available for the specified ROS 2 distribution. Only the default (recommended) Gazebo release is currently available for the ROS 2 releases using the vendor packages (i.e if ROS 2 Jazzy is used, only Gazebo Harmonic is the valid option). More information on vendor packages can be found in the [official documentation].

```yaml
jobs:
test_gazebo:
Expand Down Expand Up @@ -282,19 +284,20 @@ This workflow shows how to install ROS 2 using the GitHub action `ros-tooling/se
This workflow shows how to install Gazebo on a macOS worker using the Homebrew package manager which is installed by the action. To run, this action needs an input for `required-gazebo-distributions` parameter.

```yaml
test_gazebo:
runs-on: macos-13
steps:
- uses: actions/checkout@v4
- uses: actions/[email protected]
with:
node-version: '20.x'
- name: 'Check Gazebo installation on MacOS runner'
uses: gazebo-tooling/[email protected]
with:
required-gazebo-distributions: 'harmonic'
- name: 'Test Gazebo installation'
run: 'gz sim --versions'
jobs:
test_gazebo:
runs-on: macos-13
steps:
- uses: actions/checkout@v4
- uses: actions/[email protected]
with:
node-version: '20.x'
- name: 'Check Gazebo installation on MacOS runner'
uses: gazebo-tooling/[email protected]
with:
required-gazebo-distributions: 'harmonic'
- name: 'Test Gazebo installation'
run: 'gz sim --versions'
```

### Windows
Expand All @@ -304,23 +307,24 @@ This workflow shows how to install Gazebo on a Windows worker. The action requir
#### Setting up worker to install Gazebo on Windows

```yaml
test_gazebo:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/[email protected]
with:
node-version: '20.x'
- uses: conda-incubator/setup-miniconda@v3
- name: 'Check Gazebo installation on Windows runner'
uses: gazebo-tooling/[email protected]
with:
required-gazebo-distributions: 'harmonic'
- name: 'Test Gazebo installation'
shell: pwsh
run: |
conda activate
gz sim --versions
jobs:
test_gazebo:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/[email protected]
with:
node-version: '20.x'
- uses: conda-incubator/setup-miniconda@v3
- name: 'Check Gazebo installation on Windows runner'
uses: gazebo-tooling/[email protected]
with:
required-gazebo-distributions: 'harmonic'
- name: 'Test Gazebo installation'
shell: pwsh
run: |
conda activate
gz sim --versions
```

## License
Expand All @@ -332,3 +336,5 @@ The scripts and documentation in this project are released under the [Apache 2](
[best-effort]: https://gazebosim.org/docs/harmonic/releases#supported-platforms
[pre-release]: https://packages.osrfoundation.org/gazebo/ubuntu-prerelease/
[nightly]: https://packages.osrfoundation.org/gazebo/ubuntu-nightly/
[vendor packages]: https://gazebosim.org/docs/ionic/ros_installation/#ros-2-gazebo-vendor-packages
[official documentation]: https://gazebosim.org/docs/ionic/ros2_gz_vendor_pkgs/
29 changes: 23 additions & 6 deletions __test__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ describe("validate ROS 2 distribution test", () => {
it("test valid distro", async () => {
await expect(utils.validateROSDistro(["humble"])).toBe(true);
await expect(utils.validateROSDistro(["iron"])).toBe(true);
await expect(utils.validateROSDistro(["jazzy"])).toBe(true);
await expect(utils.validateROSDistro(["rolling"])).toBe(true);
await expect(utils.validateROSDistro(["humble", "iron"])).toBe(true);
});
it("test invalid distro", async () => {
Expand Down Expand Up @@ -177,13 +179,28 @@ describe("check for unstable repositories input", () => {
describe("generate APT package names for ros_gz", () => {
it("test ros_gz output package names list", async () => {
await expect(
utils.generateROSAptPackageNames(["humble", "iron"], ["harmonic"]),
).toEqual(["ros-humble-ros-gzharmonic", "ros-iron-ros-gzharmonic"]);
utils.generateROSGzAptPackageNames(["humble", "iron"], ["harmonic"]),
).toEqual([
"gz-harmonic",
"ros-humble-ros-gzharmonic",
"ros-iron-ros-gzharmonic",
]);
await expect(
utils.generateROSAptPackageNames(["humble"], ["fortress"]),
).toEqual(["ros-humble-ros-gz"]);
utils.generateROSGzAptPackageNames(["humble"], ["fortress"]),
).toEqual(["gz-fortress", "ros-humble-ros-gz"]);
await expect(
utils.generateROSAptPackageNames(["iron"], ["fortress", "garden"]),
).toEqual(["ros-iron-ros-gz", "ros-iron-ros-gzgarden"]);
utils.generateROSGzAptPackageNames(["iron"], ["fortress", "garden"]),
).toEqual([
"gz-fortress",
"ros-iron-ros-gz",
"gz-garden",
"ros-iron-ros-gzgarden",
]);
await expect(
utils.generateROSGzAptPackageNames(["jazzy"], ["harmonic"]),
).toEqual(["ros-jazzy-ros-gz"]);
await expect(
utils.generateROSGzAptPackageNames(["rolling"], ["harmonic"]),
).toEqual(["ros-rolling-ros-gz"]);
});
});
49 changes: 38 additions & 11 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26487,16 +26487,23 @@ function runLinux() {
// Add repo according to Ubuntu version
const ubuntuCodename = yield utils.determineDistribCodename();
yield addAptRepo(ubuntuCodename);
// Get list of Gazebo distributions
const gazeboDistros = yield utils.getRequiredGazeboDistributions();
// Check compatibility with Ubuntu version
yield utils.checkUbuntuCompatibility(gazeboDistros, ubuntuCodename);
for (const gazeboDistro of gazeboDistros) {
yield apt.runAptGetInstall([`gz-${gazeboDistro}`]);
}
// Look for ROS 2 distributions for installing ros_gz
const rosGzDistros = utils.checkForROSGz();
if (rosGzDistros.length > 0) {
const rosAptPackageNames = utils.generateROSAptPackageNames(rosGzDistros, gazeboDistros);
// Check for Gazebo vendor packages and generate appropriate package names
const rosAptPackageNames = utils.generateROSGzAptPackageNames(rosGzDistros, gazeboDistros);
yield apt.runAptGetInstall(rosAptPackageNames);
}
else {
// Install Gazebo as usual
for (const gazeboDistro of gazeboDistros) {
yield apt.runAptGetInstall([`gz-${gazeboDistro}`]);
}
}
});
}

Expand Down Expand Up @@ -26799,7 +26806,7 @@ exports.getRequiredGazeboDistributions = getRequiredGazeboDistributions;
exports.checkUbuntuCompatibility = checkUbuntuCompatibility;
exports.checkForUnstableAptRepos = checkForUnstableAptRepos;
exports.checkForROSGz = checkForROSGz;
exports.generateROSAptPackageNames = generateROSAptPackageNames;
exports.generateROSGzAptPackageNames = generateROSGzAptPackageNames;
const actions_exec = __importStar(__nccwpck_require__(1514));
const core = __importStar(__nccwpck_require__(2186));
const yaml_1 = __nccwpck_require__(4083);
Expand All @@ -26813,11 +26820,25 @@ const validROSGzDistrosList = [
rosDistro: "humble",
officialROSGzWrappers: ["fortress"],
unofficialROSGzWrappers: ["garden", "harmonic"],
vendorPackagesAvailable: false,
},
{
rosDistro: "iron",
officialROSGzWrappers: ["fortress"],
unofficialROSGzWrappers: ["garden", "harmonic"],
vendorPackagesAvailable: false,
},
{
rosDistro: "jazzy",
officialROSGzWrappers: ["harmonic"],
unofficialROSGzWrappers: [],
vendorPackagesAvailable: true,
},
{
rosDistro: "rolling",
officialROSGzWrappers: ["harmonic"],
unofficialROSGzWrappers: [],
vendorPackagesAvailable: true,
},
];
/**
Expand Down Expand Up @@ -26997,19 +27018,25 @@ function checkForROSGz() {
* Generate APT package name from ROS 2 and Gazebo distribution names
*
* @param rosGzDistrosList ROS 2 distro ros_gz packages to be installed
* @param requiredGazeboDistributionsList Installed Gazebo distributions
* @param requiredGazeboDistributionsList Gazebo distributions to be installed
* @returns string [] List of APT package names
*/
function generateROSAptPackageNames(rosGzDistrosList, requiredGazeboDistributionsList) {
const rosAptPackageNames = [];
function generateROSGzAptPackageNames(rosGzDistrosList, requiredGazeboDistributionsList) {
const rosGzAptPackageNames = [];
for (const rosDistro of rosGzDistrosList) {
const distroInfo = validROSGzDistrosList.find((distro) => distro.rosDistro === rosDistro);
for (const gazeboDistro of requiredGazeboDistributionsList) {
if (!distroInfo.vendorPackagesAvailable) {
const gzPkgName = `gz-${gazeboDistro}`;
if (rosGzAptPackageNames.indexOf(gzPkgName) < 0) {
rosGzAptPackageNames.push(gzPkgName);
}
}
if (distroInfo.officialROSGzWrappers.indexOf(gazeboDistro) > -1) {
rosAptPackageNames.push(`ros-${rosDistro}-ros-gz`);
rosGzAptPackageNames.push(`ros-${rosDistro}-ros-gz`);
}
else if (distroInfo.unofficialROSGzWrappers.indexOf(gazeboDistro) > -1) {
rosAptPackageNames.push(`ros-${rosDistro}-ros-gz${gazeboDistro}`);
rosGzAptPackageNames.push(`ros-${rosDistro}-ros-gz${gazeboDistro}`);
}
else {
throw new Error("Impossible ROS 2 and Gazebo combination requested. \
Expand All @@ -27018,7 +27045,7 @@ function generateROSAptPackageNames(rosGzDistrosList, requiredGazeboDistribution
}
}
}
return rosAptPackageNames;
return rosGzAptPackageNames;
}


Expand Down
16 changes: 11 additions & 5 deletions src/setup-gazebo-linux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,26 @@ export async function runLinux(): Promise<void> {
const ubuntuCodename = await utils.determineDistribCodename();
await addAptRepo(ubuntuCodename);

// Get list of Gazebo distributions
const gazeboDistros = await utils.getRequiredGazeboDistributions();

// Check compatibility with Ubuntu version
await utils.checkUbuntuCompatibility(gazeboDistros, ubuntuCodename);

for (const gazeboDistro of gazeboDistros) {
await apt.runAptGetInstall([`gz-${gazeboDistro}`]);
}

// Look for ROS 2 distributions for installing ros_gz
const rosGzDistros = utils.checkForROSGz();

if (rosGzDistros.length > 0) {
const rosAptPackageNames = utils.generateROSAptPackageNames(
// Check for Gazebo vendor packages and generate appropriate package names
const rosAptPackageNames = utils.generateROSGzAptPackageNames(
rosGzDistros,
gazeboDistros,
);
await apt.runAptGetInstall(rosAptPackageNames);
} else {
// Install Gazebo as usual
for (const gazeboDistro of gazeboDistros) {
await apt.runAptGetInstall([`gz-${gazeboDistro}`]);
}
}
}
33 changes: 27 additions & 6 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,31 @@ const validROSGzDistrosList: {
rosDistro: string;
officialROSGzWrappers: string[];
unofficialROSGzWrappers: string[];
vendorPackagesAvailable: boolean;
}[] = [
{
rosDistro: "humble",
officialROSGzWrappers: ["fortress"],
unofficialROSGzWrappers: ["garden", "harmonic"],
vendorPackagesAvailable: false,
},
{
rosDistro: "iron",
officialROSGzWrappers: ["fortress"],
unofficialROSGzWrappers: ["garden", "harmonic"],
vendorPackagesAvailable: false,
},
{
rosDistro: "jazzy",
officialROSGzWrappers: ["harmonic"],
unofficialROSGzWrappers: [],
vendorPackagesAvailable: true,
},
{
rosDistro: "rolling",
officialROSGzWrappers: ["harmonic"],
unofficialROSGzWrappers: [],
vendorPackagesAvailable: true,
},
];

Expand Down Expand Up @@ -232,25 +247,31 @@ export function checkForROSGz(): string[] {
* Generate APT package name from ROS 2 and Gazebo distribution names
*
* @param rosGzDistrosList ROS 2 distro ros_gz packages to be installed
* @param requiredGazeboDistributionsList Installed Gazebo distributions
* @param requiredGazeboDistributionsList Gazebo distributions to be installed
* @returns string [] List of APT package names
*/
export function generateROSAptPackageNames(
export function generateROSGzAptPackageNames(
rosGzDistrosList: string[],
requiredGazeboDistributionsList: string[],
): string[] {
const rosAptPackageNames: string[] = [];
const rosGzAptPackageNames: string[] = [];
for (const rosDistro of rosGzDistrosList) {
const distroInfo = validROSGzDistrosList.find(
(distro) => distro.rosDistro === rosDistro,
);
for (const gazeboDistro of requiredGazeboDistributionsList) {
if (!distroInfo!.vendorPackagesAvailable) {
const gzPkgName = `gz-${gazeboDistro}`;
if (rosGzAptPackageNames.indexOf(gzPkgName) < 0) {
rosGzAptPackageNames.push(gzPkgName);
}
}
if (distroInfo!.officialROSGzWrappers.indexOf(gazeboDistro) > -1) {
rosAptPackageNames.push(`ros-${rosDistro}-ros-gz`);
rosGzAptPackageNames.push(`ros-${rosDistro}-ros-gz`);
} else if (
distroInfo!.unofficialROSGzWrappers.indexOf(gazeboDistro) > -1
) {
rosAptPackageNames.push(`ros-${rosDistro}-ros-gz${gazeboDistro}`);
rosGzAptPackageNames.push(`ros-${rosDistro}-ros-gz${gazeboDistro}`);
} else {
throw new Error(
"Impossible ROS 2 and Gazebo combination requested. \
Expand All @@ -260,5 +281,5 @@ export function generateROSAptPackageNames(
}
}
}
return rosAptPackageNames;
return rosGzAptPackageNames;
}

0 comments on commit a30dfaf

Please sign in to comment.