ppovb5fc7/gazebo/test/worlds/friction_spheres.world.erb

183 lines
5.7 KiB
Plaintext

<?xml version="1.0" ?>
<%= "<!-- this file was generated using embedded ruby -->" %>
<sdf version='1.6'>
<world name='default'>
<gui>
<camera name='user_camera'>
<pose>17 3 22 0 1.1 <%= Math::PI %></pose>
<view_controller>orbit</view_controller>
</camera>
</gui>
<include>
<uri>model://sun</uri>
</include>
<include>
<uri>model://ground_plane</uri>
</include>
<gravity>0 2 -9.81</gravity>
<%
# World with several models with varying number of collision spheres
# SI units (length in meters)
require "matrix"
def a_to_s(v)
Array(v).join(" ")
end
# Geometry
ball_radius = 0.2
face_altitude = 0.5
side_length = face_altitude / (Math::sqrt(3) / 2.0)
ball_volume = 4.0 / 3.0 * Math::PI * ball_radius**3
def sphere_collision(name_suffix, pos, radius, color="Green", slip=1, friction=0.5)
"""<collision name='collision_#{name_suffix}'>
<pose>#{ a_to_s(pos) } 0 0 0</pose>
<geometry>
<sphere>
<radius>#{ radius }</radius>
</sphere>
</geometry>
<surface>
<friction>
<ode>
<mu>#{ friction }</mu>
<mu2>#{ friction }</mu2>
<slip1>#{ slip }</slip1>
<slip2>#{ slip }</slip2>
</ode>
</friction>
</surface>
</collision>
<visual name='visual_#{ name_suffix }'>
<pose>#{ a_to_s(pos) } 0 0 0</pose>
<geometry>
<sphere>
<radius>#{ radius }</radius>
</sphere>
</geometry>
<material>
<script>
<uri>file://media/materials/scripts/gazebo.material</uri>
<name>Gazebo/#{ color }</name>
</script>
</material>
</visual>"""
end
models = {}
# "lowball" has one collision sphere with a hanging center of mass,
# which makes the ball slide instead of roll
models["lowball"] = {
:inertia_offset => Vector[0, 0, -0.3],
:ball_locations => {
"a" => Vector[0, 0, 0] ,
}
}
# "twoball" has two collision spheres
# it will slide in one direction and roll in the other direction
models["twoball"] = {
:ball_locations => {
"a" => Vector[0, side_length / 2.0, 0] ,
"b" => Vector[0, -side_length / 2.0, 0] ,
}
}
# "triball" has three collision spheres arranged in an equilateral triangle
# it will slide in any direction
models["triball"] = {
:ball_locations => {
"a" => Vector[ 2.0 / 3.0 * face_altitude, 0, 0] ,
"b" => Vector[-1.0 / 3.0 * face_altitude, side_length / 2.0, 0] ,
"c" => Vector[-1.0 / 3.0 * face_altitude, -side_length / 2.0, 0] ,
}
}
# there are several pairs of test cases
# each pair has the same product of mass and slip,
mass_slip = {}
mass_slip["0.2a"] = { :mass => 1.0, :slip => 0.2, :color => "Red"}
mass_slip["0.2b"] = { :mass => 2.0, :slip => 0.1, :color => "Red"}
mass_slip["0.4a"] = { :mass => 2.0, :slip => 0.2, :color => "Green"}
mass_slip["0.4b"] = { :mass => 4.0, :slip => 0.1, :color => "Green"}
mass_slip["0.6a"] = { :mass => 3.0, :slip => 0.2, :color => "Blue"}
mass_slip["0.6b"] = { :mass => 6.0, :slip => 0.1, :color => "Blue"}
models.keys.each_with_index do |model_prefix, i|
model = models[model_prefix]
ball_locations = model[:ball_locations]
ball_count = ball_locations.length
inertia_offset = model[:inertia_offset]
inertia_offset = model.key?(:inertia_offset) ? model[:inertia_offset] : Vector[0, 0, 0]
mass_slip.keys.each_with_index do |ms_name, ii|
ms = mass_slip[ms_name]
mass = ms[:mass]
slip = ms[:slip]
color = ms[:color]
# inertia
link_mass = mass
ball_mass = link_mass * 1.0/ball_count
ball_ixx = 2.0/5.0 * ball_mass * ball_radius**2
ball_iyy = 2.0/5.0 * ball_mass * ball_radius**2
ball_izz = 2.0/5.0 * ball_mass * ball_radius**2
# center of mass (com) and lumped inertia of balls
ball_com = Vector[0, 0, 0]
ball_locations.keys.each do |k|
ball_com += ball_locations[k] / ball_count
end
link_ixx = ball_count * ball_ixx
link_iyy = ball_count * ball_iyy
link_izz = ball_count * ball_izz
link_ixy = 0.0
link_ixz = 0.0
link_iyz = 0.0
ball_locations.keys.each do |k|
dx = ball_locations[k][0] - ball_com[0]
dy = ball_locations[k][1] - ball_com[1]
dz = ball_locations[k][2] - ball_com[2]
link_ixx += ball_mass * (dy**2 + dz**2)
link_iyy += ball_mass * (dz**2 + dx**2)
link_izz += ball_mass * (dx**2 + dy**2)
link_ixy -= ball_mass * dx*dy
link_ixz -= ball_mass * dx*dz
link_iyz -= ball_mass * dy*dz
end
model_name = "#{model_prefix}_#{ms_name}"
model_pose = Vector[2*ii, -2*i, 0, 0, 0, 0]
%>
<model name="<%= model_name %>">
<pose><%= a_to_s(model_pose) %></pose>
<link name="link">
<pose>0 0 <%= ball_radius %> 0 0 0</pose>
<inertial>
<pose><%= a_to_s(ball_com + inertia_offset) %> 0 0 0</pose>
<mass><%= link_mass %></mass>
<inertia>
<ixx><%= link_ixx %></ixx>
<iyy><%= link_iyy %></iyy>
<izz><%= link_izz %></izz>
<ixy><%= link_ixy %></ixy>
<ixz><%= link_ixz %></ixz>
<iyz><%= link_iyz %></iyz>
</inertia>
</inertial>
<%
# Place sphere collision and visual at each corner
ball_locations.keys.each_index do |first|
key = ball_locations.keys[first]
pos = ball_locations[key]
%>
<%= sphere_collision(key, pos, ball_radius, color, slip) %>
<%
end
%>
</link>
</model>
<%
end
end
%>
</world>
</sdf>