Gazebo simulation stop working after moving few model

I’m running a simulation in Gazebo Fortress with the TurtleBot4 robot. In this environment a need to stop and restart the simulation multiple times and move the objects that are just a cylindrical model. I need to check the positions of the objects every time I move them, to do it I use the function called generate_random_position_object in the following script. The problem is when I do it with several objects the simulation stops working properly, that is the robot doesn’t move anymore even if it receives the linear and angular velocities commands different from zeros.

I don’t understand why this is possible. Also, everything works properly if I run the same simulation with moving only 5 objects. I don’t know if the problem is related to the number of calls to a service that Gazebo has to handle. From the log file, as far as I can see, the call to the service is executed properly since it returns the following statement data: true.

I’m running the simulation on a HPC cluster, I specify this since the same simulation doesn’t have any problem if I execute it on my local PC.

#!/bin/bash

source /opt/ros/humble/setup.bash
source /workspace/turtlebot4_minimize_surprise/install/setup.bash 


SIMULATION_TIME=60

# set spawn limit turtlebot4
X_MIN_TB=-1.8
X_MAX_TB=1.8
Y_MIN_TB=-0.2
Y_MAX_TB=3.5

# set spawn limit objects
X_MIN_OBJ=-1.8
X_MAX_OBJ=1.8
Y_MIN_OBJ=2.6
Y_MAX_OBJ=3.5

# variables to store turtlebot4 starting position and orientation
TURTLEBOT_X=0
TURTLEBOT_Y=0
TURTLEBOT_Z=0
TURTLEBOT_QX=0
TURTLEBOT_QY=0
TURTLEBOT_QZ=0
TURTLEBOT_QW=1

# variables to store objects position
OBJECT1_X=0
OBJECT1_Y=0
OBJECT2_X=0
OBJECT2_Y=0
OBJECT3_X=0
OBJECT3_Y=0
OBJECT4_X=0
OBJECT4_Y=0
OBJECT5_X=0
OBJECT5_Y=0
OBJECT6_X=0
OBJECT6_Y=0
OBJECT7_X=0
OBJECT7_Y=0

OBJECT_Z=0.2

# array to store object positions and orientations
declare -A OBJECTS

# function to spawn random position turtlebot
generate_random_position_turtlebot() {
    local x_min=$1
    local x_max=$2
    local y_min=$3
    local y_max=$4

    # generate random coordinate within limits
    local x=$(awk -v min=$x_min -v max=$x_max -v seed=$RANDOM 'BEGIN{srand(seed); print min+rand()*(max-min)}')
    local y=$(awk -v min=$y_min -v max=$y_max -v seed=$RANDOM 'BEGIN{srand(seed); print min+rand()*(max-min)}')


    # generate z coordiante based on y values
    local z
    #if (( $(echo "$y > 2.6" | bc -l) )); then # source limit
    #    z=0.11
    #elif (( $(echo "$y >= 1.5 && $y <= 2.6" | bc -l) )); then # slope limits
    #    z=0.09
    #else # cache and nest limit
    #    z=0.04
    #fi

    z=0.15

    # Assegna i valori generati alle variabili globali
    TURTLEBOT_X=$x
    TURTLEBOT_Y=$y
    TURTLEBOT_Z=$z
}

# function to spawn a random orientation (z-axis) turtlebot
generate_random_orientation_turtlebot() {
    # Generate a random yaw (rotation around z-axis) between 0 and 2*pi
    local yaw=$(awk 'BEGIN{srand(); print rand() * 2 * 3.14159265359}')

    # Convert the yaw to a quaternion (assuming no pitch or roll)
    TURTLEBOT_QX=0
    TURTLEBOT_QY=0
    TURTLEBOT_QZ=$(awk -v yaw=$yaw 'BEGIN{print sin(yaw / 2)}')
    TURTLEBOT_QW=$(awk -v yaw=$yaw 'BEGIN{print cos(yaw / 2)}')
}

generate_random_position_object() {
    local obj_id=$1

    while true; do
        local x=$(awk -v min=$X_MIN_OBJ -v max=$X_MAX_OBJ -v seed=$RANDOM 'BEGIN{srand(seed); print min+rand()*(max-min)}')
        local y=$(awk -v min=$Y_MIN_OBJ -v max=$Y_MAX_OBJ -v seed=$RANDOM 'BEGIN{srand(seed); print min+rand()*(max-min)}')


        # Check if the generated position is too close to the TurtleBot4
        local distance_to_turtlebot
        distance_to_turtlebot=$(awk -v x1=$TURTLEBOT_X -v y1=$TURTLEBOT_Y -v x2=$x -v y2=$y 'BEGIN{print sqrt((x2-x1)^2 + (y2-y1)^2)}')
        if (( $(echo "$distance_to_turtlebot <= 0.5" | bc -l) )); then
            continue
        fi

        # Check if the generated position is too close to any other objects
        local valid=true
        for existing_obj in OBJECT1 OBJECT2 OBJECT3 OBJECT4 OBJECT5 OBJECT6 OBJECT7; do
            local obj_x=${existing_obj}_X
            local obj_y=${existing_obj}_Y
            local distance_to_obj
            distance_to_obj=$(awk -v x1=${!obj_x} -v y1=${!obj_y} -v x2=$x -v y2=$y 'BEGIN{print sqrt((x2-x1)^2 + (y2-y1)^2)}')
            if (( $(echo "$distance_to_obj <= 0.2" | bc -l) )); then
                valid=false
                break
            fi
        done

        if [ "$valid" = true ]; then
            eval "OBJECT${obj_id}_X=$x"
            eval "OBJECT${obj_id}_Y=$y"
            break
        fi
    done

    ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object$obj_id' position: { x: $(eval echo \$OBJECT${obj_id}_X), y: $(eval echo \$OBJECT${obj_id}_Y), z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000    
    
    echo "respawned object${obj_id}"

}





simulation_id=$1
genome_id=$2

echo -e "\n---------------------------\nGenome ID: $genome_id, Simulation ID: $simulation_id\n---------------------------"

export ROS_DOMAIN_ID=$simulation_id && export IGN_PARTITION=$simulation_id

fastdds shm clean # https://github.com/eProsima/Fast-DDS/issues/2003#issuecomment-1160245640

while true; do
    echo "Update genome_id"
    timeout 10 ros2 param set /ann_controller genome_id  $genome_id # set the genome_id
    result=$?
    echo "Exit code: $result"
    if [ $result -eq 0 ]; then break; fi
    sleep 2
done

echo "set new genome"
sleep 5

while true; do
    timeout 10 ros2 param set /ann_controller update_genome_id True
    result=$?
    echo "Exit code: $result"
    if [ $result -eq 0 ]; then break; fi
    sleep 2
done

echo "enabled genome"

# generate random position turtlebot4
generate_random_position_turtlebot $X_MIN_TB $X_MAX_TB $Y_MIN_TB $Y_MAX_TB
sleep 2

# generate random orientation turtlebot4
generate_random_orientation_turtlebot
sleep 2


# # reset turtlebot4 position
echo "Respawning turtlebot4"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'turtlebot4' position: { x: $TURTLEBOT_X, y: $TURTLEBOT_Y, z: $TURTLEBOT_Z } orientation: { x: $TURTLEBOT_QX, y: $TURTLEBOT_QY, z: $TURTLEBOT_QZ, w: $TURTLEBOT_QW}" --timeout 2000
#sleep 2


# Generate and set positions for objects individually
echo "Respawning object1"
generate_random_position_object "1"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object1' position: { x: $OBJECT1_X, y: $OBJECT1_Y, z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000
#sleep 2

echo "Respawning object2"
generate_random_position_object "2"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object2' position: { x: $OBJECT2_X, y: $OBJECT2_Y, z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000
#sleep 2

echo "Respawning object3"
generate_random_position_object "3"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object3' position: { x: $OBJECT3_X, y: $OBJECT3_Y, z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000
#sleep 2

echo "Respawning object4"
generate_random_position_object "4"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object4' position: { x: $OBJECT4_X, y: $OBJECT4_Y, z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000
#sleep 2

echo "Respawning object5"
generate_random_position_object "5"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object5' position: { x: $OBJECT5_X, y: $OBJECT5_Y, z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000
#sleep 2

echo "Respawning object6"
generate_random_position_object "6"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object6' position: { x: $OBJECT6_X, y: $OBJECT6_Y, z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000
#sleep 2

echo "Respawning object7"
generate_random_position_object "7"
#ign service -s /world/arena/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --req "name: 'object7' position: { x: $OBJECT7_X, y: $OBJECT7_Y, z: $OBJECT_Z} orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }" --timeout 2000
#sleep 2

# start simulation
echo -e "start simulation\n"
ign service -s /world/arena/control --reqtype ignition.msgs.WorldControl --reptype ignition.msgs.Boolean --timeout 5000 --req 'pause: false'

#sleep $SIMULATION_TIME & # simulation time 


# record the rosbag
ros2 bag record -o log2/$genome_id/bag \
    /model/turtlebot4/pose \
    /cmd_vel \
    /cliff_sensor_front_left \
    /cliff_sensor_front_right \
    /cliff_sensor_side_left \
    /cliff_sensor_side_right \
    /light_sensor_frontL \
    /light_sensor_frontR \
    /light_sensor_back \
    /hazard_detection \
    /scan \
    /model/object1/pose \
    /model/object2/pose \
    /model/object3/pose \
    /model/object4/pose \
    /model/object5/pose \
    /model/object6/pose \
    /model/object7/pose &

BAG_PID=$!
sleep $SIMULATION_TIME

kill $BAG_PID

sleep 2

echo "save score"
ros2 topic echo /fitness_topic --once > log2/$genome_id/score.txt # store the score
sleep 2

echo "stop simulation"
ign service -s /world/arena/control --reqtype ignition.msgs.WorldControl --reptype ignition.msgs.Boolean --timeout 5000 --req 'pause: true' # stop simulation
sleep 2