feat: implement core functionality and stubs for webots controller

This commit is contained in:
insleker 2026-05-20 20:04:27 +08:00
parent f9538ca078
commit 535f4271a5
7 changed files with 304 additions and 1 deletions

4
.gitignore vendored
View File

@ -67,3 +67,7 @@ vcpkg_installed/
# test output & cache # test output & cache
Testing/ Testing/
.cache/ .cache/
# user
/CMakeUserPresets.json

View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.21)
project(webots_controller VERSION 0.1.0 LANGUAGES C)
option(WEBOTS_CONTROLLER_NO_PLUGINS "Disable runtime plugin loading (dlopen/LoadLibrary paths)." ON)
add_subdirectory(src/controller)

View File

@ -1,2 +1,16 @@
# webots-controller # webots-controller
Non official webots controller pack
Unofficial Conan package for Webots controller sources.
## Options
- `no_plugins` (default: `True`): disables runtime plugin loading paths (`dlopen` / `LoadLibrary`) by compiling stub implementations for robot window and remote control plugin entry points.
By default, headers are read from `./include/controller/c` and stb from `./src/stb`, matching this repo layout.
## Example
```bash
conan create . \
-o webots-controller/*:no_plugins=True
```

View File

@ -0,0 +1,52 @@
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import copy
class WebotsControllerConan(ConanFile):
name = "webots-controller"
version = "0.1.0"
package_type = "library"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"no_plugins": [True, False],
}
default_options = {
"shared": True,
"fPIC": True,
"no_plugins": True,
}
exports_sources = "CMakeLists.txt", "src/*", "LICENSE", "README.md"
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
def layout(self):
cmake_layout(self)
def generate(self):
deps = CMakeDeps(self)
deps.generate()
tc = CMakeToolchain(self)
tc.variables["BUILD_SHARED_LIBS"] = bool(self.options.shared)
tc.variables["WEBOTS_CONTROLLER_NO_PLUGINS"] = bool(self.options.no_plugins)
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
copy(self, "LICENSE", src=self.source_folder, dst=f"{self.package_folder}/licenses")
def package_info(self):
self.cpp_info.libs = ["webots_controller"]

View File

@ -0,0 +1 @@
add_subdirectory(c)

View File

@ -0,0 +1,116 @@
set(WEBOTS_HEADERS_ROOT "${CMAKE_SOURCE_DIR}/include/controller/c")
set(WEBOTS_INCLUDE_ROOT "${CMAKE_SOURCE_DIR}/include")
set(WEBOTS_STB_DIR "${CMAKE_SOURCE_DIR}/src/stb")
if(NOT EXISTS "${WEBOTS_HEADERS_ROOT}/webots")
message(FATAL_ERROR "Missing required repo path: ${WEBOTS_HEADERS_ROOT}/webots")
endif()
if(NOT EXISTS "${WEBOTS_STB_DIR}/stb_image.h")
message(FATAL_ERROR "Missing required repo path: ${WEBOTS_STB_DIR}/stb_image.h")
endif()
set(WEBOTS_CONTROLLER_C_CORE_SOURCES
abstract_camera.c
accelerometer.c
altimeter.c
ansi_codes.c
base64.c
brake.c
camera.c
compass.c
connector.c
console.c
default_robot_window.c
device.c
display.c
distance_sensor.c
emitter.c
file.c
g_image.c
g_pipe.c
gps.c
gyro.c
image.c
inertial_unit.c
joystick.c
keyboard.c
led.c
lidar.c
light_sensor.c
microphone.c
motion.c
motor.c
mouse.c
node.c
pen.c
percent.c
position_sensor.c
radar.c
range_finder.c
receiver.c
request.c
robot.c
scheduler.c
sha1.c
skin.c
speaker.c
string.c
supervisor.c
system.c
tcp_client.c
touch_sensor.c
vacuum_gripper.c
)
set(WEBOTS_CONTROLLER_C_PLUGIN_SOURCES
dynamic_library.c
html_robot_window.c
radio.c
remote_control.c
robot_window.c
)
set(WEBOTS_CONTROLLER_C_STUB_SOURCES
no_plugins_stubs.c
)
set(WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_CORE_SOURCES})
if(WEBOTS_CONTROLLER_NO_PLUGINS)
list(APPEND WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_STUB_SOURCES})
else()
list(APPEND WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_PLUGIN_SOURCES})
endif()
# add_library without STATIC/SHARED follows BUILD_SHARED_LIBS automatically in cmake.
add_library(webots_controller ${WEBOTS_CONTROLLER_C_SOURCES})
add_library(webots-controller::webots_controller ALIAS webots_controller)
if(WIN32)
set_target_properties(webots_controller PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
target_include_directories(webots_controller
PRIVATE
${WEBOTS_HEADERS_ROOT}
${WEBOTS_INCLUDE_ROOT}
${WEBOTS_STB_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
target_compile_definitions(webots_controller PRIVATE LIBCONTROLLER_VERSION="custom")
if(WEBOTS_CONTROLLER_NO_PLUGINS)
target_compile_definitions(webots_controller PUBLIC WEBOTS_CONTROLLER_NO_PLUGINS=1)
endif()
if(UNIX)
target_link_libraries(webots_controller PRIVATE m)
if(NOT APPLE)
target_link_libraries(webots_controller PRIVATE pthread rt)
if(NOT WEBOTS_CONTROLLER_NO_PLUGINS)
target_link_libraries(webots_controller PRIVATE dl)
endif()
endif()
endif()
install(TARGETS webots_controller)

View File

@ -0,0 +1,110 @@
#include <stdbool.h>
#include "html_robot_window_private.h"
#include "remote_control_private.h"
#include "robot_window_private.h"
#include <stddef.h>
void robot_window_init(const char *library_name) {
(void)library_name;
}
bool robot_window_is_initialized() {
return false;
}
const char *robot_window_get_last_error() {
return "plugins disabled";
}
void robot_window_pre_update_gui() {
}
void robot_window_update_gui() {
}
void robot_window_read_sensors() {
}
void robot_window_write_actuators() {
}
void robot_window_cleanup() {
}
void robot_window_show() {
}
void *wb_robot_window_custom_function(void *args) {
(void)args;
return NULL;
}
bool wb_robot_window_load_library(const char *name) {
(void)name;
return false;
}
void html_robot_window_init() {
}
void html_robot_window_step(int step) {
(void)step;
}
void html_robot_window_cleanup() {
}
void remote_control_init(const char *library_name) {
(void)library_name;
}
void remote_control_cleanup() {
}
bool remote_control_is_initialized() {
return false;
}
const char *remote_control_get_last_error() {
return "plugins disabled";
}
bool remote_control_start(const char *args) {
(void)args;
return false;
}
void remote_control_stop() {
}
void remote_control_stop_actuators() {
}
bool remote_control_has_failed() {
return false;
}
void remote_control_step(int duration) {
(void)duration;
}
WbRequest *remote_control_handle_messages(WbRequest *r) {
return r;
}
void remote_control_handle_one_message(WbRequest *r, WbDeviceTag tag) {
(void)r;
(void)tag;
}
bool remote_control_is_function_defined(const char *function_name) {
(void)function_name;
return false;
}
void *wb_remote_control_custom_function(void *arg) {
(void)arg;
return NULL;
}