<jupyter_start><jupyter_text>Creating models with Jupyter notebooks  Testing friction propertiesThe `pcg_gazebo_pkgs` includes also a simple interface to start Gazebo. It can be used to start Gazebo in the Python script or notebook, spawn models and interact with the simulation.<jupyter_code>try:
    import rospy
    ROS1_AVAILABLE = True
except ImportError:
    ROS1_AVAILABLE = False
    
if not ROS1_AVAILABLE:
    print('No ROS 1 available, source the ROS 1 setup.bash to run Gazebo')
else:
    # If there is a Gazebo instance running, you can spawn 
    # the box into the simulation
    from pcg_gazebo.task_manager import Server
    # First create a simulation server
    server = Server()
    # Create a simulation manager named default
    server.create_simulation('pcg-example')
    simulation = server.get_simulation('pcg-example')
if ROS1_AVAILABLE:
    # Run an instance of the empty.world scenario
    # This is equivalent to run
    #      roslaunch gazebo_ros empty_world.launch
    # with all default parameters
    simulation.create_gazebo_empty_world_task()
    # A task named 'gazebo' the added to the tasks list
    print('Tasks created: ', simulation.get_task_list())
    # But it is still not running
    print('Is Gazebo running: {}'.format(
        simulation.is_task_running('gazebo')))
if ROS1_AVAILABLE:
    # Run Gazebo
    simulation.run_all_tasks()<jupyter_output>2020-09-10 17:06:21,160 | WARNING | __init__ | Error testing roscore, message=Command '['rostopic', 'list']' returned non-zero exit status 1
2020-09-10 17:06:21,399 | WARNING | __init__ | Error testing roscore, message=Command '['rostopic', 'list']' returned non-zero exit status 1
2020-09-10 17:06:21,650 | WARNING | __init__ | Error testing roscore, message=Command '['rostopic', 'list']' returned non-zero exit status 1<jupyter_text>Once the simulation is running, an instance of the `GazeboProxy` object can be created to interact with it (e.g. spawn models).If not specified otherwise, the simulation is created with a random port for Gazebo and ROS master to enable multiple instances of the simulation to run in parallel.<jupyter_code>from pcg_gazebo.generators import WorldGenerator
import random
if ROS1_AVAILABLE:
    # Create a Gazebo proxy
    gazebo_proxy = simulation.get_gazebo_proxy()
    print('ROS configuration:')
    print(gazebo_proxy.ros_config)<jupyter_output>ROS configuration:
ROS_MASTER_URI=http://localhost:18566, GAZEBO_MASTER_URI=http://localhost:26418<jupyter_text>Create a single link box model.<jupyter_code>from pcg_gazebo.simulation import SimulationModel

obj = SimulationModel('box')

# By changing the size, collision, visual and inertial 
# properties are already going to be updated
obj.add_cuboid_link(
    link_name='link',
    size=[0.8, 0.7, 0.9],
    mass=30)

# Print the initial state of a box in the model option
print(obj.to_sdf())
# Set default friction parameters
obj.links['link'].collisions[0].enable_property('friction')
print(obj.to_sdf('model'))
obj.links['link'].collisions[0].set_ode_friction_params(
    mu=0.9,
    mu2=0.5,
    slip1=0.3, 
    slip2=0.5,
    fdir1=[0, 0, 0]
)
print(obj.to_sdf('model'))
mu = [0.1, 0.3, 0.5, 0.7, 1.0] 
for i in range(len(mu)):
    print('\t - #{} mu = {}'.format(i, mu[i]))
    obj.links['link'].collisions[0].set_ode_friction_params(
        mu=mu[i],
        mu2=mu[i],
        slip1=0.0, 
        slip2=0.0)
    print(obj.links['link'].collisions[0].to_sdf())
    # Set a random XKCD color to each box
    obj.links['link'].visuals[0].set_xkcd_color()
    obj.name = 'box_mu_{}'.format(mu[i])
    obj.pose = [0, i, 2, 0, 0, 0]
    if ROS1_AVAILABLE:
        obj.spawn(gazebo_proxy=gazebo_proxy)<jupyter_output>- #0 mu = 0.1
<collision name="collision">
  <surface>
    <friction>
      <ode>
        <slip1>0.0</slip1>
        <slip2>0.0</slip2>
        <fdir1>0 0 0</fdir1>
        <mu2>0.1</mu2>
        <mu>0.1</mu>
      </ode>
    </friction>
  </surface>
  <pose frame="">0 0 0 0 -0 0</pose>
  <geometry>
    <box>
      <size>0.8 0.7 0.9</size>
    </box>
  </geometry>
</collision>

line 81.
line 82.
	 - #1 mu = 0.3
<collision name="collision">
  <surface>
    <friction>
      <ode>
        <slip1>0.0</slip1>
        <slip2>0.0</slip2>
        <fdir1>0 0 0</fdir1>
        <mu2>0.3</mu2>
        <mu>0.3</mu>
      </ode>
    </friction>
  </surface>
  <pose frame="">0 0 0 0 -0 0</pose>
  <geometry>
    <box>
      <size>0.8 0.7 0.9</size>
    </box>
  </geometry>
</collision>

line 81.
line 82.
	 - #2 mu = 0.5
<collision name="collision">
  <surface>
    <friction>
      <ode>
        <slip1>0.0</slip1>
        <slip2>0.0</slip2>
        <fdir1>0 0 0</fdir1>
        <mu2>0.5</mu2>
        [...]<jupyter_text>![sim_boxes](images/sim_boxes.png)Apply a force to each box to see the effects of the different friction coefficients.<jupyter_code>if ROS1_AVAILABLE:
    for i in range(len(mu)):
        gazebo_proxy.apply_body_wrench(
            model_name='box_mu_{}'.format(mu[i]),
            link_name='link',
            force=[300, 0, 0],
            torque=[0, 0, 0],
            start_time=0,
            duration=2
            )<jupyter_output><empty_output><jupyter_text>![sim_boxes_after_wrench](images/sim_boxes_after_wrench.png)  Create a mobile baseRecreating the [Gazebo tutorial for a mobile base](http://gazebosim.org/tutorials/?tut=attach_gripperMobileBase)<jupyter_code>from pcg_gazebo.simulation import create_object
# Creating the main body of the chassis
chassis = create_object('box')
chassis.size = [2, 1, 0.3]
chassis.add_inertial(20)
chassis.visual.enable_property('material')
chassis.visual.set_xkcd_color()

print(chassis.to_sdf('link'))
# Creating the caster wheel
caster_wheel = create_object('sphere')
caster_wheel.radius = 0.125
caster_wheel.add_inertial(1)
caster_wheel.visual.enable_property('material')
caster_wheel.visual.set_xkcd_color()

# Setting friction parameters to zero
caster_wheel.collision.enable_property('friction')
caster_wheel.collision.set_ode_friction_params(
    mu=0.0,
    mu2=0.0,
    slip1=0, 
    slip2=0,
    fdir1=[0, 0, 0]
)

caster_wheel.collision.set_bullet_friction_params(
    friction=0.0, 
    friction2=0.0, 
    fdir1=[0, 0, 0], 
    rolling_friction=1
)

print(caster_wheel.to_sdf('link'))
right_wheel = create_object('cylinder')
right_wheel.pose = [-0.8, -0.5 - 0.025, -0.125, 0, 1.5707, 1.5707]
right_wheel.radius = 0.125
right_wheel.length = 0.05
right_wheel.add_inertial(1)
right_wheel.visual.enable_property('material')
right_wheel.visual.set_xkcd_color()

left_wheel = create_object('cylinder')
left_wheel.pose = [-0.8, 0.5 + 0.025, -0.125, 0, 1.5707, 1.5707]
left_wheel.radius = 0.125
left_wheel.length = 0.05
left_wheel.add_inertial(1)
left_wheel.visual.enable_property('material')
left_wheel.visual.set_xkcd_color()

print(right_wheel.to_sdf('link'))
# Assembling the robot mobile base
mobile_base = SimulationModel('mobile_base')

# Adding chassis
mobile_base.add_link('chassis', chassis)

# Adding caster wheel
caster_wheel.pose = [0.8, 0, -0.125, 0, 0, 0]
mobile_base.add_link('caster_wheel', caster_wheel)
mobile_base.add_joint('caster_wheel_joint', parent='chassis', child='caster_wheel', joint_type='fixed')

# Adding left wheel
mobile_base.add_link('left_wheel', left_wheel)
mobile_base.add_joint('left_wheel_joint', parent='chassis', child='left_wheel', joint_type='revolute')

# Adding right wheel
mobile_base.add_link('right_wheel', right_wheel)
mobile_base.add_joint('right_wheel_joint', parent='chassis', child='right_wheel', joint_type='revolute')

print(mobile_base.to_sdf())
print(mobile_base.to_urdf())
if ROS1_AVAILABLE:
    mobile_base.spawn(
        gazebo_proxy=gazebo_proxy,
        pos=[0, 0, 0.5])<jupyter_output>line 81.
line 82.<jupyter_text>![sim_mobile_base](images/sim_mobile_base.png)  Add sensors to mobile base<jupyter_code># Add IMU sensor
mobile_base.add_imu_sensor(
    parent='chassis',
    add_visual=True, 
    add_collision=True, 
    visualize=True,
    mass=0.01,
    size=[0.1, 0.1, 0.1],
    topic='/imu',
    link_shape='cuboid',
    link_name='imu_link')

# Add contact sensor
mobile_base.add_contact_sensor(
    pose=[1, 0, 0, 0, 0, 0],
    parent='chassis',
    add_visual=True, 
    add_collision=True, 
    add_ros_plugin=True,
    mass=0.01,
    radius=0.05,
    length=0.1,
    link_shape='cylindrical',
    link_name='contact_link')

# Add camera sensor
mobile_base.add_camera_sensor(
    pose=[1, 0, 0.2, 0, 0, 0],
    parent='chassis',
    add_visual=True, 
    add_collision=True, 
    add_ros_plugin=True,
    visualize=True,
    mass=0.01,
    size=[0.1, 0.1, 0.1],
    link_shape='cuboid',
    link_name='camera_link')
print(mobile_base.to_sdf())
if ROS1_AVAILABLE:
    mobile_base.spawn(
        gazebo_proxy=gazebo_proxy,
        robot_namespace='mobile_base_with_sensor',
        pos=[0, 2.0, 0.5])<jupyter_output>line 81.
line 82.<jupyter_text>![sim_modified_mobile_base](images/sim_modified_mobile_base.png)<jupyter_code>if ROS1_AVAILABLE:
    simulation.kill_all_tasks()<jupyter_output>2020-09-10 17:18:51,553 | WARNING | task | Task <gazebo> - Killing process tree...
2020-09-10 17:18:51,561 | WARNING | task | Sending SIGINT to child process id=8941
2020-09-10 17:18:51,562 | WARNING | task | Child process 8941 still running
2020-09-10 17:18:51,562 | WARNING | task | Sending SIGINT to child process id=8964
2020-09-10 17:18:51,563 | WARNING | task | Child process 8964 still running
2020-09-10 17:18:51,564 | WARNING | task | Sending SIGINT to child process id=8959
2020-09-10 17:18:51,564 | WARNING | task | Child process 8959 still running
2020-09-10 17:18:51,565 | WARNING | task | Sending SIGINT to child process id=9034
2020-09-10 17:18:51,566 | WARNING | task | Child process 9034 still running
2020-09-10 17:18:51,567 | WARNING | task | Sending SIGINT to child process id=9028
2020-09-10 17:18:51,567 | WARNING | task | Child process 9028 still running
2020-09-10 17:18:51,568 | WARNING | task | Sending SIGINT to child process id=8940
2020-09-10 17:18:51,569 | WARNING | tas[...]<jupyter_text>Export generated modelSimulation models can be exported as an SDF, URDF or as a static Gazebo model.In case the Gazebo model is exported, it can be stored in a provided folder path or it will be stored per default in `$HOME/.gazebo/models`.<jupyter_code>model_path = mobile_base.to_gazebo_model(overwrite=True)
import os
print('Gazebo model folder: ', model_path)
print(os.listdir(model_path))
mobile_base.to_urdf().export_xml(os.path.join(model_path, 'model.urdf'))
print(os.listdir(model_path))<jupyter_output>line 81.
line 82.
['model.sdf', 'model.urdf', 'model.config']
{'fraction_non_alphanumeric': 0.12910510962642327, 'fraction_numerical': 0.062482356262350616, 'mean_word_length': 4.070610687022901, 'pattern_counts': {'":': 0, '<': 91, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '527694', 'license': 'ECL-2.0', 'n_tokens_mistral': 4377, 'n_tokens_neox': 3938, 'n_words': 880, 'path': 'examples/sim_creating_models_with_jupyter_notebooks.ipynb', 'repo_name': 'GimpelZhang/pcg_gazebo', 'size': '10627'}