为模型添加颜色和纹理
本教程描述了颜色在gazebo上的工作原理。读完之后,你会知道如何让仿真对象看起来更像真实世界中的对象。
关于Ambient, Diffuse, Specular, and Emissive
在这一节的最后,你会知道什么参数与颜色的关系,以及它们是如何工作的。
使用Blinn-Phong shading model确定物体的颜色。有四个组件控制颜色:ambient、diffuse、specular和发emissive。OpenGL编程指南中关于照明的章节详细介绍了这些是如何工作的。
材料反射的光的成分
物体的最终颜色取决于材料和照射在其上的光线。光线值代表发出的光的强度。材料值代表物体反射的光的百分比。同一种材料可能有不同的颜色,取决于照到它们的光。
例如,考虑具有RGBA漫射颜色(1,1,0.5,1.0)的材料。在白光下,它看起来是黄色的。如果暴露在发出漫射RGBA(0 1 0 1)的光下,它将呈现绿色。如果暴露在发出漫射RGBA(1 0 0 1)的光下,它会呈现红色。具有漫射RGBA(0 0 0 0.75 1)的光会使物体呈现深蓝色。
Ambient
Ambient light 是没有光线指向物体时物体的颜色。与物体本身是完全一致的。Ambient light的意思是已经被反射了很多次、很难分辨它是从哪里来的近似的光。
Diffuse
这是纯白色光线下物体的颜色。它是用光的方向和物体表面法线计算的。物体中正对光部分为最亮的。
Specula
Specular是来自镜面反射高光的颜色和光强,会使物体看起来更有光泽。抛光的金属表面会有很大的镜面反射值,而一张纸几乎没有镜面反射值。
Emissive
Emissive只能设置在材料上。像ambient一样,emissive给物体增加颜色。看起来好像光是从物体发出的,但emissive不会给其他物体施加光照。
成分对比
四个成分中的每一个都会给物体添加颜色。物体的最终颜色是所有成分的总和。求和后,如果任何红色、绿色或蓝色值超过1.0,则设置为1.0。
颜色参数在哪里设置
指定物体的颜色需要对灯光和物体的材质都进行设置。看过这一节,你将知道光和模型的颜色参数在哪里设置,以及如何调整它们。
设置光的颜色成分值
浅色可以在世界SDF文件中指定。Ambient light在< scene >中全局设置。Ambient light数量是可由你选定。室内环境可能需要一个大的全局ambient light,因为每面墙和表面都会反射光。卫星模拟基本可以不要ambient light,因为大多数都辐射到太空中。
< light >里的< specular >和< diffuse>标签设置diffuse颜色和specular反射。这些标签需要4个介于0.0和1.0之间的浮点数(RGBA)。最后一个数字(alpha)对灯光没有影响。
光没有emissive和ambient成分。
设置物体的颜色成分值
物体上的颜色成分可以在SDF、Ogre Material Script或某些类型的meshes中设置。
SDF
每个< visual>都有一个< material >标签,用于控制物体的颜色成分。这些标签是:
- < ambient >
- < diffuse >
- < specular >
Note: Specular intensity via SDF is currently not functioning in gazebo. See issue #2120 - < emmissive >
Ogre Material Script
- ambient
- diffuse
- specular
- emissive
如果同时设置了SDF和Ogre Material Script,则SDF值用于ambient,diffuse,和emissive。如果两者都定义了specular,那么最终的specular就是Ogre Material Script和SDF值的相加。
Collada and OBJ meshes
如果visual使用了Collada(.dae)或Wavefront (obj)的mesh,则gazebo从这些格式里寻找颜色的值
物体的Collada颜色分量取自< phong >(第8-69页)效果。如果collada mesh没有任何效果,那么在gazebo7中,它将被显示为具有RGBA(1 1 1 1)的emissive值。在gazebo8+中,它将显示灰色diffuse和ambient,但没有emissive和specular。
Wavefront obj颜色来源于物体材料:Ka, Kd, Ks, Ns. 见wiki
Note: OBJ materials may not display correctly in versions earlier than gazebo 8.
关于纹理textures
纹理将图像映射到形状上。它在不添加几何图形的情况下向模型添加细节。
abmient light和diffuse light可以使得纹理被看到。
给物体设置纹理
Ogre Material Scripts
Ogre Material Scripts有许多选项可以将纹理应用到物体上。阅读Ogre Document了解更多信息。
Collada
Collada文件可以对物体应用纹理。如何创建这样的文件超出了本教程的范围。Blender是一个开源建模工具,可以导出Collada。
确保< library_images >中的纹理路径可以关联到collada文件
给模型添加颜色和纹理的例子
这个示例会简单给出如何给基本模型添加颜色
基本文件和文件夹
mkdir ~/color_tutorial
颜色包括两部分:模型和光
光在世界文件中设置,所以建立一个世界文件,保存为:
~/color_tutorial/lit_world.world
它有一个有方向的明亮的白色光和ambient light。
<?xml version="1.0" ?>
<sdf version="1.6">
<world name="default">
<scene>
<ambient>0.4 0.4 0.4 1</ambient>
<background>0.25 0.25 0.25 1</background>
<shadows>false</shadows>
</scene>
<light type="directional" name="some_light">
<diffuse>0.7 0.7 0.7 0</diffuse>
<specular>1 1 1 0</specular>
<direction>-1 -1 -1</direction>
</light>
</world>
</sdf>
下一步创建模型。文件结构为:
models文件加必须在环境标量GAZEBO_MODEL_PATH中。本教程假定你使用了文件夹~/color_tutorial/models。
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/color_tutorial/models
创建模型
mkdir -p ~/color_tutorial/models/example_model/materials/scripts
mkdir -p ~/color_tutorial/models/example_model/materials/textures
mkdir -p ~/color_tutorial/models/example_model/materials/meshes
保存为文件model.config
<?xml version="1.0"?>
<model>
<name>Example Model For Color Tutorial</name>
<version>1.0</version>
<sdf version="1.6">model.sdf</sdf>
<author>
<name>YOUR NAME HERE</name>
<email>YOUR EMAIL HERE</email>
</author>
<description>
Example of adding color to a model
</description>
</model>
保存为文件model.config
<?xml version="1.0"?>
<sdf version="1.6">
<model name="Color Tutorial Model">
<static>true</static>
<link name="robot_link">
<collision name="body_collision">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="wheel1_visual">
<pose>-0.2 0 -0.25 0 1.57079 0</pose>
<geometry>
<cylinder>
<radius>0.05</radius>
<length>0.02</length>
</cylinder>
</geometry>
</visual>
<visual name="wheel2_visual">
<pose>0.2 0 -0.25 0 1.57079 0</pose>
<geometry>
<cylinder>
<radius>0.05</radius>
<length>0.02</length>
</cylinder>
</geometry>
</visual>
<visual name="power_led_visual">
<pose>0.225 0.225 0.25 0 0 0</pose>
<geometry>
<sphere>
<radius>0.003</radius>
</sphere>
</geometry>
</visual>
<visual name="body_visual">
<geometry>
<box>
<size>0.5 0.5 0.5</size>
</box>
</geometry>
</visual>
<visual name="head_visual">
<pose>0 0 0.25 0 0 -2.5</pose>
<geometry>
<sphere>
<radius>0.25</radius>
</sphere>
</geometry>
</visual>
</link>
</model>
</sdf>
用URDF给轮子和电源指示灯上颜色
车轮和电源指示灯将是单一的统一颜色,因此它们将使用SDF设置。本示例让轮子变成深蓝色的材料子。将其添加到两个车轮< visual >标签中。
<material> <!-- Wheel material -->
<ambient>0.1 0.1 0.1 1</ambient>
<diffuse>0.1 0.1 0.2 1</diffuse>
<specular>0 0 0 0</specular>
<emissive>0 0 0 1</emissive>
</material> <!-- End wheel material -->
电源指示灯是其自身的光源,因此将使用emissive。将此添加到power_led < visual >中,使其始终为全绿色。
<material> <!-- LED material -->
<ambient>0 0 0 1</ambient>
<diffuse>0 0 0 1</diffuse>
<specular>0 0 0 0</specular>
<emissive>0 1 0 1</emissive>
</material> <!-- End LED material -->
使用Ogre Material Script 上颜色
给物体覆盖纹理
将图像保存成seamless_texture.png
保存为repeated.material。它使纹理重复覆盖在正方体的每个面上
material RepeatedTexture
{
technique
{
pass
{
texture_unit
{
// Relative to the location of the material script
texture ../textures/seamless_texture.png
// Repeat the texture over the surface (4 per face)
scale 0.5 0.5
}
}
}
}
结果是立方体的每个面都有四份相同的seamless纹理
使用带有texture的collada上颜色
将图像保存成head_texture.png
下载head.dae
这个collada将图像作为纹理。我们需要检查路径。打开head.dae,查看< library_images >
<library_images>
<image id="head_texture_png" name="head_texture_png">
<init_from>head_texture.png</init_from>
</image>
</library_images>
模型应用图片没有路径信息。它默认png图片和head.dae同一文件夹下,但是我们想把它保存在另一文件夹下。在head.dae中更改图像路径
<library_images>
<image id="head_texture_png" name="head_texture_png">
<init_from>../materials/textures/head_texture.png</init_from>
</image>
</library_images>
最后在gazebo中打开
在gazebo中效果
模型路径必须被添加进环境变量GAZEBO_MODEL_PATH。设置后,打开gazebo
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/color_tutorial/models
gazebo --verbose ~/color_tutorial/lit_world.world
插入你创建的模型