Skip to content
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.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to create a swarm scenario with CrazyS #44

Closed
gsilano opened this issue Apr 18, 2020 · 14 comments
Closed

How to create a swarm scenario with CrazyS #44

gsilano opened this issue Apr 18, 2020 · 14 comments
Assignees
Labels
type: question Further information is requested
Milestone

Comments

@gsilano
Copy link
Owner

gsilano commented Apr 18, 2020

In the following the message received by Arslan to whom I cannot reply by email (Undelivered Mail Returned to Sender).

I hope you are in the best of your health and spirit. I've been using your CrazyS GitHub repository for building swarms of crazyflie2 nano quadrotors in Gazebo.

I've one question regarding this and would be grateful to you if you shed some light. In order to spawn multiple Crazyflie I am assigning each with different namespace same as you did for firefly_swarm_hovering_example. However, it did not work for crazyflie_hovering_example.

I also have checked the rqt_graph and both "hovering example node" and position_controller_node do not communicate if I changed namespace in the launch file.

I attaching a snippet of my launch file and rqt_graph here with email and would be grateful if you can give some comments.

rqt_graph_carzyflie
launchfile_diff_namespace

@gsilano gsilano added the type: question Further information is requested label Apr 18, 2020
@gsilano gsilano self-assigned this Apr 18, 2020
@gsilano
Copy link
Owner Author

gsilano commented Apr 18, 2020

I'm happy to hear from you that you found CrazyS useful for your research.

As for your question, starting from the hovering example you can create a swarm example by copying and pasting multiple instances of the drone model (you can recognize it from the comments). Then, you can pilot every single drone using your controller algorithm.

<!-- The following lines simulate the Crazyflie dynamics -->
<include file="$(find rotors_gazebo)/launch/spawn_mav_crazyflie.launch">
<arg name="mav_name" value="$(arg mav_name)" />
<arg name="model" value="$(find rotors_description)/urdf/mav_generic_odometry_sensor.gazebo" />
<arg name="enable_logging" value="$(arg enable_logging)" />
<arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
<arg name="enable_state_estimator" value="$(arg enable_state_estimator)" />
<arg name="log_file" value="$(arg log_file)"/>
</include>

What you are changing is not the namespace, but the name of the device you are using (e.g., crazyflie, firefly, etc.). This is the meaning associated with the mav_name variable. Therefore, when you want to work with the Crazyflie you do not have to change it.

I hope this helps.

@Marslanali
Copy link

Marslanali commented Apr 19, 2020

Hi Giuseppe Silano,

Thanks for your response and just saw your message here. I will try your solution and will get back here If I will have any question.

BTW in your current framework when I will spawn multiple instance of crazyflie do I need to instantiate multiple instance in different namespaces? Right now hovering example have a namespace of crazyflie2, how can I change the namespace using same hovering example?

For instance If I change its namespace to crazyflie22 and then use run way point publisher node like this

$ rosrun rotors_gazebo waypoint_publisher 0 0 0 1 __ns:=crazyflie22

Attach is screenshot where I am running way point publisher node for your current example with namespace crazyflie2

waypoint

Thanks
Arslan

@gsilano
Copy link
Owner Author

gsilano commented Apr 20, 2020

Below is an example of how to organize the contents of the YAML file.

 <group ns="$(arg mav_name)1">
  <!-- CRAZYFLIE_1 -->
    <include file="$(find rotors_gazebo)/launch/spawn_mav_crazyflie.launch">
      <arg name="namespace" value="$(arg mav_name)1" />
      <arg name="mav_name" value="$(arg mav_name)" />
      <arg name="model" value="$(find rotors_description)/urdf/mav_generic_odometry_sensor.gazebo" />
      <arg name="enable_logging" value="$(arg enable_logging)" />
      <arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
      <arg name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <arg name="log_file" value="$(arg log_file)"/>
      <!-- Set the initial position -->
      <arg name="x" value="-1.0"/>
      <arg name="y" value="-1.0"/>
    </include>
 <group ns="$(arg mav_name)">
   <!-- The Crazyflie position controller -->
   <node name="position_controller_node" pkg="rotors_control" type="position_controller_node" output="screen">
      <param name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <param name="csvFilesStoring" value="$(arg csvFilesStoring)"/>
      <param name="csvFilesStoringTime" value="$(arg csvFilesStoringTime)"/>
      <param name="user_account" value="$(arg user_account)"/>
      <rosparam unless="$(arg enable_state_estimator)" command="load" file="$(find rotors_gazebo)/resource/controller_$(arg mav_name).yaml" />
      <rosparam if="$(arg enable_state_estimator)" command="load" file="$(find rotors_gazebo)/resource/controller_$(arg mav_name)_with_stateEstimator.yaml" />
      <rosparam command="load" file="$(find rotors_gazebo)/resource/$(arg mav_name).yaml" />
   </node>
   <node name="hovering_example" pkg="rotors_gazebo" type="hovering_example" output="screen" />
   <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
   <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
   <node name="quaternion_to_rpy" pkg="rotors_gazebo" type="quaternion_to_rpy" output="screen" >
       <remap from="odometry" to="odometry_sensor1/odometry" />
   </node>
  </group>

  <!-- CRAZYFLIE_2 -->
<group ns="$(arg mav_name)2">
    <include file="$(find rotors_gazebo)/launch/spawn_mav_crazyflie.launch">
      <arg name="namespace" value="$(arg mav_name)2" />
      <arg name="mav_name" value="$(arg mav_name)" />
      <arg name="model" value="$(find rotors_description)/urdf/mav_generic_odometry_sensor.gazebo" />
      <arg name="enable_logging" value="$(arg enable_logging)" />
      <arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
      <arg name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <arg name="log_file" value="$(arg log_file)"/>
      <!-- Set the initial position -->
      <arg name="x" value="-2.0"/>
      <arg name="y" value="-1.0"/>
    </include>
 <group ns="$(arg mav_name)">
   <!-- The Crazyflie position controller -->
   <node name="position_controller_node" pkg="rotors_control" type="position_controller_node" output="screen">
      <param name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <param name="csvFilesStoring" value="$(arg csvFilesStoring)"/>
      <param name="csvFilesStoringTime" value="$(arg csvFilesStoringTime)"/>
      <param name="user_account" value="$(arg user_account)"/>
      <rosparam unless="$(arg enable_state_estimator)" command="load" file="$(find rotors_gazebo)/resource/controller_$(arg mav_name).yaml" />
      <rosparam if="$(arg enable_state_estimator)" command="load" file="$(find rotors_gazebo)/resource/controller_$(arg mav_name)_with_stateEstimator.yaml" />
      <rosparam command="load" file="$(find rotors_gazebo)/resource/$(arg mav_name).yaml" />
   </node>
   <node name="hovering_example" pkg="rotors_gazebo" type="hovering_example" output="screen" />
   <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
   <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
   <node name="quaternion_to_rpy" pkg="rotors_gazebo" type="quaternion_to_rpy" output="screen" >
       <remap from="odometry" to="odometry_sensor1/odometry" />
   </node>
  </group>

  <!-- CRAZYFLIE_3 -->
<group ns="$(arg mav_name)3">
    <include file="$(find rotors_gazebo)/launch/spawn_mav_crazyflie.launch">
      <arg name="namespace" value="$(arg mav_name)3" />
      <arg name="mav_name" value="$(arg mav_name)" />
      <arg name="model" value="$(find rotors_description)/urdf/mav_generic_odometry_sensor.gazebo" />
      <arg name="enable_logging" value="$(arg enable_logging)" />
      <arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
      <arg name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <arg name="log_file" value="$(arg log_file)"/>
      <!-- Set the initial position -->
      <arg name="x" value="-1.0"/>
      <arg name="y" value="-2.0"/>
    </include>
   <!-- The Crazyflie position controller -->
   <node name="position_controller_node" pkg="rotors_control" type="position_controller_node" output="screen">
      <param name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <param name="csvFilesStoring" value="$(arg csvFilesStoring)"/>
      <param name="csvFilesStoringTime" value="$(arg csvFilesStoringTime)"/>
      <param name="user_account" value="$(arg user_account)"/>
      <rosparam unless="$(arg enable_state_estimator)" command="load" file="$(find rotors_gazebo)/resource/controller_$(arg mav_name).yaml" />
      <rosparam if="$(arg enable_state_estimator)" command="load" file="$(find rotors_gazebo)/resource/controller_$(arg mav_name)_with_stateEstimator.yaml" />
      <rosparam command="load" file="$(find rotors_gazebo)/resource/$(arg mav_name).yaml" />
   </node>
   <node name="hovering_example" pkg="rotors_gazebo" type="hovering_example" output="screen" />
   <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
   <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
   <node name="quaternion_to_rpy" pkg="rotors_gazebo" type="quaternion_to_rpy" output="screen" >
       <remap from="odometry" to="odometry_sensor1/odometry" />
   </node>
  </group>

Of course, it is necessary to understand whether the output interface of the waypoint publisher node is compatible with the input interface of the position controller. Also, remember that position controller is just one example made to show how the CrazyS package works. It cannot be used as a tracking controller. Therefore, you should develop your swarm control algorithm.

@Marslanali
Copy link

Thanks for your fast response. Will check your proposed solution today.

I also want to check lee position controller with crazyflie2. mav_hovering example have lee position controller node and i want to use same though I should have set all gain for crazyflie2. so question is how I can design proper gains for crazyflie first ? sorry I my question sounds basic.

Thanks

@gsilano
Copy link
Owner Author

gsilano commented Apr 20, 2020

To use the lee position controller node you can start studying the reference paper. It's not such an easy task, but not an impossible one, I can say.

@Marslanali
Copy link

sounds good. I will check the reference paper.

Thanks

@krawal19
Copy link

krawal19 commented Apr 20, 2020

Hey @gsilano,
I'm also trying to create a swarm scenario, I used your format of launch file to get 3 crazyflie in the gazebo environment without a controller node, hovering_example node, robot_state_publisher node, joint_state_publisher node, and quaternion_to_rpy node.

The expected rostopic list out when the only spawn_mav_crazyflie is launched would be (here x is the drone number)

/clock
/crazyflie2x/command/motor_speed
/crazyflie2x/gazebo/command/motor_speed
/crazyflie2x/joint_states
/crazyflie2x/motor_speed
/crazyflie2x/motor_speed/0
/crazyflie2x/motor_speed/1
/crazyflie2x/motor_speed/2
/crazyflie2x/motor_speed/3
/crazyflie2x/odometry
/crazyflie2x/odometry_sensor1/odometry
/crazyflie2x/odometry_sensor1/pose
/crazyflie2x/odometry_sensor1/pose_with_covariance
/crazyflie2x/odometry_sensor1/position
/crazyflie2x/odometry_sensor1/transform
/crazyflie2x/pose
/crazyflie2x/pose_with_covariance
/crazyflie2x/position
/crazyflie2x/transform
/crazyflie2x/wind_speed
/gazebo/link_states
/gazebo/model_states
/gazebo/parameter_descriptions
/gazebo/parameter_updates
/gazebo/set_link_state
/gazebo/set_model_state
/gazebo_gui/parameter_descriptions
/gazebo_gui/parameter_updates
/rosout
/rosout_agg
/tf
/tf_static
 .... repeating for each namespace.

but what I'm receving on rostopic list is only crazyflie2 topic whithout individual topics for each drone.

/clock
/crazyflie2/command/motor_speed
/crazyflie2/gazebo/command/motor_speed
/crazyflie2/joint_states
/crazyflie2/motor_speed
/crazyflie2/motor_speed/0
/crazyflie2/motor_speed/1
/crazyflie2/motor_speed/2
/crazyflie2/motor_speed/3
/crazyflie2/odometry
/crazyflie2/odometry_sensor1/odometry
/crazyflie2/odometry_sensor1/pose
/crazyflie2/odometry_sensor1/pose_with_covariance
/crazyflie2/odometry_sensor1/position
/crazyflie2/odometry_sensor1/transform
/crazyflie2/pose
/crazyflie2/pose_with_covariance
/crazyflie2/position
/crazyflie2/transform
/crazyflie2/wind_speed
/gazebo/link_states
/gazebo/model_states
/gazebo/parameter_descriptions
/gazebo/parameter_updates
/gazebo/set_link_state
/gazebo/set_model_state
/gazebo_gui/parameter_descriptions
/gazebo_gui/parameter_updates
/rosout
/rosout_agg
/tf
/tf_static

I've added namespace for each spawn position, my launch file looks like this

<launch>
  <arg name="mav_name" default="crazyflie2"/>
  <arg name="world_name" default="basic"/>
  <arg name="enable_logging" default="false" />
  <arg name="enable_ground_truth" default="false" />
  <arg name="enable_state_estimator" default="false" />
  <arg name="log_file" default="$(arg mav_name)" />
  <arg name="paused" value="true"/>
  <arg name="debug" default="false"/>
  <arg name="gui" default="true"/>
  <arg name="csvFilesStoring" default="false"/>
  <arg name="csvFilesStoringTime" default="15.0"/> <!-- seconds -->
  <arg name="user_account" default="giuseppe"/>
  <!-- The following line causes gzmsg and gzerr messages to be printed to the console
      (even when Gazebo is started through roslaunch) -->
  <arg name="verbose" default="false"/>

  <!-- The following lines simulate the world in Gazebo. The physic engine properties
        are set up in the file "basic_crazyflie.world" file -->
  <env name="GAZEBO_MODEL_PATH" value="${GAZEBO_MODEL_PATH}:$(find rotors_gazebo)/models"/>
  <env name="GAZEBO_RESOURCE_PATH" value="${GAZEBO_RESOURCE_PATH}:$(find rotors_gazebo)/models"/>
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find rotors_gazebo)/worlds/$(arg world_name)_crazyflie.world" />
    <arg name="debug" value="$(arg debug)" />
    <arg name="paused" value="$(arg paused)"/>
    <arg name="gui" value="$(arg gui)" />
    <arg name="verbose" value="$(arg verbose)"/>
  </include>

 <!-- CRAZYFLIE_1 -->
<group ns="$(arg mav_name)1">
    <include file="$(find rotors_gazebo)/launch/spawn_mav_crazyflie.launch">
      <arg name="namespace" value="$(arg mav_name)1" />
      <arg name="mav_name" value="$(arg mav_name)" />
      <arg name="model" value="$(find rotors_description)/urdf/mav_generic_odometry_sensor.gazebo" />
      <arg name="enable_logging" value="$(arg enable_logging)" />
      <arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
      <arg name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <arg name="log_file" value="$(arg log_file)"/>
      <!-- Set the initial position -->
      <arg name="x" value="-1.0"/>
      <arg name="y" value="-1.0"/>
    </include>
  </group>

  <!-- CRAZYFLIE_2 -->
<group ns="$(arg mav_name)2">
    <include file="$(find rotors_gazebo)/launch/spawn_mav_crazyflie.launch">
      <arg name="namespace" value="$(arg mav_name)2" />
      <arg name="mav_name" value="$(arg mav_name)" />
      <arg name="model" value="$(find rotors_description)/urdf/mav_generic_odometry_sensor.gazebo" />
      <arg name="enable_logging" value="$(arg enable_logging)" />
      <arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
      <arg name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <arg name="log_file" value="$(arg log_file)"/>
      <!-- Set the initial position -->
      <arg name="x" value="-2.0"/>
      <arg name="y" value="-1.0"/>
    </include>
  </group> 

  <!-- CRAZYFLIE_3 -->
 <group ns="$(arg mav_name)3">
    <include file="$(find rotors_gazebo)/launch/spawn_mav_crazyflie.launch">
      <arg name="namespace" value="$(arg mav_name)3" />
      <arg name="mav_name" value="$(arg mav_name)" />
      <arg name="model" value="$(find rotors_description)/urdf/mav_generic_odometry_sensor.gazebo" />
      <arg name="enable_logging" value="$(arg enable_logging)" />
      <arg name="enable_ground_truth" value="$(arg enable_ground_truth)" />
      <arg name="enable_state_estimator" value="$(arg enable_state_estimator)" />
      <arg name="log_file" value="$(arg log_file)"/>
      <arg name="x" value="-1.0"/>
      <arg name="y" value="-2.0"/>
    </include> 
  </group>  

</launch>

Can you please help me with this, as I want a separate set of topics for each drone but I'm only receiving only one set of topics.

Thank you
Kapil Rawal

@Marslanali
Copy link

Hi @gsilano I had tried your solution but still have no luck, getting same problem as @krawal19 . I cannot get the topics with different namespaces.

@krawal19
Copy link

Hey @gsilano @Marslanali,
I found what was causing the namespace issue and was able to get topics for each drone. So the fix was that in the /rotors_discription/urdf/crazyflie.xacro file line 23

<xacro:property name="namespace" value="$(arg mav_name)" />

Here it was taking input as the mav_name, which corresponds to crazyflie2 without namespace. Thus it should have to be changed from mav_name to namespace.

<xacro:property name="namespace" value="$(arg namespace)" />

This corrects the problem and assigns each drone with specified namespace xacro.
I hope that helps.

Thanks
Kapil Rawal

@Marslanali
Copy link

Hi @krawal19 thanks and will try today.

Arslan

@gsilano
Copy link
Owner Author

gsilano commented Apr 22, 2020

Hi @krawal19!! I'm happy to hear from you that you solved the issue. I will update the repository with this fix. Thanks!!

@gsilano gsilano added this to the 6.0.5 milestone Apr 22, 2020
@gsilano
Copy link
Owner Author

gsilano commented Apr 23, 2020

I have made available a swarm example with the Crazyflie (crazyflie2_swarm_hovering_example.launch). Further details are available in README.md and the reference commits.

@Marslanali
Copy link

@gsilano Thanks alot

@krawal19
Copy link

@gsilano Thanks for the update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants