Robotics StackExchange | Archived questions

Add fog to gazebo using rospy

Hi,

I have been trying to create a script that will spawn objects and take images of them for object detection. I would like to simulate difficult conditions where there might be fog present, and have the level of fog vary between each image I am taking. However, I am not sure how to change gazebo world settings using a rospy script. I am aware that I can change the <scene> tag in the .world file, however this is less than ideal as I would like the fog level to update automatically within my script. I have been searching for a while on any solutions to this and have not found any. Any help on this would be appreciated, thanks!

Asked by jdastoor3 on 2021-12-11 16:08:22 UTC

Comments

Have you looked into pygazebo?

It’s in Python2 documentation link: https://buildmedia.readthedocs.org/media/pdf/pygazebo/latest/pygazebo.pdf#page27

But there is py3gazebo fork: https://github.com/wil3/py3gazebo

Asked by osilva on 2021-12-11 16:48:50 UTC

I tried doing that just now, and I get an error saying "cannot import name 'connect' from partially initialized module 'pygazebo' (most likely due to a circular import)". I pip installed pygazebo.

from pygazebo.msg import fog_pb2

if __name__ == "__main__":
   fog_pb2.Fog(density=1)

Asked by jdastoor3 on 2021-12-11 17:48:07 UTC

Just a watch out if you install via pip is Python2 and you need a complimentary library

Check the example in: https://github.com/jpieper/pygazebo

Asked by osilva on 2021-12-11 18:04:00 UTC

I followed the steps at the bottom of py3gazebo to convert the python2 version to the python3 version, yet that still gives me the same error.

Asked by jdastoor3 on 2021-12-11 18:27:14 UTC

Update: I managed to get a bit further, but now I get another error in pygazebo.py: line 251,

future = asyncio.async(loop.sock_connect(self.socket, address))
                 ^
SyntaxError : invalid syntax

Asked by jdastoor3 on 2021-12-11 18:41:50 UTC

I used it back in Kinetic, there a few errors. I just tried it as well and fixing them

Asked by osilva on 2021-12-11 19:46:13 UTC

Answers

Hi @jdastoor3

Apologies for suggesting pygazebo, I was able to make it work but there are many bugs. Instead, I went over again and I think using Gazebo Services is the way to go:

After you launch gazebo using roslaunch gazebo_ros empty_world.launch in another terminal you can check services available: rosservice list If you look into: rosservice info /gazebo/set_light_properties you will get:

Node: /gazebo

    URI: rosrpc://127....
    Type: gazebo_msgs/SetLightProperties
    Args: light_name cast_shadows diffuse specular attenuation_constant attenuation_linear attenuation_quadratic direction pose

And if you look further into this by rossrv show gazebo_msgs/SetLightProperties

string light_name
bool cast_shadows
std_msgs/ColorRGBA diffuse
  float32 r
  float32 g
  float32 b
  float32 a
std_msgs/ColorRGBA specular
  float32 r
  float32 g
  float32 b
  float32 a
float64 attenuation_constant
float64 attenuation_linear
float64 attenuation_quadratic
geometry_msgs/Vector3 direction
  float64 x
  float64 y
  float64 z
geometry_msgs/Pose pose
  geometry_msgs/Point position
    float64 x
    float64 y
    float64 z
  geometry_msgs/Quaternion orientation
    float64 x
    float64 y
    float64 z
    float64 w
---
bool success
string status_message

To access with Python, I wrote this script:

#!/usr/bin/env python
import time
import rospy

from gazebo_msgs.srv import SetPhysicsProperties, SetPhysicsPropertiesRequest
from gazebo_msgs.srv import SetLightProperties, SetLightPropertiesRequest
from geometry_msgs.msg import Pose, Quaternion
from geometry_msgs.msg import Vector3
from std_msgs.msg import Float64    
from std_msgs.msg import ColorRGBA  
from std_srvs.srv import Empty 

service_name = '/gazebo/set_light_properties'
rospy.loginfo("Waiting for service " + str(service_name))
rospy.wait_for_service(service_name)
rospy.loginfo("Service Found "+str(service_name))

set_light = rospy.ServiceProxy(service_name, SetLightProperties)

light_name = 'sun'
cast_shadows = True

difuse = ColorRGBA()
difuse.r = float(204/255)
difuse.g = float(204/255)
difuse.b = float(204/255)
difuse.a = float(255/255)

specular = ColorRGBA()
specular.r = float(51/255)
specular.g = float(51/255)
specular.b = float(51/255)
specular.a = float(255/255)

attenuation_constant = 0.90
attenuation_linear = 0.01
attenuation_qudratic = 0.00

direction = Vector3()
direction.x = -0.483368
direction.y = 0.096674
direction.z = -0.870063

pose = Pose()
pose.position.x = 0.00
pose.position.y = 0.00
pose.position.z = 10.00

pose.orientation.x = 0.00
pose.orientation.y = 0.00
pose.orientation.z = 0.00
pose.orientation.w = 1.00

response = set_light(light_name, cast_shadows, difuse, specular, attenuation_constant, attenuation_linear, attenuation_qudratic, direction, pose)

print(response)

I am using the default settings that you can see in Gazebo:

image description

Hope this helps you, then you can change light conditions or other properties to set fog.

Asked by osilva on 2021-12-13 10:21:30 UTC

Comments

There is an example of subsea world that you can use for fog settings: https://github.com/uuvsimulator/uuv_simulator/blob/master/uuv_gazebo_worlds/worlds/subsea_bop_panel.world

Tutorial: https://uuvsimulator.github.io/packages/uuv_simulator/docs/features/gazebo_worlds/

For ODE Physics you will need as an example:

from gazebo_msgs.msg import ODEPhysics
ode_config = ODEPhysics()
ode_config.auto_disable_bodies = False
ode_config.sor_pgs_precon_iters = 0
ode_config.sor_pgs_iters = 50
ode_config.sor_pgs_w = 1.3
ode_config.sor_pgs_rms_error_tol = 0.0
ode_config.contact_surface_layer = 0.001
ode_config.contact_max_correcting_vel = 0.0
ode_config.cfm = 0.0
ode_config.erp = 0.2
ode_config.max_contacts = 20

Asked by osilva on 2021-12-13 10:40:46 UTC

Thank you for the response! I tried using SetLightProperties, however the light only seems to have an impact on the land, not on the water, which remains the same color (where I care about the impact the most). I also don't think pygazebo is the best way because I think it only works on Python 3.6, which is why it was not working for me.

Asked by jdastoor3 on 2021-12-13 12:36:26 UTC

Check the example of subsea. You can change the sky with any material + lights might do the trick

Asked by osilva on 2021-12-13 12:49:53 UTC

Also you can set this at the .sdf level first: http://sdformat.org/spec?ver=1.5&elem=scene#scene_sky

Asked by osilva on 2021-12-13 12:57:46 UTC

I want to be able to change the fog level inside my script during each main loop. So I can set the base fog level in the <scene> tag, but I would like a way to do it in Python. The subsea example looks like it's just set in the .world file

Asked by jdastoor3 on 2021-12-13 13:17:24 UTC

Only way to get at that level that I am aware is thru Gazebo API in C++

Asked by osilva on 2021-12-13 13:19:13 UTC

Or you could ‘cheat’ and just change the world file with different settings

Asked by osilva on 2021-12-13 13:20:04 UTC

Using pygazebo, did you have to use python 3.6?

Asked by jdastoor3 on 2021-12-13 15:19:29 UTC

I was able to use 3.9 with some tweaking, check my changes: https://github.com/robogeekcanada/STEMClub/tree/master/pygazebo

Asked by osilva on 2021-12-13 15:27:54 UTC

but not fully tested. Still looking at how to get to level with Python dynamically.

Asked by osilva on 2021-12-13 15:28:29 UTC

i think if you go to msg folder, there is scence_pb2.py that could be changed to do this. I will try later today.

Asked by osilva on 2021-12-13 15:46:06 UTC

I've got py3gazebo working now with the tweaks you made and am able to call the fog_pb2 file in the msg folder without any errors. However, it doesn't change anything in the actual gazebo world... strange

Asked by jdastoor3 on 2021-12-13 16:05:55 UTC

Yes I don’t know if asyncio is connecting properly. It runs but it’s not behaving the way is supposed to

Asked by osilva on 2021-12-13 16:14:55 UTC

Ya it does not seem to be connecting for me either. I tried using trollius instead, but that also did not work.

Asked by jdastoor3 on 2021-12-13 17:24:03 UTC

I fixed most of the bugs with pygazebo, updated in the same repo. Also was able to get a subscriber example to work, I added it as well. I will work on a publisher, then play with fog.

Asked by osilva on 2021-12-14 18:45:23 UTC

Thank you so much!

Asked by jdastoor3 on 2021-12-15 11:16:12 UTC

Hi, I have tried to add a publisher, however I get an error saying .publish is not a feature of asyncio.Future

Asked by jdastoor3 on 2021-12-18 18:23:44 UTC