    * [ Collections ](/collections)
  * [ Pricing ](/pricing)
Search or jump to...
#  Search code, repositories, users, issues, pull requests...
Search
Clear
[ Search syntax tips ](https://docs.github.com/search-github/github-code-
search/understanding-github-code-search-syntax)
#  Provide feedback
We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel  Submit feedback
#  Saved searches
##  Use saved searches to filter your results more quickly
Name
Query
To see all available qualifiers, see our [ documentation
](https://docs.github.com/search-github/github-code-search/understanding-
github-code-search-syntax) .
Cancel  Create saved search
[ Sign in ](/login?return_to=https%3A%2F%2Fgithub.com%2Fros-
controls%2Fros2_control%2Fpull%2F709)
[ Sign up
](/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-
name%3E%2F%3Crepo-
name%3E%2Fvoltron%2Fpull_requests_fragments%2Fpull_request_layout&source=header-
repo&source_repo=ros-controls%2Fros2_control)
You signed in with another tab or window. [ Reload ]() to refresh your
session.  You signed out in another tab or window. [ Reload ]() to refresh
your session.  You switched accounts on another tab or window. [ Reload ]() to
refresh your session.  Dismiss alert
{{ message }}
[ ros-controls ](/ros-controls) /  **[ ros2_control ](/ros-
controls/ros2_control) ** Public
  * [ Notifications ](/login?return_to=%2Fros-controls%2Fros2_control)
  * [ Fork  252  ](/login?return_to=%2Fros-controls%2Fros2_control)
  * [ Star  391  ](/login?return_to=%2Fros-controls%2Fros2_control)
  * [ Code  ](/ros-controls/ros2_control)
  * [ Issues  130  ](/ros-controls/ros2_control/issues)
  * [ Pull requests  25  ](/ros-controls/ros2_control/pulls)


First main modification is the **group** tag, where we define a **namespace
(mrm)** for our robot processes. Everything inside this tag inherits the
namespace. It’s necessary for the controller plugin.


####  Table of Contents


The rest of the names and elements are currently ignored.


Currently, only the [ ros_control ](/ros_control) project uses this
transmission elements. Developing an updated transmission format that is
extensible to all use cases was complicated endeavor that can be reviewed [
here ](https://github.com/ros-simulation/gazebo_ros_pkgs/issues/52) .


####  ROS 2 Documentation


The transmission has the following elements:


We do this for both joints we have left (in this simplified version of the
robot).


ROS for Industrial Robots


This site uses Akismet to reduce spam. [ Learn how your comment data is
processed ](https://akismet.com/privacy/) .


##  RRBot Example


[ ![](/custom/images/brought_by_horiz.png) ](https://www.openrobotics.org/)


[ ![Masterclass 2023 batch2 blog
banner](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![Masterclass 2023 batch2 blog banner](https://www.theconstruct.ai/wp-
content/uploads/2023/12/Batch-1-2024-OFFICIAL.jpeg) ](https://bit.ly/47Tbj3Z)


roslaunch rrbot_control rrbot_control.launch


####  30/08/2019


Add the 'Dynamic Reconfigure' plugin to RQT and click 'Expand All' to see the
sub-options. Assuming your controller uses PID, you should use a "pid" option.
Clicking on it should reveal 5 sliders that let you tune the controller, as
pictured in the following screenshot. Adjust these values until you get the
desired performance of your controller.


##  About ros_control


##  Create a ros_controls package


    <transmission name="${prefix}wrist_2_trans">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${prefix}wrist_2_joint">
        <hardwareInterface>PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="${prefix}wrist_2_motor">
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>

    <transmission name="${prefix}wrist_3_trans">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${prefix}wrist_3_joint">
        <hardwareInterface>PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="${prefix}wrist_3_motor">
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>


#  Wiki


Just simple as below, append to the end of the file, just before the **
</robot> ** :


Under "Global Options" change your "Fixed Frame" to "world" to resolve any
errors it might be giving you.


[ info@theconstruct.ai ](mailto:info@theconstruct.ai)


An explanation of variables:


**The Construct** is an e-learning platform for ROS and Robotics, helping
engineers grow their robotics skills with a full-scale curriculum and hands-on
courses.


Simulating a robot's controllers in Gazebo can be accomplished using
ros_control and a simple Gazebo plugin adapter. An overview of the
relationship between simulation, hardware, controllers and transmissions is
shown below:


Now, let’s modify our **launch file** .


#  Page


  * i - the RQT variable for time
  * rate - the frequency that this expression is evaluated. This should be the same number as in the rate column of the topic publisher. Recommended value is 100.
  * speed - how quick you want the join to actuate. Start off with just 1 for a slow speed
  * upper_limit and lower_limits - the joint limits of the hardware being controlled by this controller
  * diff = (upper_limit - lower_limit)/2
  * offset = upper_limit-diff


URDF for Robot Modeling


##  Step 1 – Simplifying the robot


The final line starts a robot_state_publisher node that simply listens to
/joint_states messages from the joint_state_controller then publishes the
transforms to /tf. This allows you to see your simulated robot in Rviz as well
as do other tasks.


Start RQT:


![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](https://www.theconstruct.ai/wp-content/uploads/2023/11/White-outline-The-
Construct-logo-slogan-2023.png)


Next thing, we need some **transmissions** elements in our robot model.


In addition to the transmission tags, a Gazebo plugin needs to be added to
your URDF that actually parses the transmission tags and loads the appropriate
hardware interfaces and controller manager. By default the gazebo_ros_control
plugin is very simple, though it is also extensible via an additional plugin
architecture to allow power users to create their own custom robot hardware
interfaces between ros_control and Gazebo.


Wiki: urdf/XML/Transmission (last edited 2017-02-02 14:58:56 by  [
JuliusGelsvartas ](/JuliusGelsvartas "JuliusGelsvartas @
158.129.11.5\[158.129.11.5\]") )


Name


    * ** <hardwareInterface> ** (optional) (one or more occurrences)
      * Specifies a supported joint-space [ hardware interface ](/ros_control#Hardware_Interfaces) . Note that ** <hardwareInterface> ** tag should only be specified here for ROS releases prior to Indigo. The correct place to specify this tag is in ** <joint> ** tag. More details about this can be found [ here ](https://github.com/ros-controls/ros_control/issues/164) .


  * Immutable Page
  * Comments
  * [ Info ](/action/info/urdf/XML/Transmission?action=info)
  * [ Attachments ](/action/AttachFile/urdf/XML/Transmission?action=AttachFile)
  * More Actions:  Raw Text  Print View  Render as Docbook  Delete Cache  \------------------------  Check Spelling  Like Pages  Local Site Map  \------------------------  Rename Page  Copy Page  Delete Page  \------------------------  My Pages  Subscribe User  \------------------------  Remove Spam  Revert to this revision  Package Pages  Sync Pages  \------------------------  CreatePdfDocument  Load  RawFile  Save  SlideShow


Your email address will not be published.


[ ![ROS Industrial robots Course Cover - ROS Online Courses - Robot Ignite
Academy](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![ROS Industrial robots Course Cover - ROS Online Courses - Robot Ignite
Academy](https://www.theconstruct.ai/wp-content/uploads/2019/01/ROS-
Industrial-robots-Course-Cover-ROS-Online-Courses-Robot-Ignite-Academy.jpg)
](https://www.theconstruct.ai/construct-learn-develop-robots-using-
ros/robotigniteacademy_learnros/ros-courses-library/ros-industrial-101/)


  * ` <joint name=""> ` \- the name must correspond to a joint else where in your URDF
  * ` <type> ` \- the type of transmission. Currently only "transmission_interface/SimpleTransmission" is implemented. (feel free to add more)
  * ` <hardwareInterface> ` \- within the ` <actuator> ` and ` <joint> ` tags, this tells the gazebo_ros_control plugin what hardware interface to load (position, velocity or effort interfaces). Currently only effort interfaces are implemented. (feel free to add more)


You can use that as a template for doing this with your own robot.


Remote Real Robots


Save my name, email, and website in this browser for the next time I comment.


You must have the robot like:


Forum


Share This


**CMakeLists.txt**


  * 🎉  1 reaction
[ ![@bmagyar](https://avatars.githubusercontent.com/u/3524577?s=40&v=4)
](/bmagyar)
` [ Make URDF available to HW components on initialize ](/ros-
controls/ros2_control/pull/709/commits/45ffceebb1c4519730b317b0edb3024584899af2
"Make URDF available to HW components on initialize") `
` [ 45ffcee ](/ros-
controls/ros2_control/pull/709/commits/45ffceebb1c4519730b317b0edb3024584899af2)
`
[ ![@github-actions](https://avatars.githubusercontent.com/in/15368?s=40&v=4)
](/apps/github-actions) [ github-actions ](/apps/github-actions) bot
requested review from [ anfemosa  ](/anfemosa) , [ aprotyas  ](/aprotyas) , [
destogl  ](/destogl) , [ jackcenter  ](/jackcenter) , [ kasiceo  ](/kasiceo)
and [ Serafadam  ](/Serafadam) April 22, 2022 08:40
[
![@bmagyar](https://avatars.githubusercontent.com/u/3524577?s=40&u=8f938d2dcacdcbb54f3977d6356cef945a6eb6ed&v=4)
](/bmagyar) [ bmagyar ](/bmagyar) changed the title ~~Make URDF available to
HW components on initialize~~ Make URDF available to HW components on
initialize #abi-breaking  Apr 22, 2022
[ ![destogl](https://avatars.githubusercontent.com/u/1918204?s=60&v=4)
](/destogl)
**[ destogl ](/destogl) ** approved these changes  Apr 22, 2022
[ View reviewed changes  ](/ros-
controls/ros2_control/pull/709/files/45ffceebb1c4519730b317b0edb3024584899af2)
Copy link
Member
###
![@destogl](https://avatars.githubusercontent.com/u/1918204?s=48&v=4) **[
destogl ](/destogl) ** left a comment
There was a problem hiding this comment.
###  Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. [ Learn more
](https://docs.github.com/articles/managing-disruptive-comments/#hiding-a-
comment) .
Choose a reason  Spam  Abuse  Off Topic  Outdated  Duplicate  Resolved  Hide
comment
Looking good! Nice and clean without API breaking.
Sorry, something went wrong.
All reactions
[ ![aprotyas](https://avatars.githubusercontent.com/u/34530011?s=60&v=4)


  * [ Distributions ](/Distributions)
  * [ ROS/Installation ](/ROS/Installation)
  * [ ROS/Tutorials ](/ROS/Tutorials)
  * [ RecentChanges ](/RecentChanges)
  * [ urdf/XML/Transmission ](/urdf/XML/Transmission)


    user:~$ rostopic list
    /clock
    /gazebo/link_states
    /gazebo/model_states
    /gazebo/parameter_descriptions
    /gazebo/parameter_updates
    /gazebo/set_link_state
    /gazebo/set_model_state
    /mrm/joint1_position_controller/command
    /mrm/joint1_position_controller/pid/parameter_descriptions
    /mrm/joint1_position_controller/pid/parameter_updates
    /mrm/joint1_position_controller/state
    /mrm/joint2_position_controller/command
    /mrm/joint2_position_controller/pid/parameter_descriptions
    /mrm/joint2_position_controller/pid/parameter_updates
    /mrm/joint2_position_controller/state
    /mrm/joint_states
    /rosout
    /rosout_agg


               mass="57.906"
               ixx="12.679" ixy="0" ixz="0"
               iyy="12.679" iyz="0"
               izz="0.651"
               radius="0.15" length="0.8" />

    <!--
      <m_joint name="${link_02_name}__${link_03_name}" type="revolute"
               axis_xyz="0 1 0"
               origin_rpy="0 0 0" origin_xyz="0 0 0.8"
               parent="${link_02_name}" child="${link_03_name}" />

      <m_link_cylinder name="${link_03_name}"
               origin_rpy="0 0 0" origin_xyz="0 0 0.4"
               mass="57.906"
               ixx="12.679" ixy="0" ixz="0"
               iyy="12.679" iyz="0"
               izz="0.651"
               radius="0.15" length="0.8" />

      <m_joint name="${link_03_name}__${link_04_name}" type="revolute"
               axis_xyz="0 1 0"
               origin_rpy="0 0 0" origin_xyz="0 0 0.8"
               parent="${link_03_name}" child="${link_04_name}" />

      <m_link_cylinder name="${link_04_name}"
               origin_rpy="0 0 0" origin_xyz="0 0 0.4"
               mass="57.906"
               ixx="12.679" ixy="0" ixz="0"
               iyy="12.679" iyz="0"
               izz="0.651"
               radius="0.15" length="0.8" />

      <m_joint name="${link_04_name}__${link_05_name}" type="revolute"
               axis_xyz="0 0 1"
               origin_rpy="0 0 0" origin_xyz="0 0 0.8"
               parent="${link_04_name}" child="${link_05_name}" />

      <m_link_cylinder name="${link_05_name}"
               origin_rpy="0 0 0" origin_xyz="0 0 0.125"


  * [ __ ](http://twitter.com/share?text=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers&url=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&via=_TheConstruct_)
  * [ __ ](http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&title=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers)
  * [ __ ](http://www.reddit.com/submit?url=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&title=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers)
  * [ __ ](http://www.facebook.com/sharer.php?u=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&t=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers)
  * [ __ ](https://mail.google.com/mail/u/0/?view=cm&fs=1&su=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers&body=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&ui=2&tf=1)
  * __


##  [ How to Become a Robotics Developer ](https://www.theconstruct.ai/become-
robotics-developer/)


###  Create a .yaml config file


[ ![130. The Open Source Robotics
Alliance](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![130. The Open Source Robotics Alliance](https://www.theconstruct.ai/wp-
content/uploads/2024/04/ros_developers_podcast_the_open_source_robotics_alliance_with_ryan_gariepy.jpeg)
](https://www.theconstruct.ai/130-the-open-source-robotics-alliance/)


The PID gains and controller settings must be saved in a yaml file that gets
loaded to the param server via the roslaunch file. In the config folder of
your ` MYROBOT\_control ` package, adapt the following RRBot example to your
robot as ` MYROBOT_control/config/rrbot_control.yaml ` :


        <type>transmission_interface/SimpleTransmission</type>
        <joint name="${link_01_name}__${link_02_name}">
            <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
        </joint>
        <actuator name="motor_${link_01_name}__${link_02_name}">
            <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
            <mechanicalReduction>1</mechanicalReduction>
        </actuator>
      </transmission>

      <m_link_cylinder name="${link_02_name}"
               origin_rpy="0 0 0" origin_xyz="0 0 0.4"
               mass="57.906"
               ixx="12.679" ixy="0" ixz="0"
               iyy="12.679" iyz="0"
               izz="0.651"
               radius="0.15" length="0.8" />


  * [ __ Twitter  ](http://twitter.com/share?text=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers&url=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&via=_TheConstruct_)
  * [ __ LinkedIn  ](http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&title=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers)
  * [ __ reddit  ](http://www.reddit.com/submit?url=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&title=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers)
  * [ __ Facebook  ](http://www.facebook.com/sharer.php?u=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&t=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers)
  * [ __ Gmail  ](https://mail.google.com/mail/u/0/?view=cm&fs=1&su=My%20Robotic%20Manipulator%20%2304%3A%20URDF%2FTransmission%20%2B%20Gazebo%20Controllers&body=https%3A%2F%2Fwww.theconstruct.ai%2Fmy-robotic-manipulator-04-urdf-transmission-gazebo-controllers%2F&ui=2&tf=1)
  * __


##  Related courses


    <transmission name="${prefix}shoulder_pan_trans">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${prefix}shoulder_pan_joint">
        <hardwareInterface>PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="${prefix}shoulder_pan_motor">
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>

    <transmission name="${prefix}shoulder_lift_trans">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${prefix}shoulder_lift_joint">
        <hardwareInterface>PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="${prefix}shoulder_lift_motor">
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>

    <transmission name="${prefix}elbow_trans">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${prefix}elbow_joint">
        <hardwareInterface>PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="${prefix}elbow_motor">
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>

    <transmission name="${prefix}wrist_1_trans">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${prefix}wrist_1_joint">
        <hardwareInterface>PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="${prefix}wrist_1_motor">
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>


Toggle navigation  [
![gazebo](/assets/masthead-0bd44817978df8069f427d8ca1657998789065a2b242edfd1a3d8ab4a329dd4c.png)
](/)


We encourage you to read an overview of the documentation on [ ros_control
](http://ros.org/wiki/ros_control) before proceeding.


Learn about ROS message and service calls that are available for use with
Gazebo in the tutorial [ ROS Communication with Gazebo
](/tutorials/?tut=ros_comm) .


###  <transmission> Attributes


Next, expand the topic so that you see the "data" row. In the expression
column, on the data row, try different radian values between joint1's joint
limits - in RRBot's case there are no limits because the joints are
continuous, so any value works. You should be able to get the RRBot to swing
around if you are doing this tutorial with that robot.


And in the **package.xml** file, make sure you have the following
instructions:


must change the existing code in this line in order to create a valid
suggestion.  Outdated suggestions cannot be applied.  This suggestion has been
applied or marked resolved.  Suggestions cannot be applied from pending
reviews.  Suggestions cannot be applied on multi-line comments.  Suggestions
cannot be applied while the pull request is queued to merge.  Suggestion
cannot be applied right now. Please check back later.
##  Footer
[ ](https://github.com "GitHub") © 2024 GitHub, Inc.
###  Footer navigation
  * [ Terms ](https://docs.github.com/site-policy/github-terms/github-terms-of-service)
  * [ Privacy ](https://docs.github.com/site-policy/privacy-policies/github-privacy-statement)
  * [ Security ](/security)
  * [ Status ](https://www.githubstatus.com/)
  * [ Docs ](https://docs.github.com/)
  * [ Contact ](https://support.github.com?tags=dotcom-footer)
  * Manage cookies
  * Do not share my personal information
You can’t perform that action at this time.


Add a Plot plugin to RQT and add the same topic as the one you chose above for
the topic publisher:


Create a roslaunch file for starting the ros_control controllers. Within the
launch folder create a ` MYROBOT_control/launch/MYROBOT_control.launch ` file
and adapt the following RRBot example to your robot:


    <gazebo>
      <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
        <robotNamespace>/rrbot</robotNamespace>
      </plugin>
    </gazebo>


We'll next need to create a configuration file and launch file for our
ros_control controllers that interface with Gazebo.


    mkdir ~/catkin_ws
    cd ~/catkin_ws
    catkin_create_pkg MYROBOT_control controller_manager joint_state_controller robot_state_publisher
    cd MYROBOT_control
    mkdir config
    mkdir launch


![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](https://secure.gravatar.com/avatar/ec37b84582dbbc8e32a2781670415df9?s=96&d=identicon&r=g)


Great! Now we have already configured the controllers, you can spawn the robot
again! Same commands as before, but this time you will notice the last link
won’t fall down! This is very important to achieve since the controllers are
already actuating.


Robotics Developer Masterclass 2024


What are we describing there?


[ ![How to Become a Robotics
Developer](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![How to Become a Robotics Developer](https://www.theconstruct.ai/wp-
content/uploads/2023/08/robotics-developer-photo.jpeg)
](https://www.theconstruct.ai/become-robotics-developer/)


##  URDF Transmissions


[ ![Robot-creation-URDF Course Cover - ROS Online Courses - Robot Ignite
Academy](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![Robot-creation-URDF Course Cover - ROS Online Courses - Robot Ignite
Academy](https://www.theconstruct.ai/wp-content/uploads/2019/01/Robot-
creation-URDF-Course-Cover-ROS-Online-Courses-Robot-Ignite-Academy.jpg)
](https://www.theconstruct.ai/construct-learn-develop-robots-using-
ros/robotigniteacademy_learnros/ros-courses-library/urdf-ros-robot-modeling/)


      <m_link_box name="${link_00_name}"
               origin_rpy="0 0 0" origin_xyz="0 0 0"
               mass="1024"
               ixx="170.667" ixy="0" ixz="0"
               iyy="170.667" iyz="0"
               izz="170.667"
               size="1 1 1" />

      <m_joint name="${link_00_name}__${link_01_name}" type="revolute"
               axis_xyz="0 0 1"
               origin_rpy="0 0 0" origin_xyz="0 0 0.5"
               parent="${link_00_name}" child="${link_01_name}" />

      <transmission name="trans_${link_00_name}__${link_01_name}">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="${link_00_name}__${link_01_name}">
            <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
        </joint>
        <actuator name="motor_${link_00_name}__${link_01_name}">
            <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
            <mechanicalReduction>1</mechanicalReduction>
        </actuator>
      </transmission>

      <m_link_cylinder name="${link_01_name}"
               origin_rpy="0 0 0" origin_xyz="0 0 0.2"
               mass="157.633"
               ixx="13.235" ixy="0" ixz="0"
               iyy="13.235" iyz="0"
               izz="9.655"
               length="0.4" radius="0.35" />

      <m_joint name="${link_01_name}__${link_02_name}" type="revolute"
               axis_xyz="0 1 0"
               origin_rpy="0 0 0" origin_xyz="0 0 0.4"
               parent="${link_01_name}" child="${link_02_name}" />

      <transmission name="trans_${link_01_name}__${link_02_name}">


Start the controllers:


sin(i/rate*speed)*diff + offset


##  Start the controllers using roslaunch


You'll also see the gazebo_ros_control plugin in ` rrbot.gazebo ` that reads
in all the ` <transmission> ` tags:


###  Development Notes


In this section we'll go over tools to help you visualize the performance of
your controller and tune any gains/parameters the controller might have,
particularly PID gains. We'll be using [ RQT ](http://www.ros.org/wiki/rqt) ,
ROS's plugin-based user interface, so be sure you first have that installed.


PROGRAMS


The first line, "rosparam", loads the controller settings to the parameter
server by loading a yaml configuration file (discussed in the next section).


[ « Older Entries ](https://www.theconstruct.ai/my-robotic-
manipulator-04-urdf-transmission-gazebo-controllers/page/2/?et_blog)


The transmission element has one attribute:


</robot>


Start the RRBot simulation:


ROS Developers Podcast


© 2024 The Construct Sim, S.L. All rights reserved.


In order to do that, let’s create a new file:
**~/simulation_ws/src/mrm_description/config/joints.yaml**


Apr 15, 2024


Comment


The gazebo_ros_control ` <plugin> ` tag also has the following optional child
elements:


rosservice call /rrbot/controller_manager/switch_controller "{start_controllers: [], stop_controllers: ['joint1_position_controller','joint2_position_controller'], strictness: 2}"


  * hardware_interface::JointStateInterface
  * hardware_interface::EffortJointInterface
  * hardware_interface::VelocityJointInterface - _not fully implemented_


These plugins must inherit gazebo_ros_control::RobotHWSim which implements a
simulated ros_control hardware_interface::RobotHW. RobotHWSim provides API-
level access to read and command joint properties in the Gazebo simulator.


Blog


  * **name** (required)
    * Specifies the unique name of a transmission


** WARNING ** : This documentation is for Gazebo-classic, which has been
superseded by Gazebo. [ Click here to see the documentation for the latest
Gazebo release ](https://gazebosim.org/docs)


[ ![ROS Manipulation Course Cover - ROS Online Courses - Robot Ignite
Academy](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![ROS Manipulation Course Cover - ROS Online Courses - Robot Ignite
Academy](https://www.theconstruct.ai/wp-content/uploads/2019/01/ROS-
Manipulation-Course-Cover-ROS-Online-Courses-Robot-Ignite-Academy.jpg)
](https://www.theconstruct.ai/construct-learn-develop-robots-using-
ros/robotigniteacademy_learnros/ros-courses-library/ros-manipulation-
in-5-days/)


Skip to content
Toggle navigation
[ ](https://github.com/)
[ Sign in ](/login?return_to=https%3A%2F%2Fgithub.com%2Fros-
controls%2Fros2_control%2Fpull%2F709)
  * Product
    * [ Actions  Automate any workflow  ](/features/actions)
    * [ Packages  Host and manage packages  ](/features/packages)
    * [ Security  Find and fix vulnerabilities  ](/features/security)
    * [ Codespaces  Instant dev environments  ](/features/codespaces)
    * [ Copilot  Write better code with AI  ](/features/copilot)
    * [ Code review  Manage code changes  ](/features/code-review)
    * [ Issues  Plan and track work  ](/features/issues)
    * [ Discussions  Collaborate outside of code  ](/features/discussions)
Explore
    * [ All features ](/features)
    * [ Documentation  ](https://docs.github.com)
    * [ GitHub Skills  ](https://skills.github.com/)
    * [ Blog  ](https://github.blog)
  * Solutions
For
    * [ Enterprise ](/enterprise)
    * [ Teams ](/team)
    * [ Startups ](/enterprise/startups)
    * [ Education  ](https://education.github.com)
By Solution
    * [ CI/CD & Automation ](/solutions/ci-cd/)
    * [ DevOps ](/solutions/devops/)
    * [ DevSecOps  ](https://resources.github.com/devops/fundamentals/devsecops/)
Resources
    * [ Learning Pathways  ](https://resources.github.com/learn/pathways/)
    * [ White papers, Ebooks, Webinars  ](https://resources.github.com/)
    * [ Customer Stories ](/customer-stories)
    * [ Partners  ](https://partner.github.com/)
  * Open Source
    * [ GitHub Sponsors  Fund open source developers  ](/sponsors)
    * [ The ReadME Project  GitHub community articles  ](/readme)
Repositories
    * [ Topics ](/topics)
    * [ Trending ](/trending)


    find_package(catkin REQUIRED COMPONENTS
      urdf
      controller_manager
      joint_state_controller
      robot_state_publisher
    )


###  Using service calls manually


##  Step 2 – Adding gazebo controller dependencies


  * ** <type> ** (one occurrence)
    * Specifies the transmission type.


Finally, a new **node** to run the controller process.


    <?xml version="1.0" encoding="UTF-8"?>
    <launch>
        <group ns="/mrm">

            <!-- Robot model -->
            <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mrm_description)/urdf/mrm.xacro'" />
            <arg name="x" default="0" />
            <arg name="y" default="0" />
            <arg name="z" default="0.5" />

            <!-- Spawn the robot model -->
            <node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen"
                args="-urdf -param robot_description -model mrm -x $(arg x) -y $(arg y) -z $(arg z)" />

            <!-- Load controllers -->
            <rosparam command="load" file="$(find mrm_description)/config/joints.yaml" />

            <node name="controller_spawner" pkg="controller_manager" type="spawner"
                  respawn="false" output="screen" ns="/mrm"
                  args="--namespace=/mrm
                  joint_state_controller
                  joint1_position_controller
                  joint2_position_controller
                  --timeout 60">
            </node>
        </group>
    </launch>


Contents


    # Publish all joint states -----------------------------------
    joint_state_controller:
      type: joint_state_controller/JointStateController
      publish_rate: 50

    # Position Controllers ---------------------------------------
    joint1_position_controller:
      type: effort_controllers/JointPositionController
      joint: base_link__link_01
      pid: {p: 2000.0, i: 100, d: 500.0}
    joint2_position_controller:
      type: effort_controllers/JointPositionController
      joint: link_01__link_02
      pid: {p: 50000.0, i: 100, d: 2000.0}


For Campus


The default behavior provides the following ros_control interfaces:


It goes like that:


[
![](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![](https://www.theconstruct.ai/wp-content/uploads/2023/07/robotics-developer-
masterclass-logo.png) ](https://www.theconstruct.ai/robotics-
developer/?utm_source=direct&utm_medium=wp_footer_masterlogo)


#  User


#  My Robotic Manipulator #04: URDF/Transmission + Gazebo Controllers


Open-RMF Training


](/aprotyas)
**[ aprotyas ](/aprotyas) ** approved these changes  Apr 22, 2022
[ View reviewed changes  ](/ros-
controls/ros2_control/pull/709/files/45ffceebb1c4519730b317b0edb3024584899af2)
[ ![anfemosa](https://avatars.githubusercontent.com/u/22676337?s=60&v=4)
](/anfemosa)
**[ anfemosa ](/anfemosa) ** approved these changes  Apr 23, 2022
[ View reviewed changes  ](/ros-
controls/ros2_control/pull/709/files/45ffceebb1c4519730b317b0edb3024584899af2)
Copy link
###
![@anfemosa](https://avatars.githubusercontent.com/u/22676337?s=48&v=4) **[
anfemosa ](/anfemosa) ** left a comment
There was a problem hiding this comment.
###  Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. [ Learn more
](https://docs.github.com/articles/managing-disruptive-comments/#hiding-a-
comment) .
Choose a reason  Spam  Abuse  Off Topic  Outdated  Duplicate  Resolved  Hide
comment
lgfm
Sorry, something went wrong.
All reactions
[
![@bmagyar](https://avatars.githubusercontent.com/u/3524577?s=40&u=8f938d2dcacdcbb54f3977d6356cef945a6eb6ed&v=4)
](/bmagyar) [ bmagyar ](/bmagyar) merged commit [ ` 5363e3a ` ](/ros-
controls/ros2_control/commit/5363e3a248e5fc6379e44cd50d6fe59cc05514a3) into
ros-controls  :  master  [ Apr 27, 2022  ](https://github.com/ros-
controls/ros2_control/pull/709#event-6508329511)
[ Sign up for free ](/join?source=comment-repo) **to join this conversation on
GitHub** . Already have an account? [ Sign in to comment
](/login?return_to=https%3A%2F%2Fgithub.com%2Fros-
controls%2Fros2_control%2Fpull%2F709)
Reviewers
[ ![@destogl](https://avatars.githubusercontent.com/u/1918204?s=40&v=4)
](/destogl) [ destogl  ](/destogl) [ ](/ros-
controls/ros2_control/pull/709/files/45ffceebb1c4519730b317b0edb3024584899af2)
destogl approved these changes
[ ![@anfemosa](https://avatars.githubusercontent.com/u/22676337?s=40&v=4)
](/anfemosa) [ anfemosa  ](/anfemosa) [ ](/ros-


ROS2 Training


###  Pin It on Pinterest


ROS Developers Open Classes


In this tutorial we will setup simulated controllers to actuate the joints of
your robot. This will allow us to provide the correct ROS interfaces for
planners like [ MoveIt! ](http://moveit.ros.org) . We will be using the [
ros_control ](http://ros.org/wiki/ros_control) packages, a new standard in ROS
for controller interfaces.


We need to modify two of our package files, in order to include the
dependencies. They are:


The gazebo_ros_control Gazebo plugin also provides a pluginlib-based interface
to implement custom interfaces between Gazebo and ros_control for simulating
more complex mechanisms (nonlinear springs, linkages, etc).


Make sure you have already installed ros_control, ros_controllers, and their
dependencies as described in the [ installation instructions
](/tutorials?tut=ros_installing&cat=connect_ros) .


Test the RRBot controlled by ros_control by running the following:


Click the green add button. You should now see a sine wave being plotted on
the screen.


  * ** <joint> ** (one or more occurrences)
    * A joint the transmission is connected to. The joint is specified by its **name** attribute, and the following sub-elements:


You can notice we have added a new element with the **transmission** tag.


ROS Jobs


###  Advanced: custom gazebo_ros_control Simulation Plugins


####  Explanation


(+34) 687 672 123


ROS Awards 2023


Start an empty world simulation and launch the robot from a web shell:


Assuming you are already starting a joint_state_controller as documented above
in your rosparam and roslaunch files, your next step is to start Rviz:


The example code used for the RRBot in this tutorial is available in the
repository [ gazebo_ros_demos ](https://github.com/ros-
simulation/gazebo_ros_demos) .


Except where otherwise noted, the ROS wiki is licensed under the
[ Creative Commons Attribution 3.0
](http://creativecommons.org/licenses/by/3.0/)


See you in the next post!


  * [ Courses ](https://www.theconstruct.ai/robotigniteacademy_learnros/ros-courses-library/)
  * [ Live Training ](https://www.theconstruct.ai/instructor-led-training/)
  * [ For Campus ](https://www.theconstruct.ai/for-campus/)
  * [ For Enterprise ](https://www.theconstruct.ai/for-enterprise/)


##  Use RQT To Send Commands


      <transmission name="tran1">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="joint1">
          <hardwareInterface>EffortJointInterface</hardwareInterface>
        </joint>
        <actuator name="motor1">
          <hardwareInterface>EffortJointInterface</hardwareInterface>
          <mechanicalReduction>1</mechanicalReduction>
        </actuator>
      </transmission>

      <transmission name="tran2">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="joint2">
          <hardwareInterface>EffortJointInterface</hardwareInterface>
        </joint>
        <actuator name="motor2">
          <hardwareInterface>EffortJointInterface</hardwareInterface>
          <mechanicalReduction>1</mechanicalReduction>
        </actuator>
      </transmission>


Send example joint commands to them for testing:


[ read more ](https://www.theconstruct.ai/speed-up-data-processing-with-multi-
threaded-execution-english-ros2-tutorial/)


roslaunch mrm_description spawn.launch


      <build_depend>urdf</build_depend>
      <build_depend>controller_manager</build_depend>
      <build_depend>joint_state_controller</build_depend>
      <build_depend>robot_state_publisher</build_depend>

      <build_export_depend>urdf</build_export_depend>
      <build_export_depend>controller_manager</build_export_depend>
      <build_export_depend>joint_state_controller</build_export_depend>
      <build_export_depend>robot_state_publisher</build_export_depend>

      <exec_depend>urdf</exec_depend>
      <exec_depend>controller_manager</exec_depend>
      <exec_depend>joint_state_controller</exec_depend>
      <exec_depend>robot_state_publisher</exec_depend>


rostopic pub -1 /mrm/joint2_position_controller/command std_msgs/Float64 "data: 0.7"


Add another topic to the Plot plugin that tracks the actual position of the
actuator being controlled. You will want to the reduce the error between these
two values by tuning the PID gains, as shown in the next step. For the RRBot:


    * ** <hardwareInterface> ** (one or more occurrences)
      * Specifies a supported joint-space [ hardware interface ](/ros_control#Hardware_Interfaces) . Note that the value of this tag should be **[ EffortJointInterface ](/EffortJointInterface) ** when this transmission is loaded in Gazebo and **hardware_interface/EffortJointInterface** when this transmission is loaded in RobotHW.


If you first load the rrbot_control.yaml files to the parameter server, you
could load the controllers manually through service requests. We'll include
them here for reference though we usually prefer roslaunch:


[ ![Google+](/assets/google_gray-
cc34826f560f99c7a9b7db88cd5f2db4d28fd4b3afcfa4b897435c51e3b25518.png)
](//plus.google.com/u/0/115981436296571800301?prsrc=3) [
![YouTube](/assets/youtube_gray-978838444154eb6aa5e4aa38489f66d10e40361dd06a3814411c211cba013752.png)
](https://www.youtube.com/channel/UCJyqf9XJpDoM9XnpAwW6WxA) [
![YouTube](/assets/twitter_gray-8e9dfe74c6cab12171992a40add9a65e5bba92ac93063a4ac0eeba58c77e774a.png)
](https://twitter.com/GazeboSim)


Then, the **joint** we are referencing with the transmission.


SUPPORT


  * [ Actions  ](/ros-controls/ros2_control/actions)
  * [ Projects  0  ](/ros-controls/ros2_control/projects)
  * [ Security  ](/ros-controls/ros2_control/security)
  * [ Insights  ](/ros-controls/ros2_control/pulse)
Additional navigation options
  * [ Code  ](/ros-controls/ros2_control)
  * [ Issues  ](/ros-controls/ros2_control/issues)
  * [ Pull requests  ](/ros-controls/ros2_control/pulls)
  * [ Actions  ](/ros-controls/ros2_control/actions)
  * [ Projects  ](/ros-controls/ros2_control/projects)
  * [ Security  ](/ros-controls/ros2_control/security)
  * [ Insights  ](/ros-controls/ros2_control/pulse)
New issue
**Have a question about this project?** Sign up for a free GitHub account to
open an issue and contact its maintainers and the community.
Pick a username

Email Address

Password

Sign up for GitHub
By clicking “Sign up for GitHub”, you agree to our [ terms of service
](https://docs.github.com/terms) and [ privacy statement
](https://docs.github.com/privacy) . We’ll occasionally send you account
related emails.
Already on GitHub? [ Sign in ](/login?return_to=%2Fros-
controls%2Fros2_control%2Fissues%2Fnew%2Fchoose) to your account
Jump to bottom
#  Make URDF available to HW components on initialize #abi-breaking  #709
Merged
[ bmagyar ](/bmagyar) merged 1 commit into  [ ros-controls  :  master  ](/ros-
controls/ros2_control/tree/master "ros-controls/ros2_control:master") from  [
bmagyar  :  make-original-urdf-available-to-hw-components
](/bmagyar/ros2_control/tree/make-original-urdf-available-to-hw-components
"bmagyar/ros2_control:make-original-urdf-available-to-hw-components") Apr 27,
2022
Merged
#  Make URDF available to HW components on initialize #abi-breaking  #709
[ bmagyar ](/bmagyar) merged 1 commit into  [ ros-controls  :  master  ](/ros-


Next, add a "RobotModel" display type to Rviz and you should then see your
simulated robot in Gazebo being visualized in Rviz!


[ Terms of Use ](https://www.theconstruct.ai/terms_and_conditions/)


Check the shell, you can see the controllers being loaded in the logs!


Hey ROS developers! In this post, we will make our robot able to be spawned
into Gazebo simulator. Based on the [ YouTube video series
](https://www.youtube.com/watch?v=Ale55LcdZeE&list=PLK0b4e05LnzYpDnNeWJcQLju7JfJFX-
lk) , we’ll show in this format the steps to achieve the final result of the
series!


roslaunch rrbot_gazebo rrbot_world.launch


##  Step 3 – Adding transmissions to the robot model


    rostopic pub -1 /rrbot/joint1_position_controller/command std_msgs/Float64 "data: 1.5"
    rostopic pub -1 /rrbot/joint2_position_controller/command std_msgs/Float64 "data: 1.0"


#  ROS control


##  Step 4 – Setup gazebo controllers on URDF model


In this post number #4, I’m gonna create the **Transmissions and controllers**
to some of our joints using the same XACROs files we have been working with.
Up to the end of the post, we’ll have part of our model controllers by gazebo
controllers!


###  Add a Command Publisher


    * ** <mechanicalReduction> ** (optional)
      * Specifies a mechanical reduction at the joint/actuator transmission. This tag may not be needed for all transmissions.


Then, in the secion **Load controllers** we have a new parameter, that loads
the **config.yml** file we have just created.


RESOURCES


Then tuning each one of the transmissions we have defined in our model. We
need again the **name** , **type** , **joint name** and the **PID** values


####  Written by [ Marco Arruda
](https://www.theconstruct.ai/author/2020-05-08%2012:36:47.059182/)


[ Edit
](https://github.com/osrf/gazebo_tutorials/blob/master/ros_control/tutorial.md)
Version: 1.9+


  * [ Follow  ](https://twitter.com/_theconstruct_ "Follow on Twitter")
  * [ Follow  ](https://www.facebook.com/theconstructsim "Follow on Facebook")
  * [ Follow  ](https://www.linkedin.com/company/the-construct/mycompany/ "Follow on LinkedIn")
  * [ Follow  ](https://youtube.com/@TheConstruct "Follow on Youtube")


By default, without a ` <robotSimType> ` tag, gazebo_ros_control will attempt
to get all of the information it needs to interface with a ros_control-based
controller out of the URDF. This is sufficient for most cases, and good for at
least getting started.


  * ** <actuator> ** (one or more occurrences)
    * An actuator the transmission is connected to. The actuator is specified by its **name** attribute, and the following sub-elements:


Next, in that same expression box we'll have it automatically change values
using a sine wave. Add the following:


#  Prerequisites


Apr 8, 2024


##  Add the gazebo_ros_control plugin


Select Page


First, we have a **transmission for each joint** . Then we define the **type**
of the transmission, which in this case is just a **SimpleTransmission.**


Submit Comment


##  Step 8 – Conclusion


    <gazebo>
      <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
        <robotNamespace>/MYROBOT</robotNamespace>
        <robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
      </plugin>
    </gazebo>


###  <transmission> Elements


Note: the RQT plot plugin is known to have bugs after running for a while
(>1min). The drawings start acting strangely. The current solution is to press
the blue refresh button at the top right of the plugin.


Updated: July 26, 2023 Robotics needs developers! Robotics needs software
engineers and software...


#  Tutorial: ROS Control


In the command **find_package** , let’s add some new values:


##  Manually send example commands


ROS Manipulation


###  Create new package


Topics: [ Robotic Manipulator ](https://www.theconstruct.ai/tag/robotic-
manipulator/) | [ ros-industrial ](https://www.theconstruct.ai/tag/ros-
industrial/)


       1 <transmission name="simple_trans">
       2   <type>transmission_interface/SimpleTransmission</type>
       3   <joint name="foo_joint">
       4     <hardwareInterface>EffortJointInterface</hardwareInterface>
       5   </joint>
       6   <actuator name="foo_motor">
       7     <mechanicalReduction>50</mechanicalReduction>
       8     <hardwareInterface>EffortJointInterface</hardwareInterface>
       9   </actuator>
      10 </transmission>


the construct


In order to put it back to the original position, execute the command below:


Become a ROS Instructor


##  Connect Rviz to Gazebo Simulation


##  Data flow of ros_control and Gazebo


###  Default gazebo_ros_control Behavior


###  Check Out These Related Posts


Still on the same file, let’s add to the end of the description the **tags**
related to **gazebo controller plugin** .


Gazebo is open-source licensed under [ Apache 2.0
](http://www.apache.org/licenses/LICENSE-2.0.html)


Then press the green plus sign button at the top right.


As a final test, let’s send a reference to the second joint:


  * ` <robotNamespace> ` : The ROS namespace to be used for this instance of the plugin, defaults to robot name in URDF/SDF
  * ` <controlPeriod> ` : The period of the controller update (in seconds), defaults to Gazebo's period
  * ` <robotParam> ` : The location of the robot_description (URDF) on the parameter server, defaults to '/robot_description'
  * ` <robotSimType> ` : The pluginlib name of a custom robot sim interface to be used (see below for more details), defaults to 'DefaultRobotHWSim'


This is something necessary for the gazebo controller, we must define some
control variables (PID) to apply to our transmissions.


It turns out we have a very complex robot, with 6 links and 5 joints. I want
to make it simpler in order to show how to use gazebo controller plugin.


[ read more ](https://www.theconstruct.ai/become-robotics-developer/)


Here is an example of a transmission element:


Website


May 26, 2018


![URDF/Transmission + Gazebo
Controllers](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
![URDF/Transmission + Gazebo Controllers](https://www.theconstruct.ai/wp-
content/uploads/2019/08/URDFTransmission-Gazebo-Controllers.png)


    rrbot:
      # Publish all joint states -----------------------------------
      joint_state_controller:
        type: joint_state_controller/JointStateController
        publish_rate: 50

      # Position Controllers ---------------------------------------
      joint1_position_controller:
        type: effort_controllers/JointPositionController
        joint: joint1
        pid: {p: 100.0, i: 0.01, d: 10.0}
      joint2_position_controller:
        type: effort_controllers/JointPositionController
        joint: joint2
        pid: {p: 100.0, i: 0.01, d: 10.0}


#  0 Comments


controls/ros2_control/pull/709/files/45ffceebb1c4519730b317b0edb3024584899af2)
anfemosa approved these changes
[ ![@aprotyas](https://avatars.githubusercontent.com/u/34530011?s=40&v=4)
](/aprotyas) [ aprotyas  ](/aprotyas) [ ](/ros-
controls/ros2_control/pull/709/files/45ffceebb1c4519730b317b0edb3024584899af2)
aprotyas approved these changes
[ ![@jackcenter](https://avatars.githubusercontent.com/u/23001861?s=40&v=4)
](/jackcenter) [ jackcenter  ](/jackcenter) Awaiting requested review from
jackcenter
[ ![@kasiceo](https://avatars.githubusercontent.com/u/87803506?s=40&v=4)
](/kasiceo) [ kasiceo  ](/kasiceo) Awaiting requested review from kasiceo
[ ![@Serafadam](https://avatars.githubusercontent.com/u/11968712?s=40&v=4)
](/Serafadam) [ Serafadam  ](/Serafadam) Awaiting requested review from
Serafadam
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
None yet
4 participants
[ ![@bmagyar](https://avatars.githubusercontent.com/u/3524577?s=52&v=4)
](/bmagyar) [
![@destogl](https://avatars.githubusercontent.com/u/1918204?s=52&v=4)
](/destogl) [
![@anfemosa](https://avatars.githubusercontent.com/u/22676337?s=52&v=4)
](/anfemosa) [
![@aprotyas](https://avatars.githubusercontent.com/u/34530011?s=52&v=4)
](/aprotyas)
Add this suggestion to a batch that can be applied as a single commit.  This
suggestion is invalid because no changes were made to the code.  Suggestions
cannot be applied while the pull request is closed.  Suggestions cannot be
applied while viewing a subset of changes.  Only one suggestion per line can
be applied in a batch.  Add this suggestion to a batch that can be applied as
a single commit.  Applying suggestions on deleted lines is not supported.  You


Finally, we'll use [ dynamic reconfigure
](http://ros.org/wiki/dynamic_reconfigure) to tune the proportional,
derivative, and integral gains of the PID controller, assuming this is
applicable to your robot.


##  [ Speed Up Data Processing with Multi-Threaded Execution
](https://www.theconstruct.ai/speed-up-data-processing-with-multi-threaded-
execution-english-ros2-tutorial/)


It goes like:


To use ros_control with your robot, you need to add some additional elements
to your URDF. The ` <transmission> ` element is used to link actuators to
joints, see the [ ` <transmission> ` spec
](http://ros.org/wiki/urdf/XML/Transmission) for exact XML format.


  1. URDF Transmissions
    1. <transmission> Attributes
    2. <transmission> Elements
    3. Development Notes


               mass="18.056"
               ixx="0.479" ixy="0" ixz="0"
               iyy="0.479" iyz="0"
               izz="0.204"
               radius="0.15" length="0.25" />
    -->
      <!-- END - Robot description -->

    </robot>


Let’s start opening the file **mrm.xacro** and comment leave only the first
links of the robot (the rest, we will comment). It will look like below:


  * [ Tutorials ](/tutorials)
  * [ Download ](/download)
  * [ Blog ](/blog.html)
  * [ Media ](/media)
  * [ Projects ](/projects)


    <gazebo>
        <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
        </plugin>
    </gazebo>


    <launch>

      <!-- Load joint controller configurations from YAML file to parameter server -->
      <rosparam file="$(find rrbot_control)/config/rrbot_control.yaml" command="load"/>

      <!-- load the controllers -->
      <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
        output="screen" ns="/rrbot" args="joint1_position_controller joint2_position_controller joint_state_controller"/>

      <!-- convert joint states to TF transforms for rviz, etc -->
      <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
        respawn="false" output="screen">
        <remap from="/joint_states" to="/rrbot/joint_states" />
      </node>

    </launch>


The Construct is the official ROS training provider for


    <gazebo>
      <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
        <robotNamespace>/MYROBOT</robotNamespace>
      </plugin>
    </gazebo>


Further, the **actuator type** , which is an **Effort Joint Interface** , in
this case. And the **mechanical reduction** .


###  Visualize the controller's performance


The ROS Wiki is for ROS 1. Are you using ROS 2 ( [ Humble
](http://docs.ros.org/en/humble/) , [ Iron ](http://docs.ros.org/en/iron/) ,
or [ Rolling ](http://docs.ros.org/en/rolling/) )?
[ Check out the ROS 2 Project Documentation ](http://docs.ros.org)
Package specific documentation can be found on [ index.ros.org
](https://index.ros.org)


©2014 Open Source Robotics Foundation


Email


Load the controllers for the two joints by running the second launch file:


Stop the controllers:


Rosbotics Ambassador


rosrun rqt_gui rqt_gui


For Enterprise


<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">


We add a ` <transmission> ` block similar to the following for every joint
that we wish to have Gazebo actuate. Note that the ` <hardwareInterface> `
must be included in both the ` <joint> ` and ` <actuator> ` tags (see [
ros_control issue here ](https://github.com/ros-
controls/ros_control/issues/177) ). Open your ` rrbot.xacro ` file and at the
bottom of the file you should see:


Your screen should look something like this:


##  Step 5 – Describe controller YAML file


controls/ros2_control/tree/master "ros-controls/ros2_control:master") from  [
bmagyar  :  make-original-urdf-available-to-hw-components
](/bmagyar/ros2_control/tree/make-original-urdf-available-to-hw-components
"bmagyar/ros2_control:make-original-urdf-available-to-hw-components") Apr 27,
2022
+9  −2
[ Conversation  2  ](/ros-controls/ros2_control/pull/709) [ Commits  1
](/ros-controls/ros2_control/pull/709/commits) [ Checks  0  ](/ros-
controls/ros2_control/pull/709/checks) [ Files changed  2  ](/ros-
controls/ros2_control/pull/709/files)
##  Conversation
This file contains bidirectional Unicode text that may be interpreted or
compiled differently than what appears below. To review, open the file in an
editor that reveals hidden Unicode characters. [ Learn more about
bidirectional Unicode characters ](https://github.co/hiddenchars)
[ Show hidden characters ]({{ revealButtonHref }})
[ ![bmagyar](https://avatars.githubusercontent.com/u/3524577?s=60&v=4)
](/bmagyar)
Copy link
Member
###
![@bmagyar](https://avatars.githubusercontent.com/u/3524577?s=48&v=4) **[
bmagyar ](/bmagyar) ** commented  Apr 22, 2022  •
edited
Motivation:
Some hardware components require access to more XML components than what is
parsed.
Some hardware components require access to the URDF for setting limits, etc.
This PR solves both cases, now if you need to get this information, you can do
it by doing your own parsing inside the component.
This information is handed to each hardware component here: [
https://github.com/ros-
controls/ros2_control/blob/master/hardware_interface/include/hardware_interface/system.hpp#L44
](https://github.com/ros-
controls/ros2_control/blob/master/hardware_interface/include/hardware_interface/system.hpp#L44)
Sorry, something went wrong.
👍  1  PeterMitrano reacted with thumbs up emoji  🎉  1  PeterMitrano reacted
with hooray emoji
All reactions
  * 👍  1 reaction


Load the controllers:


The transmission element is an extension to the [ URDF ](/urdf/XML) robot
description model that is used to describe the relationship between an
actuator and a joint. This allows one to model concepts such as gear ratios
and parallel linkages. A transmission transforms efforts/flow variables such
that their product - power - remains constant. Multiple actuators may be
linked to multiple joints through complex transmission.


[ Privacy Policy ](https://www.theconstruct.ai/privacy_policy/) [
](https://www.theconstruct.ai/privacy_policy/)


In the [ ROS 2 tutorial for writing a simple pub/sub package
](https://index.ros.org/doc/ros2/Tutorials/Writing-A-Simple-Cpp-Publisher-And-
Subscriber/#add-dependencies) , it says to add the following in the
package.xml file:


These six types of dependencies are specified using the following respective
tags:


![](images/qvboxlayout-with-5-children.png)


    <package>
      <name>foo_core</name>
      <version>1.2.4</version>
      <description>
        This package provides foo capability.
      </description>
      <maintainer email="ivana@willowgarage.com">Ivana Bildbotz</maintainer>
      <license>BSD</license>

      <url>http://ros.org/wiki/foo_core</url>
      <author>Ivana Bildbotz</author>

      <buildtool_depend>catkin</buildtool_depend>

      <build_depend>message_generation</build_depend>
      <build_depend>roscpp</build_depend>
      <build_depend>std_msgs</build_depend>

      <run_depend>message_runtime</run_depend>
      <run_depend>roscpp</run_depend>
      <run_depend>rospy</run_depend>
      <run_depend>std_msgs</run_depend>

      <test_depend>python-mock</test_depend>
    </package>


sendvel() publishes the current velocity values to a ROS topic. Internally
this is connected to a timer which calls it 10 times per second.

    void sendVel();

updateTopic() reads the topic name from the QLineEdit and calls setTopic()
with the result.

    void updateTopic();

Then we finish up with protected member variables.

    protected:

The control-area widget which turns mouse events into command velocities.

    DriveWidget* drive_widget_;

One-line text editor for entering the outgoing ROS topic name.

    QLineEdit* output_topic_editor_;

The current name of the output topic.


[ QBoxLayout ](qboxlayout.html)


####  ROS 2 Documentation


Call [ QWidget::updateGeometry ](qwidget.html#updateGeometry) () whenever the
size hint, minimum size hint or size policy changes. This will cause a layout
recalculation. Multiple consecutive calls to [ QWidget::updateGeometry
](qwidget.html#updateGeometry) () will only cause one layout recalculation.


Call [ QWidget::updateGeometry ](qwidget.html#updateGeometry) () whenever the
size hint, minimum size hint or size policy changes. This will cause a layout
recalculation. Multiple calls to updateGeometry() will only cause one
recalculation.


* A [ QHBox ](qhbox.html) lays out its child widgets in a horizontal row, left to right.


In certain cases the parent layout is put into [ QLayout::FreeResize
](qlayout.html#SizeConstraint-enum) mode, meaning that it will not adapt the
layout of its contents to fit inside small sized windows, or even prevent the
user from making the window too small to be usable. This can be overcome by
subclassing the problematic widgets, and implementing suitable [ sizeHint()
](qwidget.html#sizeHint-prop) and [ minimumSizeHint()
](qwidget.html#minimumSizeHint-prop) functions.


The easiest way to give your widgets a good layout is to use the layout
widgets: [ QHBox ](qhbox.html) , [ QVBox ](qvbox.html) and [ QGrid
](qgrid.html) . A layout widget automatically lays out its child widgets in
the order they are constructed. To create more complex layouts, you can nest
layout widgets inside each other.


![](images/qhboxlayout-with-5-children.png)


Each package.xml file has the ` <package> ` tag as the root tag in the
document.


* **Build Tool Dependencies** specify build system tools which this package needs to build itself. Typically the only build tool needed is catkin. In a cross-compilation scenario build tool dependencies are for the architecture on which the compilation is performed.


If the preferred height of your widget depends on its actual width (e.g. a
label with automatic word-breaking), set the [ hasHeightForWidth
](qsizepolicy.html#hasHeightForWidth) () flag in [ sizePolicy
](qwidget.html#sizePolicy) (), and reimplement [ QWidget::heightForWidth
](qwidget.html#heightForWidth) ().


  Building the Plugin  Â¶

To build the plugin, just do the normal “rosmake” thing:

    rosmake rviz_plugin_tutorials


* [ Login ](/action/login/catkin/package.xml?action=login)


[ about ](/about/) |  [ faq ](/faq/) |  [ help ](/help/ "help") |  [ privacy
policy ](/privacy/) |  [ terms of service ](/terms/)


[ **answered 2020-03-25 11:14:23 -0500  ** ](/answers/347531/revisions/)


    void DriveWidget::mouseReleaseEvent( QMouseEvent* event )
    {
      stop();
    }

Compute and emit linear and angular velocities based on Y and X mouse
positions relative to the central square.

    void DriveWidget::sendVelocitiesFromMouse( int x, int y, int width, int height )
    {
      int size = (( width > height ) ? height : width );
      int hpad = ( width - size ) / 2;
      int vpad = ( height - size ) / 2;

      linear_velocity_ = (1.0 - float( y - vpad ) / float( size / 2 )) * linear_scale_;
      angular_velocity_ = (1.0 - float( x - hpad ) / float( size / 2 )) * angular_scale_;
      Q_EMIT outputVelocity( linear_velocity_, angular_velocity_ );

update() is a QWidget function which schedules this widget to be repainted the
next time through the main event loop. We need this because the velocities
have just changed, so the arrows need to be redrawn to match.

      update();
    }

How to stop: emit velocities of 0!

    void DriveWidget::stop()
    {
      linear_velocity_ = 0;
      angular_velocity_ = 0;


###  The Header File ( ` card.h ` )


Sort by »  [ oldest  ](/question/347516/difference-in-build_depend-in-package-
format-3-vs-package-format-2/?sort=oldest#sort-top) [ newest
](/question/347516/difference-in-build_depend-in-package-format-3-vs-package-
format-2/?sort=latest#sort-top) [ most voted  ](/question/347516/difference-
in-build_depend-in-package-format-3-vs-package-format-2/?sort=votes#sort-top)


* ` <build_export_depend> `


Semantic of ` build_depend ` did not change between package format 2 and
format 3.


As an example, here is package manifest for a fictional package called
_foo_core_ .


* ` <name> ` \- The name of the package


  1. All the widgets will initially be allocated an amount of space in accordance with their [ QWidget::sizePolicy ](qwidget.html#sizePolicy-prop) () and [ QWidget::sizeHint ](qwidget.html#sizeHint-prop) ().
  2. If any of the widgets have stretch factors set, with a value greater than zero, then they are allocated space in proportion to their stretch factor (explained below).
  3. If any of the widgets have stretch factors set to zero they will only get more space if no other widgets want the space. Of these, space is allocated to widgets with an [ Expanding ](qsizepolicy.html#Policy-enum) size policy first.
  4. Any widgets that are allocated less space than their minimum size (or minimum size hint if no minimum size is specified) are allocated this minimum size they require. (Widgets don't have to have a minimum size or minimum size hint in which case the strech factor is their determining factor.)
  5. Any widgets that are allocated more space than their maximum size are allocated the maximum size space they require. (Widgets do not have to have a maximum size in which case the strech factor is their determining factor.)


    {
      angle += delta_angle / 2;
      float next_cx = cx + step_dist * cosf( angle );
      float next_cy = cy - step_dist * sinf( angle );
      angle += delta_angle / 2;

      left_track[ step ].setX( next_cx + half_track_width * cosf( angle + M_PI/2 ));
      left_track[ step ].setY( next_cy - half_track_width * sinf( angle + M_PI/2 ));
      right_track[ step ].setX( next_cx + half_track_width * cosf( angle - M_PI/2 ));
      right_track[ step ].setY( next_cy - half_track_width * sinf( angle - M_PI/2 ));

      cx = next_cx;
      cy = next_cy;
    }

Now the track arrays are filled, so stroke each with a fat green line.

    painter.drawPolyline( left_track, step_count );
    painter.drawPolyline( right_track, step_count );

Here we decide which direction each arrowhead will point (forward or
backward). This works by comparing the arc length travelled by the center in
one step (step_dist) with the arc length travelled by the wheel
(half_track_width * delta_angle).

    int left_arrow_dir = (-step_dist + half_track_width * delta_angle > 0);
    int right_arrow_dir = (-step_dist - half_track_width * delta_angle > 0);

Use MiterJoin for the arrowheads so we get a nice sharp point.

    arrow.setJoinStyle( Qt::MiterJoin );


When you make your own widget class, you should also communicate its layout
properties. If the widget has a one of Qt's layouts, this is already taken
care of. If the widget does not have any child widgets, or uses manual layout,
you can change the behavior of the widget using any or all of the following
mechanisms:


The use of rich text in a label widget can introduce some problems to the
layout of its parent widget. Problems occur due to the way rich text is
handled by Qt's layout managers when the label is word wrapped.


    <package format="2">

    </package>


**Note:** Widgets in a layout are children of the widget on which the layout
is installed, _not_ of the layout itself. Widgets can only have other widgets
as parent, not layouts.


###  Contents


* **Build Dependencies** specify which packages are needed to build this package. This is the case when any file from these packages is required at build time. This can be including headers from these packages at compilation time, linking against libraries from these packages or requiring any other resource at build time (especially when these packages are _find_package()_ -ed in CMake). In a cross-compilation scenario build dependencies are for the targeted architecture.


  Next Steps  Â¶

This Teleop panel might be useful as it is, since it already sends out command
velocities appropriate for a diff-drive robot. However, there are a few things
which might make it more useful:

  * Adjustable scaling of the linear and angular velocities.
  * Enforced maxima for the velocities.
  * An adjustable robot width parameter, so that the curved arrows accurately show the arc a robot would traverse.
  * A “strafe” mode (maybe when holding down the Shift key) for robots like the PR2 with (more) holonomic drive ability.


Close


    void TeleopPanel::setTopic( const QString& new_topic )
    {

Only take action if the name has changed.

    if( new_topic != output_topic_ )
    {
      output_topic_ = new_topic;

If the topic is the empty string, don’t publish anything.

    if( output_topic_ == "" )
    {
      velocity_publisher_.shutdown();
    }
    else
    {

The old ` velocity_publisher_  ` is destroyed by this assignment, and thus the
old topic advertisement is removed. The call to nh_advertise() says we want to
publish data on the new topic name.

      velocity_publisher_ = nh_.advertise<geometry_msgs::Twist>( output_topic_.toStdString(), 1 );
    }

rviz::Panel defines the configChanged() signal. Emitting it tells RViz that
something in this panel has changed that will affect a saved config file.
Ultimately this signal can cause QWidget::setWindowModified(true) to be called


All [ QWidget ](qwidget.html) subclasses can use layouts to manage their
children. The [ QWidget::setLayout ](qwidget.html#setLayout) () function
applies a layout to a widget. When a layout is set on a widget in this way, it
takes charge of the following tasks:


[ Wrong constructor in ROS2 ](/question/330243/wrong-constructor-in-ros2/)


Except where otherwise noted, the ROS wiki is licensed under the
[ Creative Commons Attribution 3.0
](http://creativecommons.org/licenses/by/3.0/)


##  Comments


All packages have at least one dependency, a build tool dependency on catkin
as the following example shows.


[ Widgets and Layouts ](widgets-and-layouts.html) [ Styles ](style-
reference.html)


[ ROS2 Bag - DB3 CDR Deserialization ](/question/346934/ros2-bag-db3-cdr-
deserialization/)


###  Additional Tags


Copyright © 2003 [ Trolltech ](http://www.trolltech.com/) |  [ Trademarks
](http://www.trolltech.com/trademarks.html) |


#  User


When you add widgets to a layout, the layout process works as follows:


* ` <license> ` \- The software license(s) (e.g. GPL, BSD, ASL) under which the code is released.


##  Layout Widgets


Aren't rclcpp and std_msgs required at build time?


edit


##  Custom Widgets In Layouts


* A [ QHBoxLayout ](qhboxlayout.html) lays out widgets in a horizontal row, from left to right (or right to left for right-to-left languages).


When you use a layout, you must insert each child both into its parent widget
(done in the constructor) and into its layout (typically done with a function
called addWidget()). This way, you can give layout parameters for each widget,
specifying properties like alignment, stretch, and placement.


[ Home ](index.html)


As an example, here is package manifest for a fictional package called
_foo_core_ .


[ ![Jeffrey Kane Johnson gravatar
image](/upfiles/avatars/Jeffrey%20Kane%20Johnson/resized/32/headshot-200x200.jpg)
](/users/2517/jeffrey-kane-johnson/)


If you are making a one-of-a-kind special layout, you can also make a custom
widget as described above. Reimplement [ QWidget::resizeEvent
](qwidget.html#resizeEvent) () to calculate the required distribution of sizes
and call [ setGeometry ](qwidget.html#setGeometry) () on each child.


A more realistic example that specifies build, exec, test, and doc
dependencies could look as follows.


Abstract item that a QLayout manipulates

[ QSizePolicy ](qsizepolicy.html)


[ ![ gravatar image]() ]() [ ]() (  2024-04-18 17:53:56 -0500  )  edit


* **Execution Dependencies** specify which packages are needed to run code in this package. This is the case when you depend on shared libraries in this package (especially when these packages are declared as (CATKIN_)DEPENDS in _catkin_package()_ in CMake).


* **Build Tool Dependencies** specify build system tools which this package needs to build itself. Typically the only build tool needed is catkin. In a cross-compilation scenario build tool dependencies are for the architecture on which the compilation is performed.


If we have three widgets laid out using a [ QHBox ](qhbox.html) with no
stretch factors set we will get a layout like this:


* **Run Dependencies** specify which packages are needed to run code in this package, or build libraries against this package. This is the case when you depend on shared libraries or transitively include their headers in public headers in this package (especially when these packages are declared as (CATKIN_)DEPENDS in _catkin_package()_ in CMake).


[ ALL ](/questions/scope:all/sort:activity-desc/page:1/) [ UNANSWERED
](/questions/scope:unanswered/sort:answers-asc/page:1/)


        [QWidget](qwidget.html) *main = new [QWidget](qwidget.html);

        // make a 1x1 grid; it will auto-expand
        [QGridLayout](qgridlayout.html) *grid = new [QGridLayout](qgridlayout.html)( main, 1, 1 );

        // add the first four widgets with (row, column) addressing
        grid->[addWidget](qgridlayout.html#addWidget)( new [QLabel](qlabel.html)( "One", main ),   0, 0 );
        grid->[addWidget](qgridlayout.html#addWidget)( new [QLabel](qlabel.html)( "Two", main ),   0, 1 );
        grid->[addWidget](qgridlayout.html#addWidget)( new [QLabel](qlabel.html)( "Three", main ), 1, 0 );
        grid->[addWidget](qgridlayout.html#addWidget)( new [QLabel](qlabel.html)( "Four", main ),  1, 1 );

        // add the last widget on row 2, spanning from column 0 to
        // column 1, and center aligned
        grid->[addMultiCellWidget](qgridlayout.html#addMultiCellWidget)( new [QLabel](qlabel.html)( "Five", main ), 2, 2, 0, 1,
                                  Qt::AlignCenter );

        // let the ratio between the widths of columns 0 and 1 be 2:3
        grid->[setColStretch](qgridlayout.html#setColStretch)( 0, 2 );
        grid->[setColStretch](qgridlayout.html#setColStretch)( 1, 3 );


More details on dependencies can be found [ here
](/catkin/conceptual_overview#Dependency_Management) .


©  2013 Digia Plc and/or its subsidiaries. Documentation contributions
included herein are the copyrights of their respective owners.


    <package>
      <name>foo_core</name>
      <version>1.2.4</version>
      <description>
        This package provides foo capability.
      </description>
      <maintainer email="ivana@willowgarage.com">Ivana Bildbotz</maintainer>
      <license>BSD</license>

      <buildtool_depend>catkin</buildtool_depend>
    </package>


#  Related Topics

  * [ Documentation overview ](index.html)


  * Reimplement [ QWidget::sizeHint ](qwidget.html#sizeHint-prop) () to return the preferred size of the widget.
  * Reimplement [ QWidget::minimumSizeHint ](qwidget.html#minimumSizeHint-prop) () to return the smallest size the widget can have.
  * Call [ QWidget::setSizePolicy ](qwidget.html#sizePolicy-prop) () to specify the space requirements of the widget.


##  Format 2 (Recommended)


      float linear_velocity_; // In m/s
      float angular_velocity_; // In radians/s
      float linear_scale_; // In m/s
      float angular_scale_; // In radians/s
    };


  * [ Qt 4.8 ](index.html)
  * [ ALL VERSIONS ](http://qt-project.org/doc/)


[ **updated 2020-03-25 10:56:52 -0500  ** ](/questions/347516/revisions/)


The following code makes a grid like the one above, with a couple of
improvements:


It is often convenient to group multiple packages as a single logical package.
This can be accomplished through **metapackages** . A metapackage is a normal
package with the following export tag in the package.xml:


* ` <build_depend> `


##  [ QLayout ](qlayout.html)


[ Qt Reference Documentation  ](index.html)


Thanks, [ @marguedas ](/users/19307/marguedas/) and [ @gvdhoorn
](/users/5184/gvdhoorn/) , that clarifies it for me. I also realize now that
my interpretation of the documentation for package format 2 was not correct. I
edited the question to reflect that.


         [QWidget](qwidget.html) *window = new [QWidget](qwidget.html);
         [QPushButton](qpushbutton.html) *button1 = new [QPushButton](qpushbutton.html)("One");
         [QLineEdit](qlineedit.html) *lineEdit1 = new [QLineEdit](qlineedit.html)();
         [QPushButton](qpushbutton.html) *button2 = new [QPushButton](qpushbutton.html)("Two");
         [QLineEdit](qlineedit.html) *lineEdit2 = new [QLineEdit](qlineedit.html)();
         [QPushButton](qpushbutton.html) *button3 = new [QPushButton](qpushbutton.html)("Three");
         [QLineEdit](qlineedit.html) *lineEdit3 = new [QLineEdit](qlineedit.html)();

         [QFormLayout](qformlayout.html) *layout = new [QFormLayout](qformlayout.html);
         layout->addRow(button1, lineEdit1);
         layout->addRow(button2, lineEdit2);
         layout->addRow(button3, lineEdit3);

         window->setLayout(layout);
         window->show();


To write your own layout class, you must define the following:


    <exec_depend>rclcpp</exec_depend>
    <exec_depend>std_msgs</exec_depend>


     void CardLayout::addItem([QLayoutItem](qlayoutitem.html) *item)
     {
         list.append(item);
     }


The full documentation for format 2 can be found in the [ catkin API docs
](https://docs.ros.org/melodic/api/catkin/html/howto/format2/index.html) .
More information can be found in [ REP 140 -- Package Manifest Format Two
Specification ](http://www.ros.org/reps/rep-0140.html) .


[ https://groups.google.com/forum/#!msg/ros-sig-buildsystem/mn-
VCkl2OHk/dUsHBBjyK30J ](https://groups.google.com/forum/#!msg/ros-sig-
buildsystem/mn-VCkl2OHk/dUsHBBjyK30J)


The ` setGeometry() ` function actually performs the layout. The rectangle
supplied as an argument does not include ` margin() ` . If relevant, use `
spacing() ` as the distance between items.


Lines up widgets vertically

[ QWidgetItem ](qwidgetitem.html)


###  Basic Structure


      </class>
    </library>

The first line says that the compiled library lives in
lib/librviz_plugin_tutorials (the ”.so” ending is appended by pluginlib
according to the OS). This path is relative to the top directory of the
package:

    <library path="lib/librviz_plugin_tutorials">

The next section is a ` class  ` entry describing the TeleopPanel:

    <class name="rviz_plugin_tutorials/Teleop"
           type="rviz_plugin_tutorials::TeleopPanel"
           base_class_type="rviz::Panel">
      <description>
        A panel widget allowing simple diff-drive style robot base control.
      </description>
    </class>

This specifies the name, type, base class, and description of the class. The
_name_ field must be a combination of the first two strings given to the `
PLUGINLIB_DECLARE_CLASS()  ` macro in the source file. It must be the
“package” name, a “/” slash, then the “display name” for the class. The
“display name” is the name used for the class in the user interface.

The _type_ entry must be the fully-qualified class name, including any
namespace(s) it is inside.

The _base_class_type_ is usually one of ` rviz::Panel  ` , ` rviz::Display  `
, ` rviz::Tool  ` , or ` rviz::ViewController  ` .

The _description_ subsection is a simple text description of the class, which


##  Stats


##  API Lookup


Asked: ** 2020-03-25 10:03:13 -0500  **


* A [ QVBoxLayout ](qvboxlayout.html) lays out widgets in a vertical column, from top to bottom.


[ rclpy fails to run on arm64 after cross-compilation
](/question/329161/rclpy-fails-to-run-on-arm64-after-cross-compilation/)


Last updated: **Mar 25 '20**


If the built-in layout classes are not sufficient, you can define your own.
You must make a subclass of [ QLayout ](qlayout.html) that handles resizing
and size calculations, as well as a subclass of [ QGLayoutIterator
](qglayoutiterator.html) to iterate over your layout class.


You can insert layouts inside a layout by giving the parent layout as a
parameter in the constructor.


Group box frame with a title

[ QHBoxLayout ](qhboxlayout.html)


* ` <test_depend> `


###  Stretch Factors


Stack of widgets where only one widget is visible at a time

[ QStackedWidget ](qstackedwidget.html)


A more realistic example that specifies build, runtime, and test dependencies
could look as follows.


* A [ QGrid ](qgrid.html) lays out its child widgets in a two dimensional grid. You can specify how many columns the grid has, and it is populated left to right, beginning a new row when the previous row is full. The grid is fixed; the child widgets will not flow to other rows as the widget is resized.


* A [ QGridLayout ](qgridlayout.html) lays out widgets in a two-dimensional grid. Widgets can occupy multiple cells.


![Vertical box with five child widgets](qvbox-m.png)


Seen: **1,778 times**


Afaict, it should probably be ` depend ` instead of ` exec_depend ` .


[ __ ](/questions/) |


[ subscribe to rss feed ](/feeds/question/347516/ "subscribe to the rss feed")


[ tags ](/tags/) [ users ](/users/) [ badges ](/badges/)


#  This Page

  * [ Show Source ](_sources/panel_plugin_tutorial.txt)


The Qt layout system provides a simple and powerful way of specifying the
layout of child widgets.


[ Home  ](index.html) | [ All Classes  ](classes.html) | [ Main Classes
](mainclasses.html) | [ Annotated  ](annotated.html) | [ Grouped Classes
](groups.html) | [ Functions  ](functions.html) |  ![](logo32.png)
---|---

#  Layout Classes


* ` <doc_depend> `


##  [ QLayout ](qlayout.html)


  Exporting the Plugin  Â¶

For the plugin to be found and understood by other ROS packages (in this case,
rviz), it needs a “plugin_description.xml” file. This file can be named
anything you like, as it is specified in the plugin package’s “package.xml”
file like so:

    <export>
        <rviz plugin="${prefix}/plugin_description.xml"/>
    </export>

The contents of plugin_description.xml then look like this:

    <library path="lib/librviz_plugin_tutorials">
      <class name="rviz_plugin_tutorials/Teleop"
             type="rviz_plugin_tutorials::TeleopPanel"
             base_class_type="rviz::Panel">
        <description>
          A panel widget allowing simple diff-drive style robot base control.
        </description>
      </class>
      <class name="rviz_plugin_tutorials/Imu"
             type="rviz_plugin_tutorials::ImuDisplay"
             base_class_type="rviz::Display">
        <description>
          Displays direction and scale of accelerations from sensor_msgs/Imu messages.
        </description>
        <message_type>sensor_msgs/Imu</message_type>
      </class>
      <class name="rviz_plugin_tutorials/PlantFlag"
             type="rviz_plugin_tutorials::PlantFlagTool"
             base_class_type="rviz::Tool">
        <description>
          Tool for planting flags on the ground plane in rviz.
        </description>


When you add widgets to a layout the layout process works as follows:


        [QGrid](qgrid.html) *mainGrid = new [QGrid](qgrid.html)( 2 ); // a 2 x n grid
        new [QLabel](qlabel.html)( "One", mainGrid );
        new [QLabel](qlabel.html)( "Two", mainGrid );
        new [QLabel](qlabel.html)( "Three", mainGrid );
        new [QLabel](qlabel.html)( "Four", mainGrid );
        new [QLabel](qlabel.html)( "Five", mainGrid );


The base class of geometry managers

[ QLayoutItem ](qlayoutitem.html)


  * [ Class index ](classes.html)
  * [ Function index ](functions.html)
  * [ Modules ](modules.html)
  * [ Namespaces ](namespaces.html)
  * [ Global Declarations ](qtglobal.html)
  * [ QML elements ](qdeclarativeelements.html)


add a comment


[ ![](/custom/images/brought_by_horiz.png) ](https://www.openrobotics.org/)


Layout attribute describing horizontal and vertical resizing policy

[ QSpacerItem ](qspaceritem.html)


All  |  API  |  Articles  |  Examples


The grid shown above can be produced by the following code:


* ` <url> ` \- A URL for information on the package, typically a wiki page on ros.org.


For further guidance when implementing these functions, see the _Qt Quarterly_
article [ Trading Height for Width ](http://doc.qt.nokia.com/qq/qq04-height-
for-width.html) .


![](images/qformlayout-with-6-children.png)


` addItem() ` implements the default placement strategy for layout items. This
function must be implemented. It is used by [ QLayout::add ](qlayout-
qt3.html#add) (), by the [ QLayout ](qlayout.html) constructor that takes a
layout as parent. If your layout has advanced placement options that require
parameters, you must provide extra access functions such as the row and column
spanning overloads of [ QGridLayout::addItem ](qgridlayout.html#addItem) (), [
QGridLayout::addWidget ](qgridlayout.html#addWidget) (), and [
QGridLayout::addLayout ](qgridlayout.html#addLayout) ().


[ Widgets and Layouts ](widgets-and-layouts.html) [ Styles ](style-
reference.html)


     #ifndef CARD_H
     #define CARD_H

     #include <QtGui>
     #include <QList>

     class CardLayout : public [QLayout](qlayout.html)
     {
     public:
         CardLayout([QWidget](qwidget.html) *parent, int dist): [QLayout](qlayout.html)(parent, 0, dist) {}
         CardLayout([QLayout](qlayout.html) *parent, int dist): [QLayout](qlayout.html)(parent, dist) {}
         CardLayout(int dist): [QLayout](qlayout.html)(dist) {}
         ~CardLayout();

         void addItem([QLayoutItem](qlayoutitem.html) *item);
         [QSize](qsize.html) sizeHint() const;
         [QSize](qsize.html) minimumSize() const;
             [QLayoutItem](qlayoutitem.html) *count() const;
         [QLayoutItem](qlayoutitem.html) *itemAt(int) const;
         [QLayoutItem](qlayoutitem.html) *takeAt(int);
         void setGeometry(const [QRect](qrect.html) &rect);

     private:
         [QList](qlist.html)<[QLayoutItem](qlayoutitem.html)*> list;
     };
     #endif


1 follower


[ Powered by Askbot version 0.10.2 ](http://askbot.com)


##  1  Answer


The easiest way to give your widgets a good layout is to use the built-in
layout managers: [ QHBoxLayout ](qhboxlayout.html) , [ QVBoxLayout
](qvboxlayout.html) , [ QGridLayout ](qgridlayout.html) , and [ QFormLayout
](qformlayout.html) . These classes inherit from [ QLayout ](qlayout.html) ,
which in turn derives from [ QObject ](qobject.html) (not [ QWidget
](qwidget.html) ). They take care of geometry management for a set of widgets.
To create more complex layouts, you can nest layout managers inside each
other.


         [QWidget](qwidget.html) *window = new [QWidget](qwidget.html);
         [QPushButton](qpushbutton.html) *button1 = new [QPushButton](qpushbutton.html)("One");
         [QPushButton](qpushbutton.html) *button2 = new [QPushButton](qpushbutton.html)("Two");
         [QPushButton](qpushbutton.html) *button3 = new [QPushButton](qpushbutton.html)("Three");
         [QPushButton](qpushbutton.html) *button4 = new [QPushButton](qpushbutton.html)("Four");
         [QPushButton](qpushbutton.html) *button5 = new [QPushButton](qpushbutton.html)("Five");

         [QGridLayout](qgridlayout.html) *layout = new [QGridLayout](qgridlayout.html);
         layout->addWidget(button1, 0, 0);
         layout->addWidget(button2, 0, 1);
         layout->addWidget(button3, 1, 0, 1, 2);
         layout->addWidget(button4, 2, 0);
         layout->addWidget(button5, 2, 1);

         window->setLayout(layout);
         window->show();


  The Plugin Code  Â¶

The code for TeleopPanel is in these files: [ src/teleop_panel.h
](https://github.com/ros-visualization/visualization_tutorials/tree/groovy-
devel/rviz_plugin_tutorials/src/teleop_panel.h) , [ src/teleop_panel.cpp
](https://github.com/ros-visualization/visualization_tutorials/tree/groovy-
devel/rviz_plugin_tutorials/src/teleop_panel.cpp) , [ src/drive_widget.h
](https://github.com/ros-visualization/visualization_tutorials/tree/groovy-
devel/rviz_plugin_tutorials/src/drive_widget.h) , and [ src/drive_widget.cpp
](https://github.com/ros-visualization/visualization_tutorials/tree/groovy-
devel/rviz_plugin_tutorials/src/drive_widget.cpp) .


The package manifest with minimal tags does not specify any dependencies on
other packages. Packages can have four types of dependencies:


* A [ QVBox ](qvbox.html) lays out its child widgets in a vertical column, top to bottom.


[ ![marguedas gravatar
image](/upfiles/avatars/marguedas/resized/16/avatarGithub.jpeg)
](/users/19307/marguedas/) [ marguedas ](/users/19307/marguedas/) (
2020-03-25 10:31:35 -0500  )  edit


* ` <version> ` \- The version number of the package (required to be 3 dot-separated integers)


If we apply stretch factors to each widget, they will be laid out in
proportion (but never less than their minimum size hint), e.g.


     <export>
       <metapackage />
     </export>


    cmake_minimum_required(VERSION 2.8.3)
    project(<PACKAGE_NAME>)
    find_package(catkin REQUIRED)
    catkin_metapackage()


##  Adding Widgets to a Layout


    painter.setPen( arrow );

Compute and draw polylines for each arrowhead. This code could probably be
more elegant.

        float head_len = size / 8.0;
        QPointF arrow_head[ 3 ];
        float x, y;
        if( fabsf( -step_dist + half_track_width * delta_angle ) > .01 )
        {
          x = left_track[ step_count - 1 ].x();
          y = left_track[ step_count - 1 ].y();
          arrow_head[ 0 ].setX( x + head_len * cosf( angle + 3*M_PI/4 + left_arrow_dir * M_PI ));
          arrow_head[ 0 ].setY( y - head_len * sinf( angle + 3*M_PI/4 + left_arrow_dir * M_PI ));
          arrow_head[ 1 ].setX( x );
          arrow_head[ 1 ].setY( y );
          arrow_head[ 2 ].setX( x + head_len * cosf( angle - 3*M_PI/4 + left_arrow_dir * M_PI ));
          arrow_head[ 2 ].setY( y - head_len * sinf( angle - 3*M_PI/4 + left_arrow_dir * M_PI ));
          painter.drawPolyline( arrow_head, 3 );
        }
        if( fabsf( -step_dist - half_track_width * delta_angle ) > .01 )
        {
          x = right_track[ step_count - 1 ].x();
          y = right_track[ step_count - 1 ].y();
          arrow_head[ 0 ].setX( x + head_len * cosf( angle + 3*M_PI/4 + right_arrow_dir * M_PI ));
          arrow_head[ 0 ].setY( y - head_len * sinf( angle + 3*M_PI/4 + right_arrow_dir * M_PI ));
          arrow_head[ 1 ].setX( x );
          arrow_head[ 1 ].setY( y );
          arrow_head[ 2 ].setX( x + head_len * cosf( angle - 3*M_PI/4 + right_arrow_dir * M_PI ));
          arrow_head[ 2 ].setY( y - head_len * sinf( angle - 3*M_PI/4 + right_arrow_dir * M_PI ));
          painter.drawPolyline( arrow_head, 3 );
        }
      }
    }

Every mouse move event received here sends a velocity because Qt only sends us


Metapackage now have CMakeLists.txt files after a discussion about installing
the package.xml files:


If you are making a one-of-a-kind special layout, you can also make a custom
widget as described above. Reimplement [ QWidget::resizeEvent
](qwidget.html#resizeEvent) () to calculate the required distribution of sizes
and call [ setGeometry() ](qwidget.html#geometry-prop) on each child.


##  Overview


mouse move events if there was previously a mouse-press event while in the
widget.

    void DriveWidget::mouseMoveEvent( QMouseEvent* event )
    {
      sendVelocitiesFromMouse( event->x(), event->y(), width(), height() );
    }

Mouse-press events should send the velocities too, of course.

    void DriveWidget::mousePressEvent( QMouseEvent* event )
    {
      sendVelocitiesFromMouse( event->x(), event->y(), width(), height() );
    }

When the mouse leaves the widget but the button is still held down, we don’t
get the leaveEvent() because the mouse is “grabbed” (by default from Qt).
However, when the mouse drags out of the widget and then other buttons are
pressed (or possibly other window-manager things happen), we will get a
leaveEvent() but not a mouseReleaseEvent(). Without catching this event you
can have a robot stuck “on” without the user controlling it.

    void DriveWidget::leaveEvent( QEvent* event )
    {
      stop();
    }

The ordinary way to stop: let go of the mouse button.


[ Get all key/value pairs from custom ROS2 message ](/question/370820/get-all-
keyvalue-pairs-from-custom-ros2-message/)


* [ dashing ](/questions/scope:all/sort:activity-desc/tags:dashing/page:1/)


  * [ Programming with Qt ](qt-basic-concepts.html)
  * [ Device UIs & Qt Quick ](qtquick.html)
  * [ UI Design with Qt ](qt-gui-concepts.html)
  * [ Supported Platforms ](supported-platforms.html)
  * [ Qt and Key Technologies ](technology-apis.html)
  * [ How-To's and Best Practices ](best-practices.html)


  * Introduction
  * Qt's Layout Classes
  * Horizontal, Vertical, Grid, and Form Layouts
  * Laying Out Widgets in Code
  * Tips for Using Layouts
  * Adding Widgets to a Layout
  * Stretch Factors
  * Custom Widgets in Layouts
  * Layout Issues
  * Manual Layout
  * How to Write A Custom Layout Manager
  * The Header File ( ` card.h ` )
  * The Implementation File ( ` card.cpp ` )
  * Further Notes


![3 widgets in a row](layout1.png)


#  [ Table Of Contents ](index.html)

  * TeleopPanel
    * Overview
    * The Plugin Code
      * teleop_panel.h
      * teleop_panel.cpp
      * drive_widget.h
      * drive_widget.cpp
    * Building the Plugin
    * Exporting the Plugin
    * Trying It Out
    * Next Steps


* ` <maintainer> ` \- The name of the person(s) that is/are maintaining the package


Follow


The package manifest with minimal tags does not specify any dependencies on
other packages. Packages can have six types of dependencies:


* ` <description> ` \- A description of the package contents


The widget will get an event with [ type ](qevent.html#type) ` LayoutHint `
when the layout needs to be recalculated. Reimplement [ QWidget::event
](qwidget.html#event) () to be notified of ` LayoutHint ` events.


If the preferred height of your widget depends on its actual width (e.g., a
label with automatic word-breaking), set the [ height-for-width
](qsizepolicy.html#hasHeightForWidth) flag in the widget's [ size policy
](qwidget.html#sizePolicy-prop) and reimplement [ QWidget::heightForWidth
](qwidget.html#heightForWidth) ().


  Trying It Out  Â¶

Once your RViz plugin is compiled and exported, simply run rviz normally:

    rosrun rviz rviz

and rviz will use pluginlib to find all the plugins exported to it.

Add a Teleop panel by opening the “Panels” menu and then “Add New Panel”
within that. This should bring up a Panel class chooser dialog with “Teleop”
in it (here it is “rviz_plugin_tutorials”):

![_images/teleop_plugin.png](_images/teleop_plugin.png)

If “Teleop” is not in your list of Panel types, look through RViz’s console
output for error messages relating to plugin loading. Some common problems
are:

  * not having a plugin_description.xml file,
  * not exporting it in the manifest.xml file, or
  * not properly referencing the library file (like librviz_plugin_tutorials.so) from plugin_description.xml.

Once you’ve added the Teleop panel to RViz, you just need to enter a topic
name to publish the geometry_msgs/Twist command velocities on. Once a non-
empty string has been entered in the “Output Topic” field, the control square
area should light up and accept mouse events. Holding the mouse button down in
the control area sends a linear velocity based on the Y position of the mouse
relative to the center and an angular velocity based on the X position of the
mouse relative to the center.


    {
      background = Qt::white;
      crosshair = Qt::black;
    }
    else
    {
      background = Qt::lightGray;
      crosshair = Qt::darkGray;
    }

The main visual is a square, centered in the widget’s area. Here we compute
the size of the square and the horizontal and vertical offsets of it.

    int w = width();
    int h = height();
    int size = (( w > h ) ? h : w) - 1;
    int hpad = ( w - size ) / 2;
    int vpad = ( h - size ) / 2;

    QPainter painter( this );
    painter.setBrush( background );
    painter.setPen( crosshair );

Draw the background square.

    painter.drawRect( QRect( hpad, vpad, size, size ));

Draw a cross-hair inside the square.

    painter.drawLine( hpad, height() / 2, hpad + size, height() / 2 );
    painter.drawLine( width() / 2, vpad, width() / 2, vpad + size );


See the [ Custom Layout ](customlayout.html) page for an in-depth description.


    <package>

    </package>


//#include "card.h"


* ` <buildtool_depend> `


###  Metapackages


Please note: ROS Answers requires javascript to work properly, please enable
javascript in your browser, [ here is how
](https://www.google.com/support/bin/answer.py?answer=23852)


First time here? Check out the FAQ!


The Qt layout system provides a simple and powerful way of automatically
arranging child widgets within a widget to ensure that they make good use of
the available space.


##  Custom Layouts


  * A
  * A
  * A
  * [ Print  ](javascript:this.print\(\);)


ROS Resources: [ Documentation ](http://wiki.ros.org/) | [ Support
](http://wiki.ros.org/Support) | [ Discussion Forum
](http://discourse.ros.org/) | [ Index ](http://index.ros.org/) | [ Service
Status ](http://status.ros.org/) | [ ros @ Robotics Stack Exchange
](https://robotics.stackexchange.com/questions/tagged/ros)
---

_Attention:_ Answers.ros.org is deprecated as of August the 11th, 2023. Please
visit [ robotics.stackexchange.com ](http://robotics.stackexchange.com) to ask
a new question. This site will remain online in read-only mode during the
transition and into the foreseeable future. Selected questions and answers
have been migrated, and redirects have been put in place to direct users to
the corresponding questions on Robotics Stack Exchange. Additional details are
[ available here ](https://discourse.ros.org/t/ros-and-gazebo-answers-
migration-to-robotics-stack-exchange-process/31494) .


The site is read-only. Please transition to use Robotics Stack Exchange


[ ![gvdhoorn gravatar image](/upfiles/avatars/gvdhoorn/resized/16/4550046.png)
](/users/5184/gvdhoorn/) [ gvdhoorn ](/users/5184/gvdhoorn/) (  2020-03-25
10:34:34 -0500  )  edit


    <package format="2">
      <name>foo_core</name>
      <version>1.2.4</version>
      <description>
        This package provides foo capability.
      </description>
      <maintainer email="ivana@osrf.org">Ivana Bildbotz</maintainer>
      <license>BSD</license>

      <buildtool_depend>catkin</buildtool_depend>
    </package>


This is the recommended format for new packages. It is also recommended that
older format 1 packages be migrated to format 2. For instructions on migrating
from format 1 to format 2, see [ Migrating from Format 1 to Format 2
](https://docs.ros.org/melodic/api/catkin/html/howto/format2/migrating_from_format_1.html#migrating-
from-format1-to-format2) in the catkin API docs.


More details on dependencies can be found in the catkin API docs [ here
](https://docs.ros.org/melodic/api/catkin/html/howto/format2/catkin_library_dependencies.html)
.


* **Documentation Tool Dependencies** specify documentation tools which this package needs to generate documentation.


Widgets are normally created without any stretch factor set. When they are
laid out in a layout the widgets are given a share of space in accordance with
their [ QWidget::sizePolicy ](qwidget.html#sizePolicy) () or their minimum
size hint whichever is the greater. Stretch factors are used to change how
much space widgets are given in proportion to one another.


Additionally a metapackage has a required, boilerplate CMakeLists.txt file:


[ ros2 Dashing: Message frequency lower than expected [closed]
](/question/334183/ros2-dashing-message-frequency-lower-than-expected/)


###  Required Tags


[ Slam Toolbox - How is scan data used to build the map?
](/question/371874/slam-toolbox-how-is-scan-data-used-to-build-the-map/)


The format of package.xml is straightforward.


Layout where one can anchor widgets together in Graphics View

[ QGridLayout ](qgridlayout.html)


###  Laying Out Widgets in Code


###  Basic Structure


[ ![Jeffrey Kane Johnson gravatar
image](/upfiles/avatars/Jeffrey%20Kane%20Johnson/resized/16/headshot-200x200.jpg)
](/users/2517/jeffrey-kane-johnson/) [ Jeffrey Kane Johnson
](/users/2517/jeffrey-kane-johnson/) (  2020-03-25 10:57:04 -0500  )  edit


* **Test Dependencies** specify only _additional_ dependencies for unit tests. They should never duplicate any dependencies already mentioned as build or run dependencies.


Lines up child widgets horizontally or vertically

---|---

[ QButtonGroup ](qbuttongroup.html)


add a comment


  1. Overview
  2. Format 2 (Recommended)
    1. Basic Structure
    2. Required Tags
    3. Dependencies
    4. Metapackages
    5. Additional Tags
  3. Format 1 (Legacy)
    1. Basic Structure
    2. Required Tags
    3. Build, Run, and Test Dependencies
    4. Metapackages
    5. Additional Tags


  1. All the widgets will initially be allocated an amount of space in accordance with their [ QWidget::sizePolicy ](qwidget.html#sizePolicy) ().
  2. If any of the widgets have stretch factors set, with a value greater than zero, then they are allocated space in proportion to their  stretch factor  .
  3. If any of the widgets have stretch factors set to zero they will only get more space if no other widgets want the space. Of these, space is allocated to widgets with an ` Expanding ` size policy first.
  4. Any widgets that are allocated less space than their minimum size (or minimum size hint if no minimum size is specified) are allocated this minimum size they require. (Widgets don't have to have a minimum size or minimum size hint in which case the strech factor is their determining factor.)
  5. Any widgets that are allocated more space than their maximum size are allocated the maximum size space they require. (Widgets don't have to have a maximum size in which case the strech factor is their determining factor.)


Qt's layout classes were designed for hand-written C++ code, allowing
measurements to be specified in pixels for simplicity, so they are easy to
understand and use. The code generated for forms created using _Qt Designer_
also uses the layout classes. _Qt Designer_ is useful to use when
experimenting with the design of a form since it avoids the compile, link and
run cycle usually involved in user interface development.