diff --git a/citadel/comparison.md b/citadel/comparison.md index fa507f6df5..f2cfa840a2 100644 --- a/citadel/comparison.md +++ b/citadel/comparison.md @@ -14,6 +14,7 @@ Sensor | Gazebo-classic | Ignition Gazebo -- | -- | -- Air pressure | ✕ | ✓ Altimeter | ✓ | ✓ +Bounding Box camera | ✕ | ✕ (available from Fortress) Camera | ✓ | ✓ Contact sensor | ✓ | ✓ Depth camera | ✓ | ✓ @@ -26,6 +27,7 @@ Magnetometer | ✓ | ✓ Multi-camera | ✓ | ✕ Use individual cameras with same update rate Ray | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/26) RFID sensor and tag | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/27) +Segmentation camera | ✕ | ✕ (available from Fortress) Sonar | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/19) Thermal camera | ✕ | ✓ Wide-angle camera | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/24) @@ -111,6 +113,7 @@ VehiclePlugin | ✓ | WheelSlipPlugin | ✓ | ✓ WheelTrackedVehiclePlugin | ✓ | ✓ ([partially via DiffDrivePlugin](https://github.com/ignitionrobotics/ign-gazebo/blob/44951e3ddfd238f24182d4d80b1376f0d426bd43/examples/worlds/track_drive.sdf#L2141)) KineticEnergyMonitor | ✕ | ✓ +Buoyancy engine | ✓ | ✕ (available from Fortress) ### World plugins @@ -208,7 +211,7 @@ Copy / paste | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issu Building editor | ✓ | Model editor | ✓ | [Issues](https://github.com/ignitionrobotics/ign-gazebo/issues?q=is%3Aissue+is%3Aopen+label%3Aeditor) FPS view control | ✓ | -Orthographic projection | ✓ | ✕ (available from Fortress) +Orthographic projection | ✓ | ✕ (available from Fortress) Undo / redo | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/104) Save world | ✓ | ✓ Save GUI configuration | ✓ | ✓ @@ -267,8 +270,8 @@ transport bridge instead of plugins, contained in the Supported versions: -* ROS 1 Melodic -* ROS 2 Dashing +* ROS 1 Noetic +* ROS 2 Foxy ## Platforms @@ -298,3 +301,4 @@ Ellipsoid and capsule primitives | ✕ | ✕ (available from Edifice) Hydrodynamics | ✕ | ✕ (available from Edifice) Ocean currents | ✕ | ✕ (available from Edifice) Test fixture | ✓ | [✓](https://ignitionrobotics.org/api/gazebo/3.9/test_fixture.html) +Spherical coordinates | ✓ | ✕ (available from Fortress) diff --git a/dome/comparison.md b/dome/comparison.md index 3f498589fb..e5ed897be8 100644 --- a/dome/comparison.md +++ b/dome/comparison.md @@ -14,6 +14,7 @@ Sensor | Gazebo-classic | Ignition Gazebo -- | -- | -- Air pressure | ✕ | ✓ Altimeter | ✓ | ✓ +Bounding Box camera | ✕ | ✕ (available from Fortress) Camera | ✓ | ✓ Contact sensor | ✓ | ✓ Depth camera | ✓ | ✓ @@ -26,6 +27,7 @@ Magnetometer | ✓ | ✓ Multi-camera | ✓ | ✕ Use individual cameras with same update rate Ray | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/26) RFID sensor and tag | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/27) +Segmentation camera | ✕ | ✕ (available from Fortress) Sonar | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/19) Thermal camera | ✕ | ✓ Wide-angle camera | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/24) @@ -52,7 +54,7 @@ Nested models | ✓ | Partial support, fully available from Edifice Populations | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/240) Actors | ✓ | ✓ Markers | ✓ | ✓ -Heightmaps | ✓ | ✕ (available from Edifice with Ogre 1) +Heightmaps | ✓ | ✕ (Ogre 1 from Edifice, Ogre 2 from Fortress) DEM (Digital Elevation Models) | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/235) Polylines | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/186) World plugins | ✓ | ✓ Now called System plugin @@ -111,6 +113,7 @@ VehiclePlugin | ✓ | WheelSlipPlugin | ✓ | ✓ WheelTrackedVehiclePlugin | ✓ | ✓ ([partially via DiffDrivePlugin](https://github.com/ignitionrobotics/ign-gazebo/blob/44951e3ddfd238f24182d4d80b1376f0d426bd43/examples/worlds/track_drive.sdf#L2141)) KineticEnergyMonitor | ✕ | ✓ +Buoyancy engine | ✓ | ✕ (available from Fortress) ### World plugins @@ -208,7 +211,7 @@ Copy / paste | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issu Building editor | ✓ | Model editor | ✓ | [Issues](https://github.com/ignitionrobotics/ign-gazebo/issues?q=is%3Aissue+is%3Aopen+label%3Aeditor) FPS view control | ✓ | -Orthographic projection | ✓ | ✕ (available from Fortress) +Orthographic projection | ✓ | ✕ (available from Fortress) Undo / redo | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/104) Save world | ✓ | ✓ Save GUI configuration | ✓ | ✓ @@ -267,8 +270,8 @@ transport bridge instead of plugins, contained in the Supported versions: -* ROS 1 Melodic -* ROS 2 Dashing +* ROS 1 Melodic / Noetic +* ROS 2 Foxy ## Platforms @@ -298,3 +301,4 @@ Ellipsoid and capsule primitives | ✕ | ✕ (available from Edifice) Hydrodynamics | ✕ | ✕ (available from Edifice) Ocean currents | ✕ | ✕ (available from Edifice) Test fixture | ✓ | [✓](https://ignitionrobotics.org/api/gazebo/4.9/test_fixture.html) +Spherical coordinates | ✓ | ✕ (available from Fortress) diff --git a/edifice/comparison.md b/edifice/comparison.md index e7a48476a4..354293237e 100644 --- a/edifice/comparison.md +++ b/edifice/comparison.md @@ -14,6 +14,7 @@ Sensor | Gazebo-classic | Ignition Gazebo -- | -- | -- Air pressure | ✕ | ✓ Altimeter | ✓ | ✓ +Bounding Box camera | ✕ | ✕ (available from Fortress) Camera | ✓ | ✓ Contact sensor | ✓ | ✓ Depth camera | ✓ | ✓ @@ -26,6 +27,7 @@ Magnetometer | ✓ | ✓ Multi-camera | ✓ | ✕ Use individual cameras with same update rate Ray | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/26) RFID sensor and tag | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/27) +Segmentation camera | ✕ | ✕ (available from Fortress) Sonar | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/19) Thermal camera | ✕ | ✓ Wide-angle camera | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/24) @@ -111,6 +113,7 @@ VehiclePlugin | ✓ | WheelSlipPlugin | ✓ | ✓ WheelTrackedVehiclePlugin | ✓ | ✓ ([partially via DiffDrivePlugin](https://github.com/ignitionrobotics/ign-gazebo/blob/44951e3ddfd238f24182d4d80b1376f0d426bd43/examples/worlds/track_drive.sdf#L2141)) KineticEnergyMonitor | ✕ | ✓ +Buoyancy engine | ✓ | ✕ (available from Fortress) ### World plugins @@ -208,7 +211,7 @@ Copy / paste | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issu Building editor | ✓ | Model editor | ✓ | [Issues](https://github.com/ignitionrobotics/ign-gazebo/issues?q=is%3Aissue+is%3Aopen+label%3Aeditor) FPS view control | ✓ | -Orthographic projection | ✓ | ✕ (available from Fortress) +Orthographic projection | ✓ | ✕ (available from Fortress) Undo / redo | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/104) Save world | ✓ | ✓ Save GUI configuration | ✓ | ✓ @@ -267,8 +270,8 @@ transport bridge instead of plugins, contained in the Supported versions: -* ROS 1 Melodic -* ROS 2 Dashing +* ROS 1 Noetic +* ROS 2 Galactic ## Platforms @@ -298,3 +301,4 @@ Ellipsoid and capsule primitives | ✕ | ✓ Hydrodynamics | ✕ | ✓ Ocean currents | ✕ | ✓ Test fixture | ✓ | [✓](https://ignitionrobotics.org/api/gazebo/5.1/test_fixture.html) +Spherical coordinates | ✓ | ✕ (available from Fortress) diff --git a/fortress/GUI_tutorial.md b/fortress/GUI_tutorial.md new file mode 100644 index 0000000000..1aa96f9628 --- /dev/null +++ b/fortress/GUI_tutorial.md @@ -0,0 +1,127 @@ +# Understanding the GUI + +This guide is an introduction to the Ignition Graphical User Interface (GUI). + +## Prerequisites + +Before beginning, you should have [Ignition installed](/docs/fortress/install). +If you installed [from source](/docs/fortress/install) +you will need to [source](/docs/fortress/install_ubuntu_src#using-the-workspace) the workspace; +otherwise, you're good to go! + +Start by getting Ignition up and running with a sample world: + +```bash +ign gazebo shapes.sdf +``` + +`ign gazebo` will run the latest version of Ignition you have installed. +You can check if you have more than one version of Ignition installed by running `ign gazebo --versions`. +For example, if you have Fortress and Dome installed, `--versions` might return: + +```bash +5.0.0 +4.0.0 +``` + +To ensure you're working with Fortress, include the `--force-version` directive when starting up: + +```bash +ign gazebo --force-version 5.0.0 shapes.sdf +``` + +## GUI + +After running `shapes.sdf`, you should see the following screen: + +![shapes.sdf](img/shapes.png) + +The interface consists of several sections: + +### The Toolbar + +The toolbar along the top of the GUI contains two buttons, a file menu button on the left (horizontal stripes), and a plugins button on the right (vertical ellipsis). + +The file menu button allows you to save the world to a file, save and load interface configurations and customize interface style settings. +An interface configuration consists of the plugins you have loaded and the style settings in place. + +The top left toolbar hanging below the file menu button contains shape buttons (sphere, box, cylinder, capsule and ellipsoid) and transform control (first four buttons on the second row). +To learn more about transform control, go to the "Transform Control" section of [Manipulating Models](manipulating_models) tutorial. +The shape buttons allow you to directly insert a box, sphere, cylinder capsule, or ellipsoid model into the world. +Simply click on the shape you would like to insert, and place it into the world. +The shape will automatically snap onto the ground plane, and its properties will show up on the Entity Tree plugin window. + +The following is what it looks like after inserting shapes: + +![shape insertion](img/shape_insertion.png) + +The plugins button lists all the available plugins. +You can scroll down this list to see all the plugins that are available for your version of Ignition. +When you select one, its interface will appear in the right panel. + +### The Right Panel + +The GUI contains two plugins that you see in the right panel upon starting. +At the top is the Component Inspector, followed by the Entity Tree. + +Everything in a simulation is considered an "entity." +In `shapes.sdf`, the entities listed are the ground plane, each of the shape models, and the sun. + +Items in the list can be expanded to reveal their links, as well as corresponding visuals and collisions, and joints, if they exist. + +You can select entities in the simulation by clicking on their names in the entity tree. +You can also hold `Ctrl` and click to select multiple. + +![Selecting multiple entities from the entity tree](img/entity_select.png) + +You can also right-click on any plugin to open basic `Settings` or to `Close`. + +### The Scene + +Within the scene is where you'll interact with your simulated world and objects. + +Currently, you can navigate the scene with a mouse in several ways: + +* **Left-click**: select entity +* **Right-click**: opens menu with options: + * *Move to*: center the scene on an entity + * *Follow*: choose an entity for the view to stay centered on, whether it moves or you pan around + * *Remove*: erase the entity from the simulation + * *View > Collisions*: view collisions of the entity (that are defined in the SDF file) +* **Left-click and drag**: pan around the scene +* **Right-click and drag**: zoom in and out +* **Scroll wheel forward/backward**: zoom in and out +* **Scroll wheel click and drag**: rotate the scene + +More complex methods for interacting with the entities within a scene will be explained in-depth in the coming tutorials. + +#### Grid Config + +The grid visible in the scene can be adjusted by a plugin. +You can adjust features of the world's grid, including cell size, grid position, cell count, and even color. + +Open the the Grid Config plugin by selecting it from the plugins button from the toolbar and selecting it from the dropdown list. + +![Select Grid Config](img/grid_config.png) + +#### World Control + +Along the bottom edge of the scene, you'll notice several buttons: + +![Playback buttons](img/playback.png) + +From left to right, the options are `Play`, `Steps` and `RTF` (real time factor). + +Pressing `Play` will start the simulation. +You can use the same button to pause the simulation as well. + +The `Steps` button allows you to step through the simulation at the rate of a step size, or simulation iteration. +You can customize step size by hovering over the button. + +At the furthest right end of the scene, you can expand `RTF` to see not only the percentage value that compares real time with sim time, but also those individual values themselves, as well as iteration count. + +The function of the World Control options will become clearer once you begin manipulating entities. + +## Next Up + +Now that you're comfortable with Ignition GUI navigation and terminology, let's start learning about more meaningful model interactions with the [Manipulating Models](manipulating_models) tutorial. diff --git a/fortress/Manipulating_models.md b/fortress/Manipulating_models.md new file mode 100644 index 0000000000..f5506b5533 --- /dev/null +++ b/fortress/Manipulating_models.md @@ -0,0 +1,156 @@ +# Manipulating Models + +This tutorial will walk you through using various plugins to assist model and scene manipulation in the Ignition GUI. + +The Transform Control plugin is a combination of keybindings and transform control options: selection, translation, rotation and snapping. +This chart of [Ignition's keyboard shortcuts](hotkeys) may be helpful for this tutorial. + +The View Angle plugin allows you to quickly and easily adjust the direction from which your scene faces an entity in the simulation. + +The Component Inspector plugin displays a variety of object attributes. + +The Align Tool aligns entities along or about a specific entity's bounding box. + +## Prerequisites + +Start by getting Ignition up and running with a sample world: + +```bash +ign gazebo shapes.sdf +``` + +The previous tutorial, [Understanding the GUI](gui), explains the basics of navigating the Ignition GUI. + +## Transform Control + +The top left toolbar contains controls for transforming. +Alternatively, the Transform Control plugin can be selected from the plugin drop-down menu. +The plugin will then appear at the bottom of the right panel. + +![Choosing Transform Control from the plugin list](img/plugins.png) + +### Select Mode + +Selection is the default mode. +You can click to select entities in the scene. +A selected entity will be highlighted in the Entity Tree to indicate its selection. +You can select multiple entities by holding `Ctrl` and clicking. + +![Selecting multiple entities](img/select_mult.png) + +Entities can't be manipulated in select mode. + +You can always return to selection mode from any other mode by pressing `Esc`. + +### Translate Mode + +Enter into translate mode by clicking the second icon from the left in the top left toolbar, the Transform Control plugin, or by hitting the keyboard shortcut: `T`. + +![Translate mode icon](img/translate_icon.png) + +Translate mode allows you to translate entities along the x, y and z axes. + +Click on any entity while in translate mode to see the arrows representing the axes you can move along. +The red arrow represents the x-axis, green the y-axis, and blue the z-axis. +Click and hold on any of the arrows while moving your mouse to move the entity in that direction. + +![Translate mode](img/translate.gif) + +Additionally, holding down any one of the `X`, `Y` or `Z` keys, or a combination of them, while clicking and dragging will constrain the model's movement along those axes, regardless of the direction you move your mouse or the axis arrow you select. + +### Rotate Mode + +Enter into rotate mode by clicking the third icon from the left in the top left toolbar, the Transform Control plugin, or by hitting the keyboard shortcut: `R`. + +![Rotate mode icon](img/rotate_icon.png) + +Rotate mode allows you to rotate entities around the roll, pitch and yaw axes of rotation. + +Click on any entity while in rotate mode to see the circles representing the axes you can rotate along. +The red circle represents roll, green is pitch, and blue is yaw. +Click and hold on any of the circles while moving your mouse to rotate the entity around that axis. + +![Rotate mode](img/rotate.gif) + +#### Align to World frame + +An entity's local axes can become unaligned from the world frame after rotation. +If you would like to translate along the world frame axis, simply hold `Shift`. + +This isn't a permanent realignment; you can move the entity while holding `Shift`, but once you let go it will return to it's local translational frame. + +![World frame alignment - translation](img/translate_worldframe.gif) + +The same can be done for an entity's local rotational frame. + +![World frame alignment - rotation](img/rotate_worldframe.gif) + +### Enter Custom Snap Values + +When translating or rotating, you can "snap" an entity's movement to preset increments by holding `Ctrl` and then clicking and dragging. +By default, the snap value is 1 meter for translation and 45° for rotation. + +Translational snaps will snap relative to the world frame, whereas rotational snaps will snap relative to the object's current orientation. + +![Snap rotation](img/snap.gif) + +You can customize snap values by clicking on the snap icon ![Snap icon](img/snap_icon.png) in the top left toolbar or the Transform Control plugin. + +![Custom snap values](img/custom_snap.png) + +Try holding `Shift` and `Ctrl` simultaneously to snap a model along the world frame is if isn't already aligned. + +## Component Inspector + +With this plugin, you can select an entity to display some of its attributes, including its pose, whether or not wind is acting on it, whether or not it's static, and more. +The plugin also displays the gravitational and magnetic fields of your world. + +Expanding the `Pose` attribute will show the coordinate values for a selected object. +The values will update as the object is moved around (translated or rotated) while the simulation is running. + +![Updating pose values](img/pose_value.gif) + +You can also pause the plugin so an object's pose values don't update in the inspector while the simulation is playing. + +Additionally, the Component Inspector can be locked on one object so you can open another Component Inspector to simultaneously observe another object. + +![Two Component Inspectors](img/pose2.gif) + +## View Angle + +Select the View Angle from the plugins drop-down menu. + +You can choose which angle you want to view the scene from, relative to a selected entity or the world frame if no entity is selected. +The home button will return you to the original view pose from when the scene was loaded. + +You can also select multiple entities to face simultaneously from each view angle. + +![View angle for multiple entities](img/view.gif) + +## Align Tool + +Select the Align Tool from the plugins drop-down menu. + +The Align Tool aligns a model along or about the bounding box of another model, or any other entity that has a bounding box, like a link for example. +It can't, however, align a child link or anything other than the top-level model. + +With `Relative to First` selected, select two models using `Ctrl` + click (be sure you are in select mode) and then hover over any of the Align Tool +buttons to see a preview of the second model aligning to the first along its x, y or z axis. +Hovering over the buttons for each axis will show a preview of where the model would end up if aligned along that axis while clicking will confirm that +specific alignment. + +![Align](img/align.gif) + +The Reverse button will enable alignment about the outer boundary of a model's bounding box. This feature is helpful for placing objects exactly next to each +other. Notice the difference in alignment when the Reverse button is pressed in the gif below. + +![Align Reverse](img/align_reverse.gif) + +You can align more than two models as well, simply select more models with `Ctrl` + click. You can select `First` or `Last` in the `Relative to:` drop down menu to +choose which entity to align to. + +## Next Up + +So far you've interacted with basic shape models to learn about Ignition's GUI. +It's also possible to insert more detailed models from [Ignition Fuel](https://app.ignitionrobotics.org) into the GUI. +Check out the [Model Insertion from Fuel](fuel_insert) tutorial to learn how. diff --git a/fortress/Model_insertion_fuel.md b/fortress/Model_insertion_fuel.md new file mode 100644 index 0000000000..73de227dbd --- /dev/null +++ b/fortress/Model_insertion_fuel.md @@ -0,0 +1,44 @@ +# Model Insertion from Fuel + +Ignition Fuel hosts hundreds of models that can easily be added to a world running in the Ignition GUI. +Adding models to a world typically means adding them into your world `sdf` file, but with Fuel you can drag and drop existing models directly into the scene. + +## Prerequisites + +Start by getting Ignition up and running with an empty world: + +```bash +ign gazebo empty.sdf +``` + +The previous tutorial, [Manipulating Models](manipulating_models), shows you how to interact with models, which might be helpful once you add some Fuel models to your world. + +## Choose a Model + +Fuel's model collection is at [app.ignitionrobotics.org/fuel/models](https://app.ignitionrobotics.org/fuel/models). +Head over and browse the available content. + +![Fuel models preview](img/fuel.png) + +Click on any one of the thumbnails, or use the search bar. +For example, let's find the [Mine Cart Engine](https://app.ignitionrobotics.org/OpenRobotics/fuel/models/Mine%20Cart%20Engine). + +![Vent](img/mine_cart_engine_detail.png) + +Note that some of the model files are quite large and may take some time to download into your world. +Check that the file size on the right is reasonable for your application before moving on. + +## Drag and Drop + +The only thing left to do is drag and drop. +Click and hold the `Drag me!` button and do just that: drag your mouse into the GUI scene area. + +![Drag and drop](img/mine_cart_engine.gif) + +Now you can add more models, or even load in any one of the plugins you learned about to interact with the model the same way you could with the shapes in the previous tutorial. + +If you prefer to add a Fuel model permanently to an `sdf` file, you can just as easily download the code by clicking the download-arrow icon to the right of the model's image. + +## Next Up + +Now that you know how to add models hosted on Ignition Fuel, it is time to learn how to [Build Your Own Robot](building_robot). diff --git a/fortress/actors.md b/fortress/actors.md new file mode 100644 index 0000000000..756e18d234 --- /dev/null +++ b/fortress/actors.md @@ -0,0 +1,156 @@ +# Actors + +In this tutorial we will learn how to add `actors` to our world and how to create a scripted animation. +You can find the final world of this tutorial [here](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/actors/actor_demo.sdf). + +Animations are very useful if we want to have entities following a predefined path in simulation without being affected by the physics. This means that they won't fall due to gravity or collide with other objects. They will however, have a 3D visualization which can be seen by RGB cameras, and 3D meshes which can be detected by GPU based sensors. The tutorial explains how to create open-loop trajectories which don't interact with the rest of the simulation. + +## Actors + +In Ignition Gazebo, an animated model is called an `actor`. + +There are two types of animations which can be used separately or combined together: + +* Skeleton animation, which is relative motion between links in one model: + +![skeleton_movement](tutorials/actors/skeleton_movement.gif) + +* Trajectory animation, which carries all of the actor's links around the world as one group along a trajectory: + +![trajectory_movement](tutorials/actors/trajectory_movement.gif) + +* Combined, to achieve a skeleton animation which moves in the world: + +![combined_movement](tutorials/actors/combined_movement.gif) + +Actors have the following properties: + +* No forces are applied on them, be it from gravity or contact or anything else +* Actors support skeleton animation imported from COLLADA (.dae) and BVH (.bvh) files. +* Actors can have trajectories scripted directly in SDF. + +You can check out the full specification for the `` SDF element +[here](http://sdformat.org/spec?ver=1.8&elem=actor). + +## Skeleton + +Ignition Gazebo supports two different skeleton animation file formats: COLLADA (.dae) and Biovision Hierarchy (.bvh). + +Open any world, [empty.sdf](https://raw.githubusercontent.com/ignitionrobotics/ign-gazebo/main/examples/worlds/empty.sdf) world +for example, and add an actor called `actor_walking` as follows: + +```xml + + + https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/walk.dae + 1.0 + + + https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/walk.dae + + +``` + +### Skin + +In the `` tag we just loaded a COLLADA file `walk.dae` which specifies how our actor will look. When a COLLADA file is used within the `` tags its animation is loaded. The `` scales the skin's size. + +### Animation + +In the `` tag we specify how our actor will move. We can combine different skins with different animations as long as they have compatible skeletons. Now run the world and we should see our model moving. + +![actor loaded with skin tag](tutorials/actors/actor_skin.gif) + +**Note**: You can find many actors and models on [Ignition Fuel](https://app.ignitionrobotics.org/fuel). + +## Scripted trajectory + +This is the high level animation of actors, which consists of specifying a series of poses to be reached at specific times. Ignition Gazebo takes care of interpolating the motion between them so the movement is fluid. + +Animations that have displacement on the X axis, like `walk.dae`, will have the skeleton animated while following a trajectory. But for animations that don't, such as `talk_b.dae`, their skeletons won't move if there's a trajectory. + +We can make our actor follow the specified trajectory forever and start playing as soon as the world is loaded as follows: + +```xml + +``` + +Within the `` tag we define a series of waypoints which our actor will follow. The `` has two attributes: `id` and `type`. The `type` should have the same name as the animation `walk`. Under the `trajectory` tag we define the following: + +* `waypoint`: There can be any number of waypoints in a trajectory. Each waypoint consists of a time and a pose: + * `time`: The time in seconds, counted from the beginning of the script, when the pose should be reached. + * `pose`: The pose which should be reached with respect to the initial actor pose. + +Run the world and we should see our actor moving in a square following the waypoints. + +![actor_moving around](tutorials/actors/actor_demo.gif) + +**Notes**: + +* The order in which waypoints are defined is not important, they will follow the given times. +* The trajectory is smoothed as a whole. This means that you'll get a fluid motion, but the exact poses contained in the waypoints might not be reached. + +Now it's your turn! Try out different trajectory descriptions. + +## Video walk-through + +A video walk-through of this tutorial is available from our YouTube channel: [Ignition tutorials: Animated human actors](https://youtu.be/1VZexw67a2o) + + diff --git a/fortress/building_robot.md b/fortress/building_robot.md new file mode 100644 index 0000000000..4d5995d057 --- /dev/null +++ b/fortress/building_robot.md @@ -0,0 +1,447 @@ +# Building your own robot + +In this tutorial we will learn how to build our own robot in SDFormat. We will build a simple two wheeled robot. + + You can find the finished SDF file for the tutorial [here](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/building_robot/building_robot.sdf). + +## What is SDF + +[SDFormat](http://sdformat.org/) (Simulation Description Format), sometimes abbreviated as SDF, is an XML format that describes objects and environments for robot simulators, visualization, and control. + +## Building a world + +We will start by building a simple world and then build our robot in it. Open a new file called `building_robot.sdf` and copy the following code to it. + +```xml + + + + + 0.001 + 1.0 + + + + + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + true + + + + + 0 0 1 + + + + + + + 0 0 1 + 100 100 + + + + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + + + + + +``` + +Save the file, navigate to the directory where you saved the file and launch the simulator: + +`ign gazebo building_robot.sdf` + +**Note**: You can name your file any name and save it anywhere on your computer. + +You should see an empty world with just a ground plane and a sun light. Check [World demo](sdf_worlds) to learn how to build your own world. + +## Building a model + +Under the `` tag we will add our robot model as follows: + +### Defining the model + +```xml + + 0 0 0 0 0 0 +``` + +Here we define the name of our model `vehicle_blue`, which should be a unique name among its siblings (other tags or models on the same level). +Each model may have one link designated as the `canonical_link`, the implicit frame of the model is attached to this link. If not defined, the first `` will be chosen as the canonical link. +The `` tag is used to define the position and orientation of our model and the `relative_to` attribute is used to define the pose of the model relative to any other frame. +If `relative_to` is not defined, the model's `` will be relative to the world. + +Let's make our pose relative to the `world`. The values inside the pose tag are as follows: `X Y Z R P Y`, where the `X Y Z` represent the position of the frame and `R P Y` represent the orientation in roll pitch yaw. +We set them to zeros which makes the two frames (the model and the world) identical. + +## Links forming our robot + +Every model is a group of `links` (can be just one link) connected together with `joints`. + +### Chassis + +```xml + + 0.5 0 0.4 0 0 0 +``` + +We define the first link, the `chassis` of our car and it's pose relative to the `model`. + +#### Inertial properties + +```xml + + 1.14395 + + 0.095329 + 0 + 0 + 0.381317 + 0 + 0.476646 + + +``` + +Here we define the inertial properties of the chassis like the `` and the `` matrix. The values of the inertia matrix for primitive shapes can be calculated using this [tool](https://amesweb.info/inertia/mass-moment-of-inertia-calculator.aspx). + +#### Visual and collision + +```xml + + + + 2.0 1.0 0.5 + + + + + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + + +``` + +As the name suggests, the `` tag is responsible for how our link will look. +We define the shape of our link inside the `` tag as a `` (cuboid) and then specify the three dimensions (in meters) of this box inside the `` tag. +Then, inside the `` tag we define the material of our link. +Here we defined the ``, `` and `` colors in a set of four numbers red/green/blue/alpha each in range [0, 1]. + +```xml + + + + 2.0 1.0 0.5 + + + + + +``` + +The `` tag defines the collision properties of the link, how our link will react with other objects and the effect of the physics engine on it. + +**Note**: `` can be different from the visual properties, for example, simpler collision models are often used to reduce computation time. + +After copying all the parts above into the world file in order, run the world again: + +`ign gazebo building_robot.sdf` + +Our model should look like this: + +![car chassis](tutorials/building_robot/chassis.png) + +In the top left toolbar, click the Translate icon, then select your model. +You should see three axes like this: + +![model_axis](tutorials/building_robot/model_axis.png) + +These are the axes of our model where red is the x-axis, green is the y-axis and blue is the z-axis. + +### Left wheel + +Let's add wheels to our robot. The following code goes after the `` tag and before the `` tag. All the links and joints belonging to the same model should be defined before the ``. + +```xml + + -0.5 0.6 0 -1.5707 0 0 + + 1 + + 0.043333 + 0 + 0 + 0.043333 + 0 + 0.08 + + +``` + +We defined the name of our link `left_wheel` and then defined its `` `relative_to` the `chassis` link. +The wheel needed to be placed on the left to the back of the `chassis` so that's why we chose the values for `pose` as `-0.5 0.6 0`. +Also, our wheel is a cylinder, but on its side. +That's why we defined the orientation value as `-1.5707 0 0` which is a `-90` degree rotation around the x-axis (the angles are in radians). +Then we defined the `inertial` properties of the wheel, the `mass` and the `inertia` matrix. + +#### Visualization and Collision + +```xml + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + +``` + +The `` and the `` properties are similar to the previous link, except the shape of our link has the shape of `` that requires two attributes: the `` and the `` of the cylinder. +Save the file and run the world again, our model should look like this: + +![this](tutorials/building_robot/car_left_wheel.png) + +### Right wheel + +```xml + + + -0.5 -0.6 0 -1.5707 0 0 + + 1 + + 0.043333 + 0 + 0 + 0.043333 + 0 + 0.08 + + + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + +``` + +The right wheel is similar to the left wheel except for its position. + +### Defining an arbitrary frame + +As of SDF 1.7 (Fortress uses SDF 1.8), we can define arbitrary frames. It takes two attributes: + +* `name`: the name of the frame +* `attached_to`: the name of the frame or the link to which this frame is attached. + +Let's add a frame for our caster wheel as follows: + +```xml + + 0.8 0 -0.2 0 0 0 + +``` + +We gave our frame name `caster_frame` and attached it to the `chassis` link, then the `` tag to define the position and orientation of the frame. +We didn't use the `relative_to` attribute so the pose is with respect to the frame named in the `attached_to` attribute, `chassis` in our case. + +### Caster wheel + +```xml + + + + + 1 + + 0.016 + 0 + 0 + 0.016 + 0 + 0.016 + + + + + + 0.2 + + + + 0.0 1 0.0 1 + 0.0 1 0.0 1 + 0.0 1 0.0 1 + + + + + + 0.2 + + + + +``` + +Our last link is the `caster` and its pose is with respect to the frame `caster_frame` we defined above. +As you could notice we closed the `pose` tag without defining the position or the orientation; in this case the pose of the link is the same as (identity) the frame in `relative_to`. + +In the `` and `` tags we defined a different shape `` which requires the `` of the sphere. + +### Connecting links together (joints) + +We need to connect these links together; here comes the job of the `` tag. +The joint tag connects two links together and defines how they will move with respect to each other. +Inside the `` tag we need to define the two links to connect and their relations (way of movement). + +#### Left wheel joint + +```xml + + +``` + +Our first joint is the `left_wheel_joint`. +It takes two attributes: the name `name='left_wheel_joint'` and the type `type='revolute'`. +the `revolute` type gives 1 rotational degree of freedom with joint limits. +The pose of the joint is the same as the child link frame, which is the `left_wheel` frame. + +```xml + chassis + left_wheel +``` + +Every joint connects two links (bodies) together. +Here we connect the `chassis` with the `left_wheel`. +`chassis` is the parent link and `left_wheel` is the child link. + +```xml + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + +``` + +Here we define the axis of rotation. +The axis of rotation can be any frame, not just the `parent` or the `child` link. +We chose the y-axis with respect to the `model` frame so we put `1` in the y element and zeros in the others. +For the revolute joint we need to define the `` of our rotation angle in the `` and `` tags. + +**Note**: The angles are in radians. + +#### Right wheel joint + +The `right_wheel_joint` is very similar except for the pose of the joint. +This joint connects the `right_wheel` with the `chassis`. + +```xml + + + chassis + right_wheel + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + +``` + +#### Caster wheel joint + +For the caster we need a different type of joint (connection). +We used `type='ball'` which gives 3 rotational degrees of freedom. + +```xml + + chassis + caster + +``` + +## Conclusion + +Run the world: + +`ign gazebo building_robot.sdf` + +It should look like this: + +![two_wheeled_robot](tutorials/building_robot/two_wheeled_robot.png) + +Hurray! We build our first robot. You can learn more details about SDFormat tags [here](http://sdformat.org/spec). In the next [tutorial](moving_robot) we will learn how to move our robot around. + +## Video walk-through + +A video walk-through of this tutorial is available from our YouTube channel: [Ignition tutorials: Building a robot](https://youtu.be/Z-gjU0KAjiw). + + diff --git a/fortress/comparison.md b/fortress/comparison.md new file mode 100644 index 0000000000..ccfc9cdb5c --- /dev/null +++ b/fortress/comparison.md @@ -0,0 +1,304 @@ +# Feature comparison + +A list of features present in [Gazebo-classic](https://github.com/osrf/gazebo/) +version 11 and the status of their migration to +[Ignition Fortress](https://ignitionrobotics.org/). + +All the issues below are labeled with +[close the gap](https://github.com/search?q=org%3Aignitionrobotics+label%3A%22close+the+gap%22&type=Issues) +on GitHub. + +## Sensors + +Sensor | Gazebo-classic | Ignition Gazebo +-- | -- | -- +Air pressure | ✕ | ✓ +Altimeter | ✓ | ✓ +Bounding Box camera | ✕ | ✓ +Camera | ✓ | ✓ +Contact sensor | ✓ | ✓ +Depth camera | ✓ | ✓ +Force-torque | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/25) +GPS | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/23) +GPU Ray | ✓ | ✓ Renamed to GPU Lidar +IMU | ✓ | ✓ +Logical camera | ✓ | ✓ +Magnetometer | ✓ | ✓ +Multi-camera | ✓ | ✕ Use individual cameras with same update rate +Ray | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/26) +RFID sensor and tag | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/27) +Segmentation camera | ✕ | ✓ +Sonar | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/19) +Thermal camera | ✕ | ✓ +Wide-angle camera | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/24) +Wireless | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/28) + +Sensor features | Gazebo-classic | Ignition Gazebo +-- | -- | -- +Custom update rate | ✓ | ✓ +Gaussian noise | ✓ | ✓ +Custom sensors | ✓ | ✓ +Laser retroreflection | ✓ | ✓ +Camera distortion | ✓ | [Issue](https://github.com/ignitionrobotics/ign-sensors/issues/107) +Performance metrics | ✓ | ✓ + +## SDF Features + +Feature | Gazebo-classic | Ignition Gazebo +-- | -- | -- +SDF frame semantics |✓| ✓ +SDF parametrization | ✕ | [✓](http://sdformat.org/tutorials?tut=param_passing_proposal) +Load models from local files | ✓ | [✓](https://ignitionrobotics.org/api/gazebo/4.0/resources.html) +Closed kinematic chains | ✓ | [Issue](https://github.com/ignitionrobotics/ign-physics/issues/25) +Nested models | ✓ | ✓ +Populations | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/240) +Actors | ✓ | ✓ +Markers | ✓ | ✓ +Heightmaps | ✓ | ✓ +DEM (Digital Elevation Models) | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/235) +Polylines | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/186) +World plugins | ✓ | ✓ Now called System plugin +Model plugins | ✓ | ✓ Now called System plugin +Sensor plugins | ✓ | ✓ Now called System plugin +Visual plugins | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/265) +GUI plugins | ✓ | ✓ Ignition GUI plugins and Gazebo GUI systems +System plugins | ✓ | ✓ Through Ignition Launch + +## Plugins + +### Model plugins + +Plugin | Gazebo-classic | Ignition Gazebo +-- | -- | -- +ActorPlugin | ✓ | ✕ See [FollowActor](https://github.com/ignitionrobotics/ign-gazebo/blob/main/src/systems/follow_actor/FollowActor.hh) for a demo of Actor APIs +ActuatorPlugin | ✓ | +ArduCopterPlugin | ✓ | +AttachLightPlugin | ✓ | ✕ Does not apply, use SDF +Breadcrumbs | ✕ | ✓ +BuoyancyPlugin | ✓ | [✓](https://github.com/ignitionrobotics/ign-gazebo/blob/ign-gazebo4/examples/worlds/buoyancy.sdf) +CartDemoPlugin | ✓ | ✕ +CessnaPlugin | ✓ | +DiffDrivePlugin | ✓ | ✓ +ElevatorPlugin | ✓ | +FlashLightPlugin | ✓ | +FollowerPlugin | ✓ | +GimbalSmall2dPlugin | ✓ | +GravityCompensationPlugin | ✓ | +HarnessPlugin | ✓ | +HydraDemoPlugin | ✓ | +InitialVelocityPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/50) +JointControlPlugin | ✓ (force / pos / vel, from SDF) | ✓ (vel, from msg) +JointStatePublisher | ✕ | ✓ +JointTrajectoryPlugin | ✓ | +KeysToCmdVelPlugin | ✓ | Use `ignition::gui::KeyPublisher` with `ignition::gazebo::systems::TriggeredPublisher` +KeysToJointsPlugin | ✓ | Use `ignition::gui::KeyPublisher` with `ignition::gazebo::systems::TriggeredPublisher` +LedPlugin | ✓ | +LiftDragPlugin | ✓ | ✓ +LinearBatteryConsumerPlugin | ✓ | ✓ +LinearBatteryPlugin | ✓ | ✓ +LinkPlot3DPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/231) +MudPlugin | ✓ | +MulticopterMotorModel | ✕ | ✓ +PlaneDemoPlugin | ✓ | +PosePublisher | ✕ | ✓ +RandomVelocityPlugin | ✓ | +RegionEventBoxPlugin | ✓ | +SimpleTrackedVehiclePlugin | ✓ | +SkidSteerDrivePlugin | ✓ | ✓ +SphereAtlasDemoPlugin | ✓ | ✕ +TouchPlugin | ✓ | ✓ +TrackedVehiclePlugin | ✓ | +VariableGearboxPlugin | ✓ | +VehiclePlugin | ✓ | +WheelSlipPlugin | ✓ | ✓ +WheelTrackedVehiclePlugin | ✓ | ✓ ([partially via DiffDrivePlugin](https://github.com/ignitionrobotics/ign-gazebo/blob/44951e3ddfd238f24182d4d80b1376f0d426bd43/examples/worlds/track_drive.sdf#L2141)) +KineticEnergyMonitor | ✕ | ✓ +Buoyancy engine | ✓ | ✓ + +### World plugins + +Plugin | Gazebo-classic | Ignition Gazebo +-- | -- | -- +ArrangePlugin | ✓ | +ContainPlugin | ✓ | Partial port, [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/162) +HydraPlugin | ✓ | +JoyPlugin | ✓ | ✓ Migrated as an Ignition Launch plugin +MisalignmentPlugin | ✓ | +RubblePlugin | ✓ | +StaticMapPlugin | ✓ | +TransporterPlugin | ✓ | +WindPlugin | ✓ | ✓ + +### Sensor plugins + +Plugin | Gazebo-classic | Ignition Gazebo +-- | -- | -- +BreakableJointPlugin | ✓ | +CameraPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/49) +ContactPlugin | ✓ | ✓ +DepthCameraPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/49) +FiducialCameraPlugin | ✓ | +ForceTorquePlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/49) +GpuRayPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/49) +ImuSensorPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/49) +LensFlareSensorPlugin | ✓ | +PressurePlugin | ✓ | +RayPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/49) +RaySensorNoisePlugin | ✓ | ✕ Use SDF +SonarPlugin | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/49) + +### Visual plugins + +Plugin | Gazebo-classic | Ignition Gazebo +-- | -- | -- +AmbientOcclusionVisualPlugin | ✓ | +BlinkVisualPlugin | ✓ | +HeightmapLODPlugin | ✓ | +ShaderParamVisualPlugin | ✓ | + +### GUI plugins + +Plugin | Gazebo-classic | Ignition Gazebo +-- | -- | -- +CessnaGUIPlugin | ✓ | +KeyboardGUIPlugin | ✓ | `ignition::gui::KeyPublisher` +LookAtDemoPlugin | ✓ | +TimerGUIPlugin | ✓ | + +### System plugins + +Plugin | Gazebo-classic | Ignition Gazebo +-- | -- | -- +ModelPropShop | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/100) +RestUiPlugin | ✓ | +RestWebPlugin | ✓ | +StopWorldPlugin | ✓ | + +## GUI + +Feature | Gazebo-classic | Ignition Gazebo +-- | -- | -- +Play / pause / step | ✓ | ✓ +Reset world / models | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/203) +World stats | ✓ | ✓ +Topic echo | ✓ | ✓ +Image viewer | ✓ | ✓ +Translate / rotate | ✓ | ✓ +Scale models | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/195) +Insert models from Fuel | Partial support | ✓ +Insert models from disk | ✓ | ✓ +Insert simple shapes | ✓ | ✓ +Insert simple lights | ✓ | ✓ +Delete models | ✓ | ✓ +World tree | ✓ | ✓ +Scene properties | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/246) +Log recording / playback | ✓ | ✓ +Plotting | ✓ | ✓ +Video recording | ✓ | ✓ +Screenshot | ✓ | [✓](https://ignitionrobotics.org/api/gui/3.5/screenshot.html) +View angles | ✓ | ✓ +Apply force / torque | ✓ | +Visualize as transparent | ✓ | ✓ +Visualize as wireframe | ✓ | ✓ +Visualize joints | ✓ | ✓ +Visualize collisions | ✓ | ✓ +Visualize inertia | ✓ | ✓ +Visualize CoM | ✓ | ✓ +Visualize contacts | ✓ | ✓ +Visualize lights | ✓ | ✓ +Follow / move to | ✓ | ✓ +Copy / paste | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/102) +Building editor | ✓ | +Model editor | ✓ | [Issues](https://github.com/ignitionrobotics/ign-gazebo/issues?q=is%3Aissue+is%3Aopen+label%3Aeditor) +FPS view control | ✓ | +Orthographic projection | ✓ | ✓ +Undo / redo | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/104) +Save world | ✓ | ✓ +Save GUI configuration | ✓ | ✓ +Color scheme and themes | ✕ | ✓ +Position, resize and configure widgets | ✕ | ✓ +Load GUI plugins from menu | ✕ | ✓ +Edit model pose | ✓ | ✓ +Edit light properties | ✓ | ✓ +Edit physics properties | ✓ | ✓ + +## Physics + +In Ignition Physics, physics engines are integrated as plugins, so any engine +can be integrated without changing the core source code, as it was the case +in Gazebo. + +Feature | Gazebo-classic | Ignition Gazebo +-- | -- | -- +ODE engine | ✓ | [Issue](https://github.com/ignitionrobotics/ign-physics/issues/63) +Bullet engine | ✓ | ✓ +DART engine | ✓ | ✓ Plugin shipped with ign-physics +Simbody engine | ✓ | [Issue](https://github.com/ignitionrobotics/ign-physics/issues/63) +TPE engine | ✕ | ✓ +Custom engine plugins | ✕ | ✓ +Collide bitmasks | ✓ | ✓ +Restitution coefficient | ✓ | ✓ +Collision detector | ✓ | ✓ +Solver | ✓ | ✓ + +## Rendering + +In Ignition Rendering, render engines are integrated as plugins, so any engine +can be integrated without changing the core source code. + +Feature | Gazebo-classic | Ignition Gazebo +-- | -- | -- +Ogre 1.x engine | ✓ | ✓ +Ogre 2.x engine | ✕ | ✓ +Optix engine | ✕ | ✓ Partial support +Custom engine plugins | ✕ | [✓](https://ignitionrobotics.org/api/rendering/5.0/renderingplugin.html) +Sky | ✓ | ✓ +Fog | ✓ | +Material scripts | ✓ (Ogre 1.x scripts) | Does not apply +Physically Based Rendering (PBR) | ✕ | ✓ (with engines that support it, like Ogre 2) +Normal maps | ✓ | ✓ +Environment maps | ✕ | ✓ +Lightmaps | ✕ | ✓ +Particle effects | ✕ | ✓ +Render order | ✕ | ✓ + +## ROS integration + +ROS integration with Ignition will be done primarily via a +transport bridge instead of plugins, contained in the +[ros_ign](https://github.com/osrf/ros1_ign) package. + +Supported versions: + +* ROS 1 Noetic +* ROS 2 Rolling + +## Platforms + +Platform | Gazebo-classic | Ignition Gazebo +-- | -- | -- +Ubuntu | ✓ | ✓ +OSX | ✓ | Most of the stack works, outstanding issues: [command line](https://github.com/ignitionrobotics/ign-gazebo/issues/25), [render window](https://github.com/ignitionrobotics/ign-gazebo/issues/44) +Windows | ✓ | The stack works up to ign-gazebo: [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/168) + +## Others + +Feature | Gazebo-classic | Ignition Gazebo +-- | -- | -- +Nested models | ✓ | ✓ +Log / playback | ✓ | ✓ +Web client (GzWeb) | ✓ | +COLLADA meshes | ✓ | ✓ +OBJ meshes | ✓ | ✓ +STL meshes | ✓ | ✓ +Code introspection | ✓ | All simulation state is accessible from system plugins or through the `SceneBroadcaster`'s state topic +Distribute simulation across processes | ✕ | (coming up) +Incrementally load levels | ✕ | ✓ +Online model database | [gazebo_models repository](https://github.com/osrf/gazebo_models/) | [Ignition Fuel](https://app.ignitionrobotics.org/fuel/models) +Saved simulation states | ✓ | [Issue](https://github.com/ignitionrobotics/ign-gazebo/issues/137) +Sphere, cylinder and box primitives | ✓ | ✓ +Ellipsoid and capsule primitives | ✕ | ✓ +Hydrodynamics | ✕ | ✓ +Ocean currents | ✕ | ✓ +Test fixture | ✓ | [✓](https://ignitionrobotics.org/api/gazebo/5.1/test_fixture.html) +Spherical coordinates | ✓ | ✓ diff --git a/fortress/hotkeys.md b/fortress/hotkeys.md new file mode 100644 index 0000000000..eda0c4f9e2 --- /dev/null +++ b/fortress/hotkeys.md @@ -0,0 +1,41 @@ +# Ignition Keyboard Shortcuts + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ActionOperationInstruction
MODE
Enter Selection mode (default mode)Escpress "Esc" for Select (model) mode
Enter Rotate moderpress "r" for Rotate (model) mode
Enter Translate modetpress "t" for Translate (model) mode
Pause / unpauseSpacepress the space bar to pause / unpause
MANIPULATING MODELS
Rotate modelrpress "r" for Rotate mode; click a model & rotate it using markers
Translate modeltpress "t" for Translate mode; click a model & translate it using markers
Constrain along axisx/y/zhold key while manipulating a model to constrain movement along that axis
Snap when rotatingCtrl + draghold Ctrl while rotating a model to rotate in customizable increments (default 45°)
Snap when translatingCtrl + draghold Ctrl while translating a model to move in customizable increments (default 1m)
Align to world frameShifthold Shift while manipulating a model to temporarily align axis its to the world frame
+ + + +
diff --git a/fortress/img/align.gif b/fortress/img/align.gif new file mode 100644 index 0000000000..04b15b6cfd Binary files /dev/null and b/fortress/img/align.gif differ diff --git a/fortress/img/align_reverse.gif b/fortress/img/align_reverse.gif new file mode 100644 index 0000000000..3854876a24 Binary files /dev/null and b/fortress/img/align_reverse.gif differ diff --git a/fortress/img/bridge_image_exchange_ign-gazebo.png b/fortress/img/bridge_image_exchange_ign-gazebo.png new file mode 100644 index 0000000000..a2c020fbd7 Binary files /dev/null and b/fortress/img/bridge_image_exchange_ign-gazebo.png differ diff --git a/fortress/img/custom_snap.png b/fortress/img/custom_snap.png new file mode 100644 index 0000000000..fe22a3e617 Binary files /dev/null and b/fortress/img/custom_snap.png differ diff --git a/fortress/img/entity_select.png b/fortress/img/entity_select.png new file mode 100644 index 0000000000..5cba580ab2 Binary files /dev/null and b/fortress/img/entity_select.png differ diff --git a/fortress/img/fuel.png b/fortress/img/fuel.png new file mode 100644 index 0000000000..e7cb49183c Binary files /dev/null and b/fortress/img/fuel.png differ diff --git a/fortress/img/grid.gif b/fortress/img/grid.gif new file mode 100644 index 0000000000..562b55e118 Binary files /dev/null and b/fortress/img/grid.gif differ diff --git a/fortress/img/grid2.gif b/fortress/img/grid2.gif new file mode 100644 index 0000000000..4eed529a6e Binary files /dev/null and b/fortress/img/grid2.gif differ diff --git a/fortress/img/grid_config.png b/fortress/img/grid_config.png new file mode 100644 index 0000000000..e7fc8b124f Binary files /dev/null and b/fortress/img/grid_config.png differ diff --git a/fortress/img/mine_cart_engine.gif b/fortress/img/mine_cart_engine.gif new file mode 100644 index 0000000000..5451296fdd Binary files /dev/null and b/fortress/img/mine_cart_engine.gif differ diff --git a/fortress/img/mine_cart_engine_detail.png b/fortress/img/mine_cart_engine_detail.png new file mode 100644 index 0000000000..61c2c9104f Binary files /dev/null and b/fortress/img/mine_cart_engine_detail.png differ diff --git a/fortress/img/playback.png b/fortress/img/playback.png new file mode 100644 index 0000000000..bd521bce15 Binary files /dev/null and b/fortress/img/playback.png differ diff --git a/fortress/img/plugins.png b/fortress/img/plugins.png new file mode 100644 index 0000000000..ad9600fc8b Binary files /dev/null and b/fortress/img/plugins.png differ diff --git a/fortress/img/pose2.gif b/fortress/img/pose2.gif new file mode 100644 index 0000000000..630377ebd6 Binary files /dev/null and b/fortress/img/pose2.gif differ diff --git a/fortress/img/pose_value.gif b/fortress/img/pose_value.gif new file mode 100644 index 0000000000..df1263b28a Binary files /dev/null and b/fortress/img/pose_value.gif differ diff --git a/fortress/img/rotate.gif b/fortress/img/rotate.gif new file mode 100644 index 0000000000..649b7227ab Binary files /dev/null and b/fortress/img/rotate.gif differ diff --git a/fortress/img/rotate_icon.png b/fortress/img/rotate_icon.png new file mode 100644 index 0000000000..a594047df1 Binary files /dev/null and b/fortress/img/rotate_icon.png differ diff --git a/fortress/img/rotate_worldframe.gif b/fortress/img/rotate_worldframe.gif new file mode 100644 index 0000000000..d57f531cb8 Binary files /dev/null and b/fortress/img/rotate_worldframe.gif differ diff --git a/fortress/img/select_mult.png b/fortress/img/select_mult.png new file mode 100644 index 0000000000..ef1cab3d83 Binary files /dev/null and b/fortress/img/select_mult.png differ diff --git a/fortress/img/shape_insertion.png b/fortress/img/shape_insertion.png new file mode 100644 index 0000000000..9212f8ca8a Binary files /dev/null and b/fortress/img/shape_insertion.png differ diff --git a/fortress/img/shapes.png b/fortress/img/shapes.png new file mode 100644 index 0000000000..7c27568d90 Binary files /dev/null and b/fortress/img/shapes.png differ diff --git a/fortress/img/snap.gif b/fortress/img/snap.gif new file mode 100644 index 0000000000..d113f863d1 Binary files /dev/null and b/fortress/img/snap.gif differ diff --git a/fortress/img/snap_icon.png b/fortress/img/snap_icon.png new file mode 100644 index 0000000000..490112b542 Binary files /dev/null and b/fortress/img/snap_icon.png differ diff --git a/fortress/img/translate.gif b/fortress/img/translate.gif new file mode 100644 index 0000000000..0956282b01 Binary files /dev/null and b/fortress/img/translate.gif differ diff --git a/fortress/img/translate_icon.png b/fortress/img/translate_icon.png new file mode 100644 index 0000000000..6c32b6ebcd Binary files /dev/null and b/fortress/img/translate_icon.png differ diff --git a/fortress/img/translate_worldframe.gif b/fortress/img/translate_worldframe.gif new file mode 100644 index 0000000000..ba11d4b3d6 Binary files /dev/null and b/fortress/img/translate_worldframe.gif differ diff --git a/fortress/img/view.gif b/fortress/img/view.gif new file mode 100644 index 0000000000..badc9da1a8 Binary files /dev/null and b/fortress/img/view.gif differ diff --git a/fortress/index.yaml b/fortress/index.yaml index 9fccdb83a1..60d911e23f 100644 --- a/fortress/index.yaml +++ b/fortress/index.yaml @@ -41,3 +41,46 @@ pages: - name: troubleshooting title: Troubleshooting file: troubleshooting.md + - name: comparison + title: Feature Comparison + file: comparison.md + description: A list of features present in Gazebo-classic and the status of their migration to Ignition. + - name: tutorials + title: Tutorials + file: tutorials.md + children: + - name: ros_integration + title: ROS Integration + file: ros_integration.md + description: This tutorial details how to interface with ROS, enabling the ability to use tools such as Rviz for robot or sensor visualization. + - name: ros2_integration + title: ROS 2 Integration + file: ros2_integration.md + - name: gui + title: Understanding the GUI + file: GUI_tutorial.md + - name: manipulating_models + title: Manipulating Models + file: Manipulating_models.md + - name: fuel_insert + title: Model Insertion from Fuel + file: Model_insertion_fuel.md + - name: hotkeys + title: Keyboard Shortcuts + file: hotkeys.md + description: Ignition keyboard shortcuts + - name: building_robot + title: Building your own robot + file: building_robot.md + - name: moving_robot + title: Moving the robot + file: moving_robot.md + - name: sdf_worlds + title: SDF worlds + file: sdf_worlds.md + - name: sensors + title: Sensors + file: sensors.md + - name: actors + title: Actors + file: actors.md diff --git a/fortress/install.md b/fortress/install.md index 416379f2e0..c17c301163 100644 --- a/fortress/install.md +++ b/fortress/install.md @@ -1,13 +1,13 @@ # Fortress Installation Until the official release, Fortress can be compiled from source or installed -from nightly debian packages on Linux. +from pre-release debian packages on Linux. Fortress supports the following platforms: - * Ubuntu Bionic amd64 and Focal on amd64 - * MacOS Mojave and Catalina - * Ignition currently only works in headless mode + * Ubuntu Bionic amd64/arm64/i386 and Focal on amd64/arm64 + * MacOS Catalina and BigSur + * Ignition currently only works in headless mode using Ogre 1 (GUI does not render; instead of using `ign gazebo fuel.sdf` command, use `ign gazebo -s fuel.sdf` to start the server only). * Windows 10 diff --git a/fortress/install_osx.md b/fortress/install_osx.md index 1d04df1a72..951b4ab1d1 100644 --- a/fortress/install_osx.md +++ b/fortress/install_osx.md @@ -1,6 +1,6 @@ # Binary Installation on MacOS -All the Fortress binaries are available in Mojave and Catalina using the +All the Fortress binaries are available in Catalina and BigSur using the [homebrew package manager](https://brew.sh/). Up to Fortress's release date, the binaries should be considered unstable. diff --git a/fortress/install_ubuntu.md b/fortress/install_ubuntu.md index f69ea28f10..133a199e04 100644 --- a/fortress/install_ubuntu.md +++ b/fortress/install_ubuntu.md @@ -18,7 +18,7 @@ Then install Ignition Fortress: ```bash sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list' -sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-nightly `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-nightly.list' +sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-prerelease `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-prerelease.list' wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add - sudo apt-get update sudo apt-get install ignition-fortress diff --git a/fortress/moving_robot.md b/fortress/moving_robot.md new file mode 100644 index 0000000000..0596ce98f9 --- /dev/null +++ b/fortress/moving_robot.md @@ -0,0 +1,173 @@ +# Moving the robot + +In this tutorial we will learn how to move our robot. We will use the +robot we built in the [Build your own robot](building_robot) +tutorial. You can download the robot from [here](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/building_robot/building_robot.sdf). +You can also find the finished world of this tutorial [here](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/moving_robot/moving_robot.sdf). + +## What is a plugin + +To make our robot move we will use the `diff_drive` plugin. But before doing so let's answer the question "What is a plugin?" A plugin is a chunk of code that is compiled as a shared library and inserted into the simulation. Plugins make us control many aspects of the simulation like world, models, etc. + +### Diff_drive plugin + +`diff_drive` plugin helps us control our robot, specifically a robot that +can be differentially driven. Let's setup the plugin on our robot. Open +the `building_robot.sdf` and add the following code within the `vehicle_blue` +model tags. + +```xml + + left_wheel_joint + right_wheel_joint + 1.2 + 0.4 + 1 + cmd_vel + +``` + +The `` tag has two attributes, `filename` which takes the library file name and `name` which takes the name of the plugin. +In the `` and `` tags we define the joints which connect the left and the right wheel with the body of the robot, in our case `left_wheel_joint` and `right_wheel_joint`. `` takes the distance between the two wheels. +Our robot has its `left_wheel` at 0.6 m and the `right_wheel` at -0.6 m in y-axis with respect to the `chassis`, so the `wheel_separation` is 1.2 m. +`` takes the radius of the wheel which was defined in the `` tag under the wheel link. +`` sets the frequency at which the odometry is published at `/model/vehicle_blue/odometry`. +`cmd_vel` is the input `` to the `DiffDrive` plugin. + +## Topics and Messages + +Now our model is ready. We just need to send commands (messages) to it. +These messages will be published (sent) on the `cmd_vel` topic defined above. + +A topic is simply a name for grouping a specific set of messages or a particular service. +Our model will subscribe (listen) to the messages sent on the `cmd_vel` topic. + +Launch the robot world: + +`ign gazebo building_robot.sdf` + +In another terminal let's send a message to to our robot: + +`ign topic -t "/cmd_vel" -m ignition.msgs.Twist -p "linear: {x: 0.5}, angular: {z: 0.05}"` + +Now you should have your robot moving in the simulation. + +**Note:** Don't forget to press the play button in the simulation. + +The command specifies the topic to publish to after the `-t` option. +After the `-m` we specify the message type. +Our robot expects messages of type `Twist` which consists of two components, `linear` and `angular`. +After the `-p` option we specify the content (value) of the message: linear speed `x: 0.5` and angular speed `z: 0.05`. + +**Hint:** You can know what every topic option does using this command: `ign topic -h` + +For more information about `Topics` and `Messages` in Ignition check the [Transport library tutorials](https://ignitionrobotics.org/api/transport/9.0/tutorials.html) + +## Moving the robot using the keyboard + +Instead of sending messages from the terminal we will send messages using the keyboard keys. To do so we will add two new plugins: `KeyPublisher` and `TriggeredPublisher`. + +### KeyPublisher + +`KeyPublisher` is an `ign-gui` plugin that reads the keyboard's keystrokes and sends them on a default topic `/keyboard/keypress`. +Let's try this plugin as follows: + +* In one terminal type + + `ign gazebo building_robot.sdf` + +* In the top right corner click on the plugins dropdown list (vertical ellipsis), click the Key Publisher. + +* In another terminal type + + `ign topic -e -t /keyboard/keypress` + +The last command will display all messages sent on `/keyboard/keypress` topic. + +In the ignition window press different keys and you should see data (numbers) on the terminal where you run the `ign topic -e -t /keyboard/keypress` command. + +![KeyPublisher](tutorials/moving_robot/keypublisher_data.png) + +We want to map these keystrokes into messages of type `Twist` and publish them to the `/cmd_vel` topic which our model listens to. +The `TriggeredPublisher` plugin will do this. + +### Triggered Publisher + +The `TriggeredPublisher` plugin publishes a user specified message on an output topic in response to an input message that matches user specified criteria. +Let's add the following code under the `` tag: + +```xml + + + + 16777235 + + + linear: {x: 0.5}, angular: {z: 0.0} + + +``` + +This code defines the `triggered-publisher` plugin. +It accepts messages of type `ignition.msgs.Int32` on the `/keyboard/keypress` topic and if the value in the `data` field matches `16777235`(Up arrow key) it outputs a `Twist` message on the `cmd_vel` topic with values `x: 0.5`, `z: 0.0`. + +Now launch `building_robot.sdf` then add the Key Publisher plugin and our robot should move forward as we press the Up arrow key ↑ (make sure you start the simulation by pressing the play button to see the robot move forward after pressing the Up arrow key). + +There is a demo explaining how the [Triggered Publisher](https://github.com/ignitionrobotics/ign-gazebo/blob/ign-gazebo2/tutorials/triggered_publisher.md) works. + +### Moving using arrow keys + +To see what values are sent on the `/keyboard/keypress` topic when pressing the arrows we can use the `--echo` or `-e` option + +* Run the model in one terminal: + + `ign gazebo building_robot.sdf` + +* In the top right corner click on the plugins dropdown list (vertical ellipsis), click the Key Publisher. + +* In another terminal run the following command: + + `ign topic -e -t /keyboard/keypress` + +Start pressing the arrows keys and see what values they give: + +* Left ← : 16777234 +* Up ↑ : 16777235 +* Right → : 16777236 +* Down ↓ : 16777237 + +We will add the `Triggered publisher` plugin for each arrow key. +For example, the Down arrow: + +```xml + + + + 16777237 + + + linear: {x: -0.5}, angular: {z: 0.0} + + +``` + +Map each arrow (key stroke) with the desired message (movement) as we did with the backward arrow: + +* Left ➞ 16777234 ➞ linear: {x: 0.0}, angular: {z: 0.5} +* Up ➞ 16777235 ➞ linear: {x: 0.5}, angular: {z: 0.0} +* Right ➞ 16777236 ➞ linear: {x: 0.0}, angular: {z: -0.5} +* Down ➞ 16777237 ➞ linear: {x: 0.5}, angular: {z: 0.0} + +Now it's your turn try to make the robot move using different keys. + +In the [next tutorial](sdf_worlds), you'll learn to create your own simulated world with SDF. + +## Video walk-through + +A video walk-through of this tutorial is available from our YouTube channel: [Ignition tutorials: Moving robot](https://youtu.be/oHtQYPDGk3Y). + + diff --git a/fortress/ros2_integration.md b/fortress/ros2_integration.md new file mode 100644 index 0000000000..3d3cbfce48 --- /dev/null +++ b/fortress/ros2_integration.md @@ -0,0 +1,87 @@ +# ROS 2 Integration + +In this tutorial we will learn how to Integrate ROS 2 with Ignition. We will establish +communication between them. This can help in many aspects; we can receive data or commands +from ROS and apply it to Ignition and vice versa. + +## ros_ign_bridge + +`ros_ign_bridge` provides a network bridge which enables the exchange of messages between ROS 2 and Ignition Transport. Its support is limited to only certain message types. Please, check this [README](https://github.com/ignitionrobotics/ros_ign/blob/ros2/ros_ign_bridge/README.md) to verify if your message type is supported by the bridge. + +## Requirements + +For this tutorial to work correctly make sure you have the following installed: + +* [ROS 2 Rolling](https://index.ros.org/doc/ros2/Installation/Foxy/) +* [Ignition Fortress](https://ignitionrobotics.org/docs/fortress) +* [ros_ign_bridge](https://github.com/ignitionrobotics/ros_ign/tree/ros2#from-source) + +## Bidirectional communication + +We can initialize a bidirectional bridge so we can have ROS as the publisher and Ignition as the subscriber or vice versa. + +For example: + +``` +ros2 run ros_ign_bridge parameter_bridge /TOPIC@ROS_MSG@IGN_MSG +``` + +The `ros2 run ros_ign_bridge parameter_bridge` command simply runs the `parameter_bridge` code from the `ros_ign_bridge` package. Then, we specify our topic `/TOPIC` over which the messages will be sent. The first `@` symbol delimits the topic name from the message types. Following the first `@` symbol is the ROS message type. + +The ROS message type is followed by an `@`, `[`, or `]` symbol where: + +* `@` is a bidirectional bridge. +* `[` is a bridge from Ignition to ROS. +* `]` is a bridge from ROS to Ignition. + +Have a look at these [examples](https://github.com/ignitionrobotics/ros_ign/blob/ros2/ros_ign_bridge/README.md#example-1a-ignition-transport-talker-and-ros-2-listener) +explaining how to make communication connections from ROS to Ignition and vice versa. + +## Publish key strokes to ROS + +Let's send messages to ROS using the `Key Publisher` an Ignition plugin. + +**Note:** Make sure to have all workspaces you need (ROS, Ignition and, `ros_ign`...) sourced. + + +First we will start a bridge between ROS and Ignition specifying the topic +at which the `Key Publisher` plugin sends messages and also the type +of the messages as follows: + +``` +ros2 run ros_ign_bridge parameter_bridge /keyboard/keypress@std_msgs/msg/Int32@ignition.msgs.Int32 +``` + +We started a bridge on `/keyboard/keypress` topic with message of type `Int32`. +For ROS it is `std_msgs/msg/Int32` and for Ignition it is `ignition.msgs.Int32` + +In another terminal launch an Ignition Gazebo world, for example the `empty.sdf` world: + +``` +ign gazebo empty.sdf +``` + +Then add the `Key Publisher` plugin from the dropdown menu on the top right corner. + +![empty_world_with_KeyPublisher](tutorials/ros2_integration/empty_world.png) + +In another terminal start the ROS listener: + +``` +ros2 topic echo /keyboard/keypress +``` + +This command listens to the messages sent over the `/keyboard/keypress` topic. + +On the Ignition window, press on the keyboard keys and you should +find data on the listener terminal. This is what the terminals should look like: + +![exchange_messages](tutorials/ros2_integration/ros_ign.png) + +Now it's your turn! Try to send data from ROS to Ignition. You can also try different data types and different directions of communication. + +## Video walk-through + +A video walk-through of this tutorial is available from our YouTube channel: [Ignition tutorials: ROS 2 Foxy integration](https://youtu.be/IpZTNyTp9t8). + + diff --git a/fortress/ros_integration.md b/fortress/ros_integration.md new file mode 100644 index 0000000000..3272fc2ace --- /dev/null +++ b/fortress/ros_integration.md @@ -0,0 +1,83 @@ +# ROS Integration + +Most of the Ignition libraries use [Ignition Transport](https://github.com/ignitionrobotics/ign-transport) +to exchange data between different software components. This tutorial details +how to interface with [ROS](http://www.ros.org/), enabling the ability to use +tools such as [Rviz](http://wiki.ros.org/rviz) for robot or sensor +visualization. + +> **Important**: The packages documented here used to have the `ros1_` prefix +> instead of `ros_`. Please update your code accordingly in order to avoid +> adverse effects. + +# ros_ign_bridge to the rescue + +ros_ign_bridge provides a network bridge which enables the exchange of messages +between ROS 1 and Ignition Transport. Its support is limited to only certain +message types. Please, read this [README](https://github.com/osrf/ros_ign/blob/noetic/ros_ign_bridge/README.md) +to verify if your message type is supported by the bridge. + +# How to install ros_ign_bridge + +## Binary install + +Binaries are not yet supported for Fortress. Check out the [table on ros_ign](https://github.com/ignitionrobotics/ros_ign/tree/noetic) for other combinations. + +## Source install + +See the [from source](https://github.com/ignitionrobotics/ros_ign/tree/noetic#from-source) of the bridge documentation. This tutorial requires Ubuntu Bionic or newer. + +# Run the bridge and exchange images + +In this example, we're going to generate Ignition Transport images using Gazebo, that will be converted into ROS 1 images, and visualized with rqt_viewer. It is assumed that you are using ROS Noetic. + +First we start a ROS 1 `roscore`: + +```bash +# Shell A: +. /opt/ros/noetic/setup.bash +roscore +``` + +Then we start Gazebo. + +```bash +# Shell B: +ign gazebo -r camera_sensor.sdf +# if you don't see the camera image in the Image Display and it stays grey, press the orange refresh button +``` + +Gazebo should be running and publishing images over the `/camera` topic. +Let's verify it: + +```bash +# Shell C: +ign topic -l | grep "^/camera" +``` + +Then we start the parameter bridge with the previous topic. To run the bridge: + +```bash +# Shell D: +. /opt/ros/noetic/setup.bash +# If installed from source, make sure you've sourced the ros-ign packages too +rosrun ros_ign_bridge parameter_bridge /camera@sensor_msgs/Image@ignition.msgs.Image +``` + +Now we start the ROS 1 GUI: + +```bash +# Shell E: +. /opt/ros/noetic/setup.bash +sudo apt-get install ros-noetic-rqt-image-view +rqt_image_view /camera +``` + +You should see the current images in `rqt_image_view` which are coming from +Gazebo (published as Ignition Msgs over Ignition Transport). + +The screenshot shows all the shell windows and their expected content +(it was taken using ROS Noetic and in a Dome workspace but the expected content applies to Fortress): + + +![Ignition Transport images and ROS 1 rqt](img/bridge_image_exchange_ign-gazebo.png) diff --git a/fortress/sdf_worlds.md b/fortress/sdf_worlds.md new file mode 100644 index 0000000000..a65cf962dc --- /dev/null +++ b/fortress/sdf_worlds.md @@ -0,0 +1,290 @@ +# SDF worlds + +In this tutorial we will learn how to build our world using SDF, and how to add models to it. Open your text editor and add code as you follow along with this tutorial. You can also download the finished world for this tutorial from [here](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/sdf_worlds/world_demo.sdf). + +## Defining a world + +Every SDF world starts with these tags. + +```xml + + + + ... + ... + + +``` + +The first two tags define the version of the `XML` and the `SDF`. Then we have the ` ` tags between which everything goes. + +## Physics + +```xml + + 0.001 + 1.0 + +``` + +The physics tag specifies the type and properties of the dynamic engine. We chose the `name` `1ms` as the step size is 1 millisecond. The `type` is the type of the dynamic engine (physics library). There are options like, Ode, Bullet, Simbody and Dart. We set it to `ignored`, as choosing the type of the physics engine is not done through this tag yet. + +`` is the maximum time at which every system in simulation can interact with the states of the world. The smaller the value, the more accurate your calculations, but more computation power is needed. +`` is the ratio of simulation time to real time. + +## Plugins + +Plugins are a dynamically loaded chunk of code. For example: + +```xml + + +``` + +The `Physics` plugin is very important for simulating the dynamics of the world. + +```xml + + +``` + +The `UserCommands` plugin is responsible for creating models, moving models, deleting them and many other user commands. + +```xml + + +``` + +`SceneBroadcaster` shows our world scene. + +## GUI + +Now let's define the GUI. Under the `` tag we specify anything related to the `GUI` of Ignition. + +```xml + + ... + ... + +``` + +[ignition-gui](https://github.com/ignitionrobotics/ign-gui/) has a bunch of plugins to choose from. We will add the ones that are necessary to get our world up and running with basic functionality. + +### Scene 3D plugin + +```xml + + + + 3D View + false + docked + + + ogre2 + scene + 1.0 1.0 1.0 + 0.8 0.8 0.8 + -6 0 6 0 0.5 0 + +``` + +The `GzScene3D` plugin is responsible for displaying the 3D scene of our world. It has the following properties (most of the GUI plugins have them): + +* `showTitleBar` if true it will show the blue title bar over the plugin with the name mentioned in the `` tag. +* `state` is the state of the plugin it can be docked in its place using `docked` or it can be `floating`. + +For the rendering engine we can choose `ogre` or `ogre2`. The `<ambient_light>` and the `<background_color>` specify the ambient and the background color of the scene. `<camera_pose>` specifies the `X Y Z` position of the camera followed by its rotation in `Roll Pitch Yaw`. + +### World control plugin + +```xml +<!-- World control --> +<plugin filename="WorldControl" name="World control"> + <ignition-gui> + <title>World control + false + false + 72 + 121 + 1 + + floating + + + + + + + true + true + true + /world/world_demo/control + /world/world_demo/stats + +``` + +The `World control` plugin is responsible for controlling the world. Some of its properties are the following: + +* `` if `true` we will have the play-pause button on the bottom left corner. +* `` tag specifies the topic at which the world stats like simulation time and real time are published on. +* `` if `true` the simulation will be paused at the start of Ignition. + +### World stats plugin + +```xml + + + + World stats + false + false + 110 + 290 + 1 + + floating + + + + + + + true + true + true + true + /world/world_demo/stats + + +``` + +The `World stats` plugin is responsible for displaying the world statistics, +``, ``, `` and ``. + +With these tags we can choose what values to display (expand the bottom right corner to see these values). We can choose which `` these values will be published on. Let's try to run the world and listen to that topic. + +Run the world: + +`ign gazebo world_demo.sdf` + +Press the play button and in another terminal listen to the messages: + +`ign topic -e -t /world/world_demo/stats` + +The message should look like this: + +![world_shapes_stats](tutorials/sdf_worlds/world_stats.png) + +### Entity tree + +```xml + + + +``` + +In this plugin we can see all the entities of our world (everything in simulation is considered an "entity"). We can see the different models, sun and also their links, visuals and collisions. + +![Entity tree plugin](tutorials/sdf_worlds/entity_tree.png) + +It is blank because we didn't add anything to our world yet. + +There are a bunch of useful ignition-gui plugins like the `Transform control` plugin that allows us to manipulate different components of our world, and translate and rotate the entities. Check out this [tutorial](manipulating_models) explaining how to manipulate models. + +The plugins can also be added from the GUI using the plugin drop-down menu in the top right corner of Ignition. Now that we are done with the GUI, let's add different elements to our world. **Don't** forget to add the closing tag ``. + +## Light + +```xml + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + +``` + +* `` specifies the light source in the world. The `` of the light can be `point`, `directional` or `spot`. +* `` is the position (x,y,z) and orientation (roll, pitch, yaw) of the light element with respect to the frame mentioned in the `relative_to attribute`; in our case (`relative_to` attribute is ignored) it is relative to the world. +* `` when true the light will cast shadows. `` and `` are the diffuse and specular light color. +* `` specifies the light attenuation properties, which are: + + * `` is range of light. + * `` is the constant attenuation factor, `1` never attenuate and `0` complete attenuation. + * `` is the linear attenuation factor, `1` means attenuate evenly over the distance. + * `` is the quadratic attenuation factor. It adds curvature to the attenuation. + * `` is direction of the light, only applicable to spot and directional light. + +## Adding models + +Instead of building our own models we can use already built ones. [Ignition Fuel](https://app.ignitionrobotics.org/fuel) hosts hundreds of models that can easily be added to an Ignition world. Models can be added as follows. + +### Drag and drop the model + +Adding models to a world typically means adding them into your world sdf file, but with Fuel you can drag and drop existing models directly into the scene. Checkout this [tutorial](fuel_insert) on how to add models to your world by drag and drop. + +### Include the model URI + +Another way of adding the model to your world is to use the model link. Visit the [Ignition Fuel website](https://app.ignitionrobotics.org/fuel). Choose the model you like and click on the `<>` icon on the model description page. This will copy an SDF snippet to your clipboard, then paste it in your world right above the closing `` tag, like this: + +```xml + + + https://fuel.ignitionrobotics.org/1.0/OpenRobotics/models/Coke + + +``` + +### Download the model + +The previous methods download your model on run time. For saving the model permanently you can download the model from fuel, and then refer to it like this: + +```xml + + + model://Coke + + +``` + +We need to set `IGN_GAZEBO_RESOURCE_PATH` environment variable to the parent folder of our model. For example, if our directory looks like this: + +``` +world_tutorial
+├── Coke
+└── world_demo.sdf +``` + +Then we have to set it to the `world_tutorial` directory, like this: + +`export IGN_GAZEBO_RESOURCE_PATH="$HOME/world_tutorial"` + +Run your world: + +`ign gazebo world_demo.sdf` + +You should see the model in the origin of the world. You can also set its coordinates using the ``tag. + +![world with can](tutorials/sdf_worlds/coke_world.png) + +Now that you have a custom world, the [next tutorial](sensors) will teach you how to add sensors to a robot to allow it to interact with the world around it. + +## Video walk-through + +A video walk-through of this tutorial is available from our YouTube channel: [Ignition tutorials: Creating worlds](https://youtu.be/48TX-XJ14Gs). + + diff --git a/fortress/sensors.md b/fortress/sensors.md new file mode 100644 index 0000000000..3450497fe8 --- /dev/null +++ b/fortress/sensors.md @@ -0,0 +1,428 @@ +# Sensors + +**Note:** This tutorial is a continuation from the +[Moving the robot tutorial](moving_robot). + +In this tutorial we will learn how to add sensors to our robot and +to other models in our world. We will use three different sensors: +an IMU sensor, a Contact sensor and a Lidar sensor. We will also +learn how to launch multiple tasks with just one file using `ign_launch`. + +You can find the final world of this tutorial [here](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/sensors/sensor_tutorial.sdf) + +## IMU sensor + +The inertial measurement unit (IMU) outputs the `orientation` of our +robot in quaternions, the `angular_velocity` in the three axes (X, Y, Z), +and the `linear_acceleration` in the three axes. Let's use our +[moving_robot.sdf](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/moving_robot/moving_robot.sdf) world and modify it. Create a new file +`sensor_tutorial.sdf` and add the code from `moving_robot.sdf` to it. +To define the `IMU` sensor add this code under the `` tag: + +```xml + + +``` + +This code defines the `IMU` sensor plugin to be used in our world. +Now we can add the `IMU` sensor to our robot as follows: + +```xml + + 1 + 1 + true + imu + +``` + +The sensor is usually added to one of the links of our model; we added + it under the `chassis` link. + +Let's describe the tags: + + * `` if true the sensor will always be updated + according to the update rate. + * `` the frequency at which the sensor data is generated. + * `` if true the sensor is visualized in the GUI. + * `` name of the topic on which data is published. + +**Note:** Not all the tags are supported for all sensors yet. + +### Read data from IMU + +To read the data from the `IMU`, run the world in one terminal and press the play button: + +`ign gazebo sensor_tutorial.sdf` + +In another terminal, run: + +`ign topic -e -t /imu` + +The last command listens to the messages sent over the `/imu` topic. The IMU data are `orientation`, `angular_velocity` and `linear_acceleration` as described above. It should look like this: + +![Imu_message](tutorials/sensors/imu_msgs.png) + +Move your robot forward using the keyboard up key. You should see the sensor values changing. + +## Contact sensor + +Let's introduce a different type of sensor, the `contact` sensor. +You can guess from the name that this sensor gives indication when +it touches (contacts) something else. We will build an obstacle (wall) +and add the contact sensor to it. If the robot hits the obstacle it will +stop, preventing the robot from damaging itself. Let's first build the +obstacle as follows: + +```xml + + true + 5 0 0 0 0 0 + + + + + + 0.5 10.0 2.0 + + + + + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + + + + + + 0.5 10.0 2.0 + + + + + +``` + +It is just a simple model with one link of box shape. You can check the [Build your own robot tutorial](building_robot) to learn how to build models. + +Now run the world and make sure that the wall appears in the simulation like this: + +![wall_in_world](tutorials/sensors/sensor_wall.png) + +Let's add the contact sensor to the wall. As with the `IMU` sensor, we should first define the `Contact` sensor by adding the following code: + +```xml + + +``` + +Now we can add the `contact` sensor to the `box` link of the `wall` model: + +```xml + + + collision + + +``` + +The definition of the `` is straight forward, we just define the `name` and the `type` of the sensor. And inside the `collision` we define the box link collision name which is `collision`. + +We need also to add the `TouchPlugin` under the `wall` model as follows: + +```xml + + vehicle_blue + wall + + true + +``` + +The `TouchPlugin` will publish (send) a message when the `wall` +has been touched. The tags of the plugin are as follows: + +* `` which will be in contact with our wall, in our case `vehicle_blue`. +* `` takes the namespace of our topic, so when our robot hits the wall it will send a message to `/wall/touched` topic. + + Run the world in one terminal: + +`ign gazebo sensor_tutorial.sdf` + +In another terminal, listen to the `/wall/touched` topic: + +`ign topic -e -t /wall/touched` + +Drive your robot forward to the wall using the keyboard arrow keys. Make sure to start the simulation by hitting the play button, and enable the Key Publisher plugin as well by clicking on the plugins dropdown list (vertical ellipsis), then selecting "Key Publisher". + +When you hit the bump you should see a message `data: true` on the terminal where you ran the `ign topic -e -t /wall/touched`. + +Now we can use the `TriggeredPublisher` plugin to make our robot stop when hits the wall as follows: + +```xml + + + data: true + + + linear: {x: 0.0}, angular: {z: 0.0} + + +``` + +As explained in the [Moving robot tutorial](moving_robot), +we can publish an output depending on a received input. So when we receive +`data: true` on the `/wall/touched` topic we publish +`linear: {x: 0.0}, angular: {z: 0.0}` to make our robot stop. + +## Lidar sensor + +We don't want our robot to touch the wall at all because this may cause some damage, so instead of the contact sensor we can use the Lidar. Lidar is an acronym for "light detection and ranging". This sensor can help us detect obstacles around the robot. We will use it to measure the distance between our robot and the wall. + +First let's create a frame to fix our lidar to. This should be added inside of the `vehicle_blue` `` tag, since the lidar frame is attached to the robot's `chassis`: + +```xml + + 0.8 0 0.5 0 0 0 + +``` + +Then add this plugin under the `` tag, to be able to use the `lidar` sensor: + +```xml + + ogre2 + +``` + +Under the `chassis` link we can add the `lidar` sensor as follows: + +```xml +" + 0 0 0 0 0 0 + lidar + 10 + + + + 640 + 1 + -1.396263 + 1.396263 + + + 1 + 0.01 + 0 + 0 + + + + 0.08 + 10.0 + 0.01 + + + 1 + true + +``` + +* First we defined the `name` and `type` of our sensor, then we defined its +`` relative to the `lidar_frame`. +* In the `` we define the topic on which the lidar data will be published. +* `` is the frequency at which the `lidar` data is generated, in +our case `10 Hz` which is equal to `0.1 sec`. +* Under the `` and `` tags we define the properties of the +horizontal and vertical laser rays. +* `` is the number of simulated lidar rays to generate per complete +laser sweep cycle. +* ``: this number is multiplied by samples to determine the number +range data points. +* The `` and `` are the angle range of the generated rays. +* Under the `` we define range properties of each simulated ray + * `` and `` define the minimum and maximum distance for each lidar ray. + * The `` tag here defines the linear resolution of each lidar ray. + * ``: if true the sensor will always be updated according to the ``. + * ``: if true the sensor is visualized in the GUI. + +Now run the world and press the play button in the bottom-left corner: + +`ign gazebo sensor_tutorial.sdf` + +Look at the lidar messages on the `/lidar` topic, specifically the `ranges` data: + +`ign topic -e -t /lidar` + +The lidar message has the following attributes: + +``` +message LaserScan +{ + Header header = 1; + + string frame = 2; + Pose world_pose = 3; + double angle_min = 4; + double angle_max = 5; + double angle_step = 6; + double range_min = 7; + double range_max = 8; + uint32 count = 9; + double vertical_angle_min = 10; + double vertical_angle_max = 11; + double vertical_angle_step = 12; + uint32 vertical_count = 13; + + repeated double ranges = 14; + repeated double intensities = 15; +} +``` + +### Avoid the wall + +Now as we have the lidar on our robot, we can use the `ranges` data +and make our robot avoid hitting the wall. +To do that, we'll write a short C++ program that listens to +the sensor data and sends velocity commands to the robot. +This program is called a node. We will build a node that subscribes +to the `/lidar` topic and reads its data. +Have a look at this [tutorial](https://ignitionrobotics.org/api/transport/9.0/messages.html) +to learn how to build a `publisher` and a `subscriber` node. +You can download the finished node for this demo from [here](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/sensors/lidar_node.cc). + +#### The lidar_node + +```cpp +ignition::transport::Node node; +std::string topic_pub = "/cmd_vel"; +ignition::msgs::Twist data; +auto pub = node.Advertise(topic_pub); +``` + +We declare a `node` which will publish to `cmd_vel` topic and defined the message type `Twist`. Then advertise our node. + +```cpp +void cb(const ignition::msgs::LaserScan &_msg) +{ + bool allMore = true; + for (int i = 0; i < _msg.ranges_size(); i++) + { + if (_msg.ranges(i) < 1.0) + { + allMore = false; + break; + } + } + if (allMore) //if all bigger than one + { + data.mutable_linear()->set_x(0.5); + data.mutable_angular()->set_z(0.0); + } + else + { + data.mutable_linear()->set_x(0.0); + data.mutable_angular()->set_z(0.5); + } + pub.Publish(data); +} +``` + +Inside the callback function we check if the range of all rays are bigger than `1.0`. +If so we publish a message to our car to move forward. Otherwise we make the robot rotate. + +```cpp +int main(int argc, char **argv) +{ + std::string topic = "/lidar"; + // Subscribe to a topic by registering a callback. + if (!node.Subscribe(topic, cb)) + { + std::cerr << "Error subscribing to topic [" << topic << "]" << std::endl; + return -1; + } + + // Zzzzzz. + ignition::transport::waitForShutdown(); + + return 0; +} +``` + +Inside the main we subscribe to the `lidar` topic, and wait until the node is shut down. + +#### Build the node + +Download the [CMakeLists.txt](https://github.com/ignitionrobotics/docs/blob/master/fortress/tutorials/sensors/CMakeLists.txt), and in the same folder of `lidar_node` create `build/` directory: + +```{.sh} +mkdir build +cd build +``` + +Run cmake and build the code: + +```{.sh} +cmake .. +make lidar_node +``` + +##### Run the node + +Run the node from terminal 1: + +```{.sh} +./build/lidar_node +``` + +Run the world from terminal 2: + +```{.sh} +ign gazebo sensor_tutorial.sdf +``` + +Now you can see the robot move forward and as it approaches the wall it starts to turn left until it's clear and moves forward again (be sure to press the play button in the bottom-left corner to make the robot start moving). + +## Ignition launch + +Instead of running two different tasks from two different terminals we can make a launch file which will run the `sensor_world` and the `lidar_node` at the same time. Open your text editor and add the following code. + +```xml + + + + ign gazebo sensor_tutorial.sdf + + + + ./build/lidar_node + + + +``` + +The launch file is an XML file. We simply define what commands will run under the `` tag. +The first command is `ign gazebo sensor_tutorial.sdf` which launches the world. +And the second command is `./build/lidar_node` which runs the `lidar_node`. +Save the file as `sensor_launch.ign`, and then run it using the following command: + +```{.sh} +ign launch sensor_launch.ign +``` + +Press the play button to start the simulation. Hurray! Our robot is now moving and avoiding the wall. + +To add even more complexity to your simulation, learn how to add actors to a world in the [next tutorial](actors). + +## Video walk-through + +A video walk-through of this tutorial is available from our YouTube channel: [Ignition tutorials: Sensors](https://youtu.be/WcFyGPEfhHc) + + diff --git a/fortress/troubleshooting.md b/fortress/troubleshooting.md new file mode 100644 index 0000000000..d3da371d7c --- /dev/null +++ b/fortress/troubleshooting.md @@ -0,0 +1,186 @@ +# Troubleshooting + +## macOS + +### Unable to find `urdf_model.h` error + +After installing all the dependencies and starting the build process, you may encounter an error that looks like this: + +```bash +/Users/user/fortress_ws/src/sdformat/src/parser_urdf.cc:30:10: fatal error: 'urdf_model/model.h' file not found +#include + ^~~~~~~~~~~~~~~~~~~~ +1 error generated. +make[2]: *** [src/CMakeFiles/sdformat9.dir/parser_urdf.cc.o] Error 1 +make[1]: *** [src/CMakeFiles/sdformat9.dir/all] Error 2 +make: *** [all] Error 2 +Failed <<< sdformat9 [ Exited with code 2 ] +``` + +First check if `urdfdom` and `urdfdom_headers` are installed by running: + +```bash +brew install urdfdom urdfdom_headers +``` + +Then if the error persists, compile with the internal version of `urdfdom` by running: + +```bash +colcon build --cmake-args -DUSE_INTERNAL_URDF=ON --merge-install +``` + +This command will ignore the system installation of `urdfdom` and use the internal version instead. + +### Unable to load .dylib file + +When running the `ign gazebo -s` command, an error like the one below may show up: + +```bash +Error while loading the library [/Users/fortress/fortress_ws/install/lib//libignition-physics2-dartsim-plugin.2.dylib]: dlopen(/Users/fortress/fortress_ws/install/lib//libignition-physics2-dartsim-plugin.2.dylib, 5): Library not loaded: @rpath/libIrrXML.dylib + Referenced from: /usr/local/opt/assimp/lib/libassimp.5.dylib + Reason: image not found +[Err] [Physics.cc:275] Unable to load the /Users/fortress/fortress_ws/install/lib//libignition-physics2-dartsim-plugin.2.dylib library. +Escalating to SIGKILL on [Ignition Gazebo Server] +``` + +The issue is related to OSX System Integrity Protection(SIP). The workaround is to run `ign` with a different ruby then make sure that ruby is loaded. + +```bash +brew install ruby + +# Add the following to ~/.bashrc +export PATH=/usr/local/Cellar/ruby/2.6.5/bin:$PATH + +# Source ~/.bashrc in terminal +. ~/.bashrc +``` + +## Ignition libraries are not found + +If you see this error message: + +```bash +I cannot find any available 'ign' command: + * Did you install any ignition library? + * Did you set the IGN_CONFIG_PATH environment variable? + E.g.: export IGN_CONFIG_PATH=$HOME/local/share/ignition +``` + +You should set up the environment variable `IGN_CONFIG_PATH=/usr/local/share/ignition/` + +### No rule to make target `/usr/lib/libm.dylib', needed by `lib/libignition-physics3-dartsim-plugin.3.1.0.dylib'. Stop. + +Try to run `brew outdated` followed by a `brew upgrade` may fix some of it. + +### Unable to find `urdf_model.h` error + +After installing all the dependencies and starting the build process, you may encounter an error that looks like this: + +```bash +/Users/user/fortress_ws/src/sdformat/src/parser_urdf.cc:30:10: fatal error: 'urdf_model/model.h' file not found +#include + ^~~~~~~~~~~~~~~~~~~~ +1 error generated. +make[2]: *** [src/CMakeFiles/sdformat9.dir/parser_urdf.cc.o] Error 1 +make[1]: *** [src/CMakeFiles/sdformat9.dir/all] Error 2 +make: *** [all] Error 2 +Failed <<< sdformat9 [ Exited with code 2 ] +``` + +First check if `urdfdom` and `urdfdom_headers` are installed by running: + +```bash +brew install urdfdom urdfdom_headers +``` + +Then if the error persists, compile with the internal version of `urdfdom` by running: + +```bash +colcon build --cmake-args -DUSE_INTERNAL_URDF=ON --merge-install +``` + +This command will ignore the system installation of `urdfdom` and use the internal version instead. + +### Unable to load .dylib file + +When running the `ign gazebo -s` command, an error like the one below may show up: + +```bash +Error while loading the library [/Users/fortress/fortress_ws/install/lib//libignition-physics2-dartsim-plugin.2.dylib]: dlopen(/Users/fortress/fortress_ws/install/lib//libignition-physics2-dartsim-plugin.2.dylib, 5): Library not loaded: @rpath/libIrrXML.dylib + Referenced from: /usr/local/opt/assimp/lib/libassimp.5.dylib + Reason: image not found +[Err] [Physics.cc:275] Unable to load the /Users/fortress/fortress_ws/install/lib//libignition-physics2-dartsim-plugin.2.dylib library. +Escalating to SIGKILL on [Ignition Gazebo Server] +``` + +The issue is related to OSX System Integrity Protection(SIP). The workaround is to run `ign` with a different ruby then make sure that ruby is loaded. + +```bash +brew install ruby + +# Add the following to ~/.bashrc +export PATH=/usr/local/Cellar/ruby/2.6.5/bin:$PATH + +# Source ~/.bashrc in terminal +. ~/.bashrc +``` + +## Ubuntu + +### Unable to create the rendering window + +If you're getting errors like "Unable to create the rendering window", it could +mean you're using an old OpenGL version. Ignition Gazebo uses the Ogre 2 +rendering engine by default, which requires an OpenGL version higher than 3.3. + +This can be confirmed by checking the Ogre 2 logs at `~/.ignition/rendering/ogre2.log`, +which should have an error like: + +"OGRE EXCEPTION(3:RenderingAPIException): OpenGL 3.3 is not supported. Please update your graphics card drivers." + +You can also check your OpenGL version running: + + glxinfo | grep "OpenGL version" + +You should be able to use Ogre 1 without any issues however. You can check if +that's working by running a world which uses Ogre 1 instead of Ogre 2, such as: + + ign gazebo -v 3 lights.sdf + +If that loads, you can continue to use Ignition with Ogre 1, just use the +`--render-engine ogre` option. + +To enable Ogre 2 support, you'll need to update your computer's OpenGL version. +As suggested on the Ogre logs, this may require updating your graphics card +drivers. + +The Ogre 2 debs from the osrfoundation repository are built from a fork of +Ogre's `v2-1` branch with changes needed for deb packaging and allowing it to +be co-installable with Ogre 1.x. The code can be found here: + +https://github.com/osrf/ogre-2.1-release + +## Windows + +### VisualStudioVersion is not set, please run within a Visual Studio Command Prompt. + +When you try to compile Ignition Robotics you might see an error in your prompt like: + + VisualStudioVersion is not set, please run within a Visual Studio Command Prompt. + + - CMD +```bash + "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 +``` + + - PowerShell: +```bash +pushd "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools" +cmd /c "VsDevCmd.bat&set" | +foreach { + if ($_ -match "=") { + $v = $_.split("="); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])" + } +} +popd +``` diff --git a/fortress/tutorials.md b/fortress/tutorials.md new file mode 100644 index 0000000000..f72c98b55f --- /dev/null +++ b/fortress/tutorials.md @@ -0,0 +1,27 @@ +# Ignition Tutorials + +These tutorials cover general concepts to help get you started with Ignition. + + +## ROS integration + +* [ROS Integration](ros_integration) +* [ROS 2 Integration](ros2_integration) + +## GUI tutorials + +* [Understanding the GUI](gui) +* [Manipulating Models](manipulating_models) +* [Model Insertion from Fuel](fuel_insert) +* [Keyboard Shortcuts](hotkeys) + +## Basics tutorials + +* [Building Your Own Robot](building_robot) +* [Moving the Robot](moving_robot) +* [SDF Worlds](sdf_worlds) +* [Sensors](sensors) +* [Actors](actors) + + +More specific content correlating to each Ignition library can be found under the *API & Tutorials* sections on the [Libraries page](/libs). diff --git a/fortress/tutorials/actors/actor_demo.gif b/fortress/tutorials/actors/actor_demo.gif new file mode 100644 index 0000000000..d1692f8f1e Binary files /dev/null and b/fortress/tutorials/actors/actor_demo.gif differ diff --git a/fortress/tutorials/actors/actor_demo.sdf b/fortress/tutorials/actors/actor_demo.sdf new file mode 100644 index 0000000000..939f08d704 --- /dev/null +++ b/fortress/tutorials/actors/actor_demo.sdf @@ -0,0 +1,188 @@ + + + + + + ogre + + + + + + + + + + + 3D View + false + docked + + + ogre + scene + 0.4 0.4 0.4 + 0.8 0.8 0.8 + -6 0 6 0 0.5 0 + + + + + + World control + false + false + 72 + 121 + 1 + + floating + + + + + + + true + true + false + /world/actors/control + /world/actors/stats + + + + + + World stats + false + false + 110 + 290 + 1 + + floating + + + + + + + true + true + true + true + /world/actors/stats + + + + + + false + docked + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + true + + + + + 0.0 0.0 1 + + + + + + + 0.0 0.0 1 + 100 100 + + + + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + + + + + + + https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/walk.dae + 1.0 + + + https://fuel.ignitionrobotics.org/1.0/Mingfei/models/actor/tip/files/meshes/walk.dae + + + + + + diff --git a/fortress/tutorials/actors/actor_skin.gif b/fortress/tutorials/actors/actor_skin.gif new file mode 100644 index 0000000000..7292afe306 Binary files /dev/null and b/fortress/tutorials/actors/actor_skin.gif differ diff --git a/fortress/tutorials/actors/combined_movement.gif b/fortress/tutorials/actors/combined_movement.gif new file mode 100644 index 0000000000..50afbb6f0d Binary files /dev/null and b/fortress/tutorials/actors/combined_movement.gif differ diff --git a/fortress/tutorials/actors/skeleton_movement.gif b/fortress/tutorials/actors/skeleton_movement.gif new file mode 100644 index 0000000000..d13e07a4c6 Binary files /dev/null and b/fortress/tutorials/actors/skeleton_movement.gif differ diff --git a/fortress/tutorials/actors/trajectory_movement.gif b/fortress/tutorials/actors/trajectory_movement.gif new file mode 100644 index 0000000000..046e84120a Binary files /dev/null and b/fortress/tutorials/actors/trajectory_movement.gif differ diff --git a/fortress/tutorials/building_robot/building_robot.sdf b/fortress/tutorials/building_robot/building_robot.sdf new file mode 100644 index 0000000000..9a17329312 --- /dev/null +++ b/fortress/tutorials/building_robot/building_robot.sdf @@ -0,0 +1,249 @@ + + + + + 0.001 + 1.0 + + + + + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + true + + + + + 0 0 1 + + + + + + + 0 0 1 + 100 100 + + + + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + + + + + + 0 0 0 0 0 0 + + + + 0.5 0 0.4 0 0 0 + + 1.14395 + + 0.095329 + 0 + 0 + 0.381317 + 0 + 0.476646 + + + + + + 2.0 1.0 0.5 + + + + + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + + + + + + 2.0 1.0 0.5 + + + + + + + + -0.5 0.6 0 -1.5707 0 0 + + 1 + + 0.043333 + 0 + 0 + 0.043333 + 0 + 0.08 + + + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + + + + + -0.5 -0.6 0 -1.5707 0 0 + + 1 + + 0.043333 + 0 + 0 + 0.043333 + 0 + 0.08 + + + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + + + + + 0.8 0 -0.2 0 0 0 + + + + + + + 1 + + 0.016 + 0 + 0 + 0.016 + 0 + 0.016 + + + + + + 0.2 + + + + 0.0 1 0.0 1 + 0.0 1 0.0 1 + 0.0 1 0.0 1 + + + + + + 0.2 + + + + + + + + + chassis + left_wheel + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + + + + + + chassis + right_wheel + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + + + + + chassis + caster + + + + diff --git a/fortress/tutorials/building_robot/car_left_wheel.png b/fortress/tutorials/building_robot/car_left_wheel.png new file mode 100644 index 0000000000..f35f5a4c68 Binary files /dev/null and b/fortress/tutorials/building_robot/car_left_wheel.png differ diff --git a/fortress/tutorials/building_robot/chassis.png b/fortress/tutorials/building_robot/chassis.png new file mode 100644 index 0000000000..d1e79c4e4a Binary files /dev/null and b/fortress/tutorials/building_robot/chassis.png differ diff --git a/fortress/tutorials/building_robot/model_axis.png b/fortress/tutorials/building_robot/model_axis.png new file mode 100644 index 0000000000..41d94fea55 Binary files /dev/null and b/fortress/tutorials/building_robot/model_axis.png differ diff --git a/fortress/tutorials/building_robot/two_wheeled_robot.png b/fortress/tutorials/building_robot/two_wheeled_robot.png new file mode 100644 index 0000000000..448463da71 Binary files /dev/null and b/fortress/tutorials/building_robot/two_wheeled_robot.png differ diff --git a/fortress/tutorials/moving_robot/keypublisher_data.png b/fortress/tutorials/moving_robot/keypublisher_data.png new file mode 100644 index 0000000000..0b357dbbd7 Binary files /dev/null and b/fortress/tutorials/moving_robot/keypublisher_data.png differ diff --git a/fortress/tutorials/moving_robot/moving_robot.sdf b/fortress/tutorials/moving_robot/moving_robot.sdf new file mode 100644 index 0000000000..a99a12c96d --- /dev/null +++ b/fortress/tutorials/moving_robot/moving_robot.sdf @@ -0,0 +1,303 @@ + + + + + 0.001 + 1.0 + + + + + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + true + + + + + 0 0 1 + + + + + + + 0 0 1 + 100 100 + + + + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + + + + + + 0 0 0 0 0 0 + + + 0.5 0 0.4 0 0 0 + + 1.14395 + + 0.126164 + 0 + 0 + 0.416519 + 0 + 0.481014 + + + + + + 2.0 1.0 0.5 + + + + + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + + + + + + 2.0 1.0 0.5 + + + + + + + + -0.5 0.6 0 -1.5707 0 0 + + 2 + + [Build your own robot](SDF_tutorial_link) tutorial. You can download the robot fro 0.145833 + 0 + 0 + 0.145833 + 0 + 0.125 + + + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + + + + + -0.5 -0.6 0 -1.5707 0 0 + + 1 + + 0.145833 + 0 + 0 + 0.145833 + 0 + 0.125 + + + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + + + + 0.8 0 -0.2 0 0 0 + + + + + + + 1 + + 0.1 + 0 + 0 + 0.1 + 0 + 0.1 + + + + + + 0.2 + + + + 0.0 1 0.0 1 + 0.0 1 0.0 1 + 0.0 1 0.0 1 + + + + + + 0.2 + + + + + + + + + + chassis + left_wheel + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + + + + + chassis + right_wheel + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + + + + + chassis + caster + + + + + left_wheel_joint + right_wheel_joint + 1.2 + 0.4 + 1 + cmd_vel + + + + + + + 16777235 + + + linear: {x: 0.5}, angular: {z: 0.0} + + + + + + + 16777237 + + + linear: {x: -0.5}, angular: {z: 0.0} + + + + + + + 16777236 + + + linear: {x: 0.0}, angular: {z: -0.5} + + + + + + + 16777234 + + + linear: {x: 0.0}, angular: {z: 0.5} + + + + diff --git a/fortress/tutorials/ros2_integration/empty_world.png b/fortress/tutorials/ros2_integration/empty_world.png new file mode 100644 index 0000000000..0b48a4ef07 Binary files /dev/null and b/fortress/tutorials/ros2_integration/empty_world.png differ diff --git a/fortress/tutorials/ros2_integration/ros_ign.png b/fortress/tutorials/ros2_integration/ros_ign.png new file mode 100644 index 0000000000..e6738ff8e4 Binary files /dev/null and b/fortress/tutorials/ros2_integration/ros_ign.png differ diff --git a/fortress/tutorials/sdf_worlds/coke_world.png b/fortress/tutorials/sdf_worlds/coke_world.png new file mode 100644 index 0000000000..7ac8b9892d Binary files /dev/null and b/fortress/tutorials/sdf_worlds/coke_world.png differ diff --git a/fortress/tutorials/sdf_worlds/entity_tree.png b/fortress/tutorials/sdf_worlds/entity_tree.png new file mode 100644 index 0000000000..23a8151927 Binary files /dev/null and b/fortress/tutorials/sdf_worlds/entity_tree.png differ diff --git a/fortress/tutorials/sdf_worlds/world_demo.sdf b/fortress/tutorials/sdf_worlds/world_demo.sdf new file mode 100644 index 0000000000..3420dd8b80 --- /dev/null +++ b/fortress/tutorials/sdf_worlds/world_demo.sdf @@ -0,0 +1,114 @@ + + + + + 0.001 + 1.0 + + + + + + + + + + + + + + 3D View + false + docked + + + ogre2 + scene + 0.4 0.4 0.4 + 0.8 0.8 0.8 + -6 0 6 0 0.5 0 + + + + + + World control + false + false + 72 + 121 + 1 + + floating + + + + + + + true + true + true + /world/world_demo/control + /world/world_demo/stats + + + + + + + World stats + false + false + 110 + 290 + 1 + + floating + + + + + + + true + true + true + true + /world/world_demo/stats + + + + + + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + + https://fuel.ignitionrobotics.org/1.0/OpenRobotics/models/Coke + + + + diff --git a/fortress/tutorials/sdf_worlds/world_stats.png b/fortress/tutorials/sdf_worlds/world_stats.png new file mode 100644 index 0000000000..7dadcab368 Binary files /dev/null and b/fortress/tutorials/sdf_worlds/world_stats.png differ diff --git a/fortress/tutorials/sensors/CMakeLists.txt b/fortress/tutorials/sensors/CMakeLists.txt new file mode 100644 index 0000000000..6ef59d929c --- /dev/null +++ b/fortress/tutorials/sensors/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR) + +project(avoid_wall) + +# Find the Ignition_Transport library +find_package(ignition-transport10 QUIET REQUIRED OPTIONAL_COMPONENTS log) +set(IGN_TRANSPORT_VER ${ignition-transport10_VERSION_MAJOR}) + +include_directories(${CMAKE_BINARY_DIR}) + +if (EXISTS "${CMAKE_SOURCE_DIR}/lidar_node.cc") + add_executable(lidar_node lidar_node.cc) + target_link_libraries(lidar_node ignition-transport${IGN_TRANSPORT_VER}::core) +endif() diff --git a/fortress/tutorials/sensors/imu_msgs.png b/fortress/tutorials/sensors/imu_msgs.png new file mode 100644 index 0000000000..56663f83bf Binary files /dev/null and b/fortress/tutorials/sensors/imu_msgs.png differ diff --git a/fortress/tutorials/sensors/lidar_node.cc b/fortress/tutorials/sensors/lidar_node.cc new file mode 100644 index 0000000000..65b4544f2e --- /dev/null +++ b/fortress/tutorials/sensors/lidar_node.cc @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#include +#include +#include + + +std::string topic_pub = "/cmd_vel"; //publish to this topic +ignition::transport::Node node; +auto pub = node.Advertise(topic_pub); + +////////////////////////////////////////////////// +/// \brief Function called each time a topic update is received. +void cb(const ignition::msgs::LaserScan &_msg) +{ + ignition::msgs::Twist data; + + bool allMore = true; + for (int i = 0; i < _msg.ranges_size(); i++) + { + if (_msg.ranges(i) < 1.0) + { + allMore = false; + break; + } + } + if (allMore) //if all bigger than one + { + data.mutable_linear()->set_x(0.5); + data.mutable_angular()->set_z(0.0); + } + else + { + data.mutable_linear()->set_x(0.0); + data.mutable_angular()->set_z(0.5); + } + pub.Publish(data); +} + +////////////////////////////////////////////////// +int main(int argc, char **argv) +{ + std::string topic_sub = "/lidar"; // subscribe to this topic + // Subscribe to a topic by registering a callback. + if (!node.Subscribe(topic_sub, cb)) + { + std::cerr << "Error subscribing to topic [" << topic_sub << "]" << std::endl; + return -1; + } + + // Zzzzzz. + ignition::transport::waitForShutdown(); + + return 0; +} diff --git a/fortress/tutorials/sensors/sensor_launch.ign b/fortress/tutorials/sensors/sensor_launch.ign new file mode 100644 index 0000000000..0467a17dcd --- /dev/null +++ b/fortress/tutorials/sensors/sensor_launch.ign @@ -0,0 +1,11 @@ + + + + ign gazebo sensor_tut.sdf + + + + ./build/lidar_node + + + diff --git a/fortress/tutorials/sensors/sensor_tutorial.sdf b/fortress/tutorials/sensors/sensor_tutorial.sdf new file mode 100644 index 0000000000..c1a4a94c10 --- /dev/null +++ b/fortress/tutorials/sensors/sensor_tutorial.sdf @@ -0,0 +1,486 @@ + + + + + 0.001 + 1.0 + + + + + + + + + + + ogre2 + + + + + + + + + 3D View + false + docked + + + ogre2 + scene + 0.4 0.4 0.4 + 0.8 0.8 0.8 + + + + + + World control + false + false + 72 + 121 + 1 + + floating + + + + + + + true + true + true + /world/sensor_world/control + /world/sensor_world/stats + + + + + + World stats + false + false + 110 + 290 + 1 + + floating + + + + + + + true + true + true + true + /world/sensor_world/stats + + + + + + + + + + + + + + true + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + true + + + + + 0 0 1 + + + + + + + 0 0 1 + 100 100 + + + + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + 0.8 0.8 0.8 1 + + + + + + + 0 0 1 0 0 0 + + + 0.8 0 0.5 0 0 0 + + + + 0.5 0 0.4 0 0 0 + + 1.14395 + + 0.126164 + 0 + 0 + 0.416519 + 0 + 0.481014 + + + + + + 2.0 1.0 0.5 + + + + + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + + + + + + 2.0 1.0 0.5 + + + + + 1 + 1 + true + imu + + " + 0 0 0 0 0 0 + lidar + 10 + + + + 640 + 1 + -1.396263 + 1.396263 + + + 1 + 0.01 + 0 + 0 + + + + 0.08 + 10.0 + 0.01 + + + 1 + true + + + + + + -0.5 0.6 0 -1.5707 0 0 + + 2 + + [Build your own robot](SDF_tutorial_link) tutorial. You can download the robot fro 0.145833 + 0 + 0 + 0.145833 + 0 + 0.125 + + + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + + + + + -0.5 -0.6 0 -1.5707 0 0 + + 1 + + 0.145833 + 0 + 0 + 0.145833 + 0 + 0.125 + + + + + + 0.4 + 0.2 + + + + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + 1.0 0.0 0.0 1 + + + + + + 0.4 + 0.2 + + + + + + + 0.8 0 -0.2 0 0 0 + + + + + + + 1 + + 0.1 + 0 + 0 + 0.1 + 0 + 0.1 + + + + + + 0.2 + + + + 0.0 1 0.0 1 + 0.0 1 0.0 1 + 0.0 1 0.0 1 + + + + + + 0.2 + + + + + + + + + chassis + left_wheel + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + + + + + chassis + right_wheel + + 0 1 0 + + -1.79769e+308 + 1.79769e+308 + + + + + + + chassis + caster + + + + + left_wheel_joint + right_wheel_joint + 1.2 + 0.4 + 1 + cmd_vel + + + + + + true + 5 0 0 0 0 0 + + + + 1.14395 + + 9.532917 + 0 + 0 + 0.023832 + 0 + 9.556749 + + + + + + 0.5 10.0 2.0 + + + + + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + 0.0 0.0 1.0 1 + + + + + + 0.5 10.0 2.0 + + + + + + collision + + + + + vehicle_blue + wall + + true + + + + + + + 16777235 + + + linear: {x: 0.5}, angular: {z: 0.0} + + + + + + + 16777237 + + + linear: {x: -0.5}, angular: {z: 0.0} + + + + + + + 16777236 + + + linear: {x: 0.0}, angular: {z: -0.5} + + + + + + + 16777234 + + + linear: {x: 0.0}, angular: {z: 0.5} + + + + + + + data: true + + + linear: {x: 0.0}, angular: {z: 0.0} + + + + diff --git a/fortress/tutorials/sensors/sensor_wall.png b/fortress/tutorials/sensors/sensor_wall.png new file mode 100644 index 0000000000..95b07c4b51 Binary files /dev/null and b/fortress/tutorials/sensors/sensor_wall.png differ