Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reset WbFieldRef->last_update After Simulation Reset #6758

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/reference/changelog-r2025.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Webots R2025 Change Log

## Webots R2025b
- Bug Fixes
- Fixed a bug causing supervisors to occasionally read stale field values after the simulation was reset ([#6758](https://github.com/cyberbotics/webots/pull/6758)).

## Webots R2025a
Released on January 31st, 2025.
- New Features
Expand All @@ -24,7 +28,7 @@ Released on January 31st, 2025.
- Improved the image range of the rotating [Lidar](lidar.md) ([#6324](https://github.com/cyberbotics/webots/pull/6324)).
- Show box-plane contact point normals when showing contact points ([#6678](https://github.com/cyberbotics/webots/pull/6678)).
- Improved the speed and accuracy of box-plane collisions ([#6688](https://github.com/cyberbotics/webots/pull/6688)).
- Enabled the launching of MATLAB desktop from the extern launcher ([#6366](https://github.com/cyberbotics/webots/pull/6366)).
- Enabled the launching of MATLAB desktop from the extern launcher ([#6366](https://github.com/cyberbotics/webots/pull/6366)).
- Improved overlays visible in Overlays menu by adding all the robots in the menu list ([#6297](https://github.com/cyberbotics/webots/pull/6297)).
- Cleanup
- Removed deprecated `windowPosition`, `pixelSize` fields of [Display](display.md) node ([#6327](https://github.com/cyberbotics/webots/pull/6327)).
Expand Down
2 changes: 1 addition & 1 deletion src/controller/c/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
#define C_SUPERVISOR_RELOAD_WORLD 52
#define C_SUPERVISOR_SET_LABEL 53
#define C_SUPERVISOR_SIMULATION_QUIT 54
#define C_SUPERVISOR_SIMULATION_RESET 55
#define C_SUPERVISOR_SIMULATION_CHANGE_MODE 56
#define C_SUPERVISOR_SIMULATION_RESET_PHYSICS 57
#define C_SUPERVISOR_START_MOVIE 58
Expand All @@ -101,6 +100,7 @@
#define C_SUPERVISOR_NODE_GET_PROTO 78

// ctr <-> sim
#define C_SUPERVISOR_SIMULATION_RESET 55
#define C_ROBOT_WAIT_FOR_USER_INPUT_EVENT 80
#define C_ROBOT_WWI_MESSAGE 81
#define C_SUPERVISOR_SAVE_WORLD 82
Expand Down
9 changes: 9 additions & 0 deletions src/controller/c/supervisor.c
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,15 @@ static void supervisor_read_answer(WbDevice *d, WbRequest *r) {
case C_SUPERVISOR_MOVIE_STATUS:
movie_status = request_read_uchar(r);
break;
case C_SUPERVISOR_SIMULATION_RESET: {
// Clear cached field values
WbFieldStruct *field = field_list;
while (field) {
field->last_update = -DBL_MAX;
field = field->next;
}
break;
}
case C_SUPERVISOR_SAVE_WORLD:
save_status = request_read_uchar(r);
break;
Expand Down
12 changes: 12 additions & 0 deletions src/webots/nodes/utils/WbSupervisorUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ WbSupervisorUtilities::WbSupervisorUtilities(WbRobot *robot) : mRobot(robot) {
// otherwise, conflicts can occur in case of multiple controllers
connect(this, &WbSupervisorUtilities::changeSimulationModeRequested, this, &WbSupervisorUtilities::changeSimulationMode,
Qt::QueuedConnection);
connect(WbWorld::instance(), &WbWorld::resetRequested, this, &WbSupervisorUtilities::simulationReset, Qt::QueuedConnection);
}

WbSupervisorUtilities::~WbSupervisorUtilities() {
Expand Down Expand Up @@ -343,6 +344,7 @@ void WbSupervisorUtilities::initControllerRequests() {
mNodesDeletedSinceLastStep.clear();
mUpdatedFields.clear();
mWatchedFields.clear();
mSimulationReset = false;
}

QString WbSupervisorUtilities::readString(QDataStream &stream) {
Expand Down Expand Up @@ -2347,6 +2349,11 @@ void WbSupervisorUtilities::writeAnswer(WbDataStream &stream) {
}
mVirtualRealityHeadsetOrientationRequested = false;
}
if (mSimulationReset) {
stream << (short unsigned int)0;
stream << (unsigned char)C_SUPERVISOR_SIMULATION_RESET;
mSimulationReset = false;
}
}

void WbSupervisorUtilities::writeConfigure(WbDataStream &stream) {
Expand Down Expand Up @@ -2419,3 +2426,8 @@ QString WbSupervisorUtilities::createLabelUpdateString(const WbWrenLabelOverlay
.arg(y)
.arg(text.replace("\n", "\\n"));
}

void WbSupervisorUtilities::simulationReset(bool restartControllers) {
if (!restartControllers) // If the controller is about to be restarted, there's no need to tell it to reset its own state
mSimulationReset = true;
}
2 changes: 2 additions & 0 deletions src/webots/nodes/utils/WbSupervisorUtilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ private slots:
void removeTrackedContactPoints(QObject *obj);
void removeTrackedPoseNode(QObject *obj);
void removeTrackedField(QObject *obj);
void simulationReset(bool restartControllers);

private:
WbRobot *mRobot;
Expand Down Expand Up @@ -111,6 +112,7 @@ private slots:
bool mNodeExportStringRequest;
bool mIsProtoRegenerated;
bool mShouldRemoveNode;
bool mSimulationReset;

// pointer to a single integer: if not NULL, the new status has to be sent to the libController
int *mAnimationStartStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/supervisor_reset_simulation_fields
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 1996-2023 Cyberbotics Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Webots Makefile system
#
# You may add some variable definitions hereafter to customize the build process
# See documentation in $(WEBOTS_HOME_PATH)/resources/Makefile.include


# Do not modify the following: this includes Webots global Makefile.include
null :=
space := $(null) $(null)
WEBOTS_HOME_PATH?=$(subst $(space),\ ,$(strip $(subst \,/,$(WEBOTS_HOME))))
include $(WEBOTS_HOME_PATH)/resources/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Description: Test Supervisor device API
* This file contains tests of reset simulation method
*/

#include <webots/robot.h>
#include <webots/supervisor.h>

#include "../../../lib/ts_assertion.h"
#include "../../../lib/ts_utils.h"

#define TIME_STEP 32

int main(int argc, char **argv) {
ts_setup(argv[1]);

const double initial_translation[3] = {0, 0, 1};
const double new_translation[3] = {1, 0, 0};
WbFieldRef translation_field = wb_supervisor_node_get_field(wb_supervisor_node_get_from_def("SOLID"), "translation");
if (strcmp(argv[1], "supervisor_reset_simulation_fields_resetter") == 0) {
wb_robot_step(TIME_STEP);
wb_robot_step(TIME_STEP);

// <Other controller verifies SOLID's inital position>

wb_robot_step(TIME_STEP);
wb_supervisor_simulation_reset();
wb_robot_step(TIME_STEP); // We have to wait another step or else the reset will overwrite the new value
wb_supervisor_field_set_sf_vec3f(translation_field, new_translation);
} else {
wb_robot_step(TIME_STEP);
wb_robot_step(TIME_STEP);
const double *first_translation = wb_supervisor_field_get_sf_vec3f(translation_field);
ts_assert_vec3_equal(
first_translation[0], first_translation[1], first_translation[2], initial_translation[0], initial_translation[1],
initial_translation[2], "SOLID's initial position should be [%f, %f, %f] not [%f, %f, %f]", initial_translation[0],
initial_translation[1], initial_translation[2], first_translation[0], first_translation[1], first_translation[2]);
wb_robot_step(TIME_STEP);

// <Other controller resets the simulation>

wb_robot_step(TIME_STEP);

// <Other controller updates SOLID's position>

wb_robot_step(TIME_STEP);
const double *second_translation = wb_supervisor_field_get_sf_vec3f(translation_field);
ts_assert_vec3_equal(
second_translation[0], second_translation[1], second_translation[2], new_translation[0], new_translation[1],
new_translation[2], "SOLID's position should be [%f, %f, %f] not [%f, %f, %f] after reset", new_translation[0],
new_translation[1], new_translation[2], second_translation[0], second_translation[1], second_translation[2]);
}

ts_send_success();
return EXIT_SUCCESS;
}
53 changes: 53 additions & 0 deletions tests/api/worlds/supervisor_reset_simulation_fields.wbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#VRML_SIM R2025a utf8

EXTERNPROTO "webots://tests/default/protos/TestSuiteSupervisor.proto"
EXTERNPROTO "webots://tests/default/protos/TestSuiteEmitter.proto"

WorldInfo {
info [
"Test that fields do not return stale values after reset"
]
basicTimeStep 8
coordinateSystem "NUE"
}
Viewpoint {
orientation 0.3011392881427894 -0.8944857953945254 -0.3304698034227591 4.845225060401701
position 8.056890161252701 5.15602094221405 0.024334960209242112
}
Background {
skyColor [
0 0 1
]
}
DirectionalLight {
direction 0 -1 0
}
DEF SOLID Solid {
translation 0 0 1
}
TestSuiteSupervisor {
}
Robot {
controller "supervisor_reset_simulation_fields"
controllerArgs [
"supervisor_reset_simulation_fields_checker"
]
children [
TestSuiteEmitter {
}
]
name "checker robot"
supervisor TRUE
}
Robot {
controller "supervisor_reset_simulation_fields"
controllerArgs [
"supervisor_reset_simulation_fields_resetter"
]
children [
TestSuiteEmitter {
}
]
name "receiver robot"
supervisor TRUE
}
Loading