first commit

This commit is contained in:
lgv 2026-08-05 16:42:59 +08:00
commit 78578a1bed
108 changed files with 10358 additions and 0 deletions

10
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/cmvr-head-client.iml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="mujoco_rbtbox" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="mujoco_rbtbox" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="mujoco_rbtbox" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/cmvr-head-client.iml" filepath="$PROJECT_DIR$/.idea/cmvr-head-client.iml" />
</modules>
</component>
</project>

6
__init__.py Normal file
View File

@ -0,0 +1,6 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:45 2026.
#
# AUTOGENERATED - DO NOT EDIT
#

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

90
config/servo_config.json Normal file
View File

@ -0,0 +1,90 @@
{
"version": 1,
"servo_count": 4,
"servos": [
{
"id": "eye_l_up",
"limit_min_angle_rad": -0.8,
"limit_max_angle_rad": 0,
"home_angle_rad": 0,
"driver": {
"period_ns": 20000000,
"min_pulse_ns": 500000,
"max_pulse_ns": 2500000,
"min_angle_rad": -1.5707963,
"max_angle_rad": 1.5707963,
"pwm_dev_name": "pwm1",
"pwm_channel": 1
},
"control": {
"max_velocity_rad": 20,
"max_acceleration_rad": 1000.0,
"max_jerk_rad": 500.0,
"position_gain": 4.5
}
},
{
"id": "eye_l_lower",
"limit_min_angle_rad": -1,
"limit_max_angle_rad": -0.2,
"home_angle_rad": -1,
"driver": {
"period_ns": 20000000,
"min_pulse_ns": 500000,
"max_pulse_ns": 2500000,
"min_angle_rad": -1.5707963,
"max_angle_rad": 1.5707963,
"pwm_dev_name": "pwm1",
"pwm_channel": 2
},
"control": {
"max_velocity_rad": 20,
"max_acceleration_rad": 1000.0,
"max_jerk_rad": 500.0,
"position_gain": 4.5
}
},
{
"id": "eye_l_v",
"limit_min_angle_rad": -0.85,
"limit_max_angle_rad": 0.85,
"home_angle_rad": 0,
"driver": {
"period_ns": 20000000,
"min_pulse_ns": 500000,
"max_pulse_ns": 2500000,
"min_angle_rad": -1.5707963,
"max_angle_rad": 1.5707963,
"pwm_dev_name": "pwm1",
"pwm_channel": 3
},
"control": {
"max_velocity_rad": 20,
"max_acceleration_rad": 1000.0,
"max_jerk_rad": 500.0,
"position_gain": 4.5
}
},
{
"id": "eye_l_h",
"limit_min_angle_rad": -0.65,
"limit_max_angle_rad": 0.7,
"home_angle_rad": 0,
"driver": {
"period_ns": 20000000,
"min_pulse_ns": 500000,
"max_pulse_ns": 2500000,
"min_angle_rad": -1.5707963,
"max_angle_rad": 1.5707963,
"pwm_dev_name": "pwm1",
"pwm_channel": 4
},
"control": {
"max_velocity_rad": 20,
"max_acceleration_rad": 1000.0,
"max_jerk_rad": 500.0,
"position_gain": 4.5
}
}
]
}

60
config/servo_config.yaml Normal file
View File

@ -0,0 +1,60 @@
version: 1
servo_count: 4
default_driver: &default_driver
period_ns: 20000000
min_pulse_ns: 500000
max_pulse_ns: 2500000
min_angle_rad: -1.5707963
max_angle_rad: 1.5707963
default_control: &default_control
max_velocity_rad: 20
max_acceleration_rad: 1000.0
max_jerk_rad: 500.0
position_gain: 4.5
servos:
- id: eye_l_up
limit_min_angle_rad: -0.8
limit_max_angle_rad: 0
home_angle_rad: 0
driver:
<<: *default_driver
pwm_dev_name: pwm1
pwm_channel: 1
control:
<<: *default_control
- id: eye_l_lower
limit_min_angle_rad: -1
limit_max_angle_rad: -0.2
home_angle_rad: -1
driver:
<<: *default_driver
pwm_dev_name: pwm1
pwm_channel: 2
control:
<<: *default_control
- id: eye_l_v
limit_min_angle_rad: -0.85
limit_max_angle_rad: 0.85
home_angle_rad: 0
driver:
<<: *default_driver
pwm_dev_name: pwm1
pwm_channel: 3
control:
<<: *default_control
- id: eye_l_h
limit_min_angle_rad: -0.65
limit_max_angle_rad: 0.7
home_angle_rad: 0
driver:
<<: *default_driver
pwm_dev_name: pwm1
pwm_channel: 4
control:
<<: *default_control

57
config/yaml_to_json.py Normal file
View File

@ -0,0 +1,57 @@
import argparse
import json
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
DEFAULT_INPUT_FILE = SCRIPT_DIR / "servo_config.yaml"
DEFAULT_OUTPUT_FILE = SCRIPT_DIR / "servo_config.json"
def parse_args():
parser = argparse.ArgumentParser(description="Convert a servo YAML config to JSON.")
parser.add_argument("input", nargs="?", type=Path, default=DEFAULT_INPUT_FILE)
parser.add_argument("output", nargs="?", type=Path, default=DEFAULT_OUTPUT_FILE)
return parser.parse_args()
def convert_yaml_to_json(input_file, output_file):
try:
import yaml
except ModuleNotFoundError as exc:
raise RuntimeError(
"PyYAML is required. Install it with: python -m pip install PyYAML"
) from exc
input_file = Path(input_file).resolve()
output_file = Path(output_file).resolve()
with input_file.open("r", encoding="utf-8") as stream:
data = yaml.safe_load(stream)
if not isinstance(data, dict):
raise ValueError("Servo config root must be a YAML mapping.")
# These helper nodes only exist to support YAML anchors and merge keys.
data.pop("default_driver", None)
data.pop("default_control", None)
output_file.parent.mkdir(parents=True, exist_ok=True)
with output_file.open("w", encoding="utf-8") as stream:
json.dump(data, stream, indent=2, ensure_ascii=False)
stream.write("\n")
return output_file
def main():
args = parse_args()
try:
output_file = convert_yaml_to_json(args.input, args.output)
except Exception as exc:
raise SystemExit(f"YAML conversion failed: {exc}") from exc
print(f"Generated {output_file}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.20)
project(cmvr_scurve LANGUAGES CXX)
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
execute_process(
COMMAND "${Python_EXECUTABLE}" -m pybind11 --cmakedir
OUTPUT_VARIABLE pybind11_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
find_package(pybind11 CONFIG REQUIRED)
pybind11_add_module(_s_curve_native
src/s_curve.cpp
src/s_curve_pybind.cpp
../../planner/s_curve_planner/src/s_curve_velocity_planner.cpp
../../planner/s_curve_planner/src/s_curve_position_planner.cpp
)
target_compile_features(_s_curve_native PUBLIC cxx_std_17)
target_include_directories(_s_curve_native
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../..
${CMAKE_CURRENT_SOURCE_DIR}/include
)
set_target_properties(_s_curve_native PROPERTIES
OUTPUT_NAME "_s_curve_native"
)

View File

@ -0,0 +1,26 @@
# SCurve Python Bridge
This folder now exposes the C++ `SCurve` class as a native Python extension built with `pybind11`.
## Build
From the repository root:
```powershell
powershell -ExecutionPolicy Bypass -File .\cpp\common\curve\build_python.ps1 -PythonExecutable "C:\Users\Administrator\miniconda3\envs\cmvr-head-client\python.exe"
```
Expected output:
- `cpp/common/curve/build/_s_curve_native*.pyd`
## Python usage
```python
from s_curve import SCurve
curve = SCurve(max_velocity=3.0, max_acceleration=10.0, max_jerk=50.0)
curve.setConstraints(4.0, 12.0, 80.0)
profile = curve.calculateProfile(0.0, 30.0, 0.0, 0.0)
samples = curve.sampleTrajectory(profile, 0.01)
```

Binary file not shown.

View File

@ -0,0 +1,12 @@
# ninja log v5
1 1048 7986139309146135 _s_curve_native.cp310-win_amd64.pyd 673782cfb92e82ed
294 378 7985314121237372 cmvr_scurve.dll f5a2deae4722be51
3 192 7985314119482111 CMakeFiles/cmvr_scurve.dir/src/s_curve_c_api.cpp.obj c45d67ef9cd340bf
1 192 7985325638396114 CMakeFiles/_s_curve_native.dir/src/s_curve.cpp.obj c1eacea52f4088b1
1 294 7985314120489746 CMakeFiles/cmvr_scurve.dir/src/s_curve.cpp.obj feab6347a1d9fd9
2 140 7986137855321581 CMakeFiles/_s_curve_native.dir/D_/cmvr/0-worksapce/cmvr-head-client/cpp/planner/s_curve_planner/src/s_curve_position_planner.cpp.obj e63e15a214de1054
294 378 7985314121237372 cmvr_scurve.lib f5a2deae4722be51
3 1750 7986133195476363 CMakeFiles/_s_curve_native.dir/src/s_curve_pybind.cpp.obj e94b80eb42378794
1 164 7986135846813044 CMakeFiles/_s_curve_native.dir/D_/cmvr/0-worksapce/cmvr-head-client/cpp/planner/s_curve_planner/src/s_curve_velocity_planner.cpp.obj f46dab0fc0756a6a
1 137 7986140057393930 CMakeFiles/_s_curve_native.dir/D_/cmvr/0-worksapce/cmvr-head-client/cpp/planner/s_curve_planner/src/s_curve_position_planner.cpp.obj e63e15a214de1054
137 1174 7986140067522517 _s_curve_native.cp310-win_amd64.pyd 673782cfb92e82ed

View File

@ -0,0 +1,352 @@
# This is the CMakeCache file.
# For build in directory: d:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build
# It was generated by CMake: C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/bin/cmake.exe
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//Path to a program.
CMAKE_AR:FILEPATH=C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/lib.exe
//Choose the type of build, options are: None Debug Release RelWithDebInfo
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=Release
//CXX compiler
CMAKE_CXX_COMPILER:FILEPATH=C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/cl.exe
//Flags used by the CXX compiler during all build types.
CMAKE_CXX_FLAGS:STRING=/DWIN32 /D_WINDOWS /EHsc
//Flags used by the CXX compiler during DEBUG builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=/Zi /Ob0 /Od /RTC1
//Flags used by the CXX compiler during MINSIZEREL builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=/O1 /Ob1 /DNDEBUG
//Flags used by the CXX compiler during RELEASE builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=/O2 /Ob2 /DNDEBUG
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=/Zi /O2 /Ob1 /DNDEBUG
//Libraries linked by default with all C++ applications.
CMAKE_CXX_STANDARD_LIBRARIES:STRING=kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
//Flags used by the linker during all build types.
CMAKE_EXE_LINKER_FLAGS:STRING=/machine:x64
//Flags used by the linker during DEBUG builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL
//Flags used by the linker during MINSIZEREL builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO
//Flags used by the linker during RELEASE builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO
//Flags used by the linker during RELWITHDEBINFO builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
//Value Computed by CMake.
CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/pkgRedirects
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=C:/Program Files (x86)/cmvr_scurve
//Path to a program.
CMAKE_LINKER:FILEPATH=C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/link.exe
//make program
CMAKE_MAKE_PROGRAM:FILEPATH=C:/PROGRA~1/STM32/STM32C~1.0/Ninja/bin/ninja.exe
//Flags used by the linker during the creation of modules during
// all build types.
CMAKE_MODULE_LINKER_FLAGS:STRING=/machine:x64
//Flags used by the linker during the creation of modules during
// DEBUG builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL
//Flags used by the linker during the creation of modules during
// MINSIZEREL builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO
//Flags used by the linker during the creation of modules during
// RELEASE builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO
//Flags used by the linker during the creation of modules during
// RELWITHDEBINFO builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL
//Path to a program.
CMAKE_MT:FILEPATH=C:/Program Files (x86)/Windows Kits/10/bin/10.0.26100.0/x64/mt.exe
//Value Computed by CMake
CMAKE_PROJECT_DESCRIPTION:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=cmvr_scurve
//RC compiler
CMAKE_RC_COMPILER:FILEPATH=C:/Program Files (x86)/Windows Kits/10/bin/10.0.26100.0/x64/rc.exe
//Flags for Windows Resource Compiler during all build types.
CMAKE_RC_FLAGS:STRING=-DWIN32
//Flags for Windows Resource Compiler during DEBUG builds.
CMAKE_RC_FLAGS_DEBUG:STRING=-D_DEBUG
//Flags for Windows Resource Compiler during MINSIZEREL builds.
CMAKE_RC_FLAGS_MINSIZEREL:STRING=
//Flags for Windows Resource Compiler during RELEASE builds.
CMAKE_RC_FLAGS_RELEASE:STRING=
//Flags for Windows Resource Compiler during RELWITHDEBINFO builds.
CMAKE_RC_FLAGS_RELWITHDEBINFO:STRING=
//Flags used by the linker during the creation of shared libraries
// during all build types.
CMAKE_SHARED_LINKER_FLAGS:STRING=/machine:x64
//Flags used by the linker during the creation of shared libraries
// during DEBUG builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL
//Flags used by the linker during the creation of shared libraries
// during MINSIZEREL builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO
//Flags used by the linker during the creation of shared libraries
// during RELEASE builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO
//Flags used by the linker during the creation of shared libraries
// during RELWITHDEBINFO builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries
// during all build types.
CMAKE_STATIC_LINKER_FLAGS:STRING=/machine:x64
//Flags used by the linker during the creation of static libraries
// during DEBUG builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of static libraries
// during MINSIZEREL builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of static libraries
// during RELEASE builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of static libraries
// during RELWITHDEBINFO builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
//No help, variable specified on the command line.
Python_EXECUTABLE:UNINITIALIZED=C:\Users\Administrator\miniconda3\envs\cmvr-head-client\python.exe
//Value Computed by CMake
cmvr_scurve_BINARY_DIR:STATIC=D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build
//Value Computed by CMake
cmvr_scurve_IS_TOP_LEVEL:STATIC=ON
//Value Computed by CMake
cmvr_scurve_SOURCE_DIR:STATIC=D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve
########################
# INTERNAL cache entries
########################
//ADVANCED property for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=d:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=28
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/bin/cmake.exe
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/bin/cpack.exe
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/bin/ctest.exe
//ADVANCED property for variable: CMAKE_CXX_COMPILER
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_STANDARD_LIBRARIES
CMAKE_CXX_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
//Path to cache edit program executable.
CMAKE_EDIT_COMMAND:INTERNAL=C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/bin/cmake-gui.exe
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=Unknown
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Ninja
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve
//ADVANCED property for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MT
CMAKE_MT-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//noop for ranlib
CMAKE_RANLIB:INTERNAL=:
//ADVANCED property for variable: CMAKE_RC_COMPILER
CMAKE_RC_COMPILER-ADVANCED:INTERNAL=1
CMAKE_RC_COMPILER_WORKS:INTERNAL=1
//ADVANCED property for variable: CMAKE_RC_FLAGS
CMAKE_RC_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RC_FLAGS_DEBUG
CMAKE_RC_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RC_FLAGS_MINSIZEREL
CMAKE_RC_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RC_FLAGS_RELEASE
CMAKE_RC_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RC_FLAGS_RELWITHDEBINFO
CMAKE_RC_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
//Details about finding Python
FIND_PACKAGE_MESSAGE_DETAILS_Python:INTERNAL=[C:\Users\Administrator\miniconda3\envs\cmvr-head-client\python.exe][C:/Users/Administrator/miniconda3/envs/cmvr-head-client/libs/python310.lib][C:/Users/Administrator/miniconda3/envs/cmvr-head-client/include][cfound components: Interpreter Development.Module ][v3.10.20()]
//Test HAS_MSVC_GL_LTCG
HAS_MSVC_GL_LTCG:INTERNAL=1
//Python executable during the last CMake run
PYBIND11_PYTHON_EXECUTABLE_LAST:INTERNAL=C:\Users\Administrator\miniconda3\envs\cmvr-head-client\python.exe
//Python debug status
PYTHON_IS_DEBUG:INTERNAL=0
PYTHON_MODULE_DEBUG_POSTFIX:INTERNAL=
PYTHON_MODULE_EXTENSION:INTERNAL=.cp310-win_amd64.pyd
_PYBIND11_CROSSCOMPILING:INTERNAL=OFF
_Python:INTERNAL=Python
//Compiler reason failure
_Python_Compiler_REASON_FAILURE:INTERNAL=
_Python_DEVELOPMENT_MODULE_SIGNATURE:INTERNAL=3a22dc2b94a46256ea8dac49ac5f6ebc
//Development reason failure
_Python_Development_REASON_FAILURE:INTERNAL=
_Python_EXECUTABLE:INTERNAL=C:\Users\Administrator\miniconda3\envs\cmvr-head-client\python.exe
//Path to a file.
_Python_INCLUDE_DIR:INTERNAL=C:/Users/Administrator/miniconda3/envs/cmvr-head-client/include
//Python Properties
_Python_INTERPRETER_PROPERTIES:INTERNAL=Python;3;10;20;64;;cp310-win_amd64;;C:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib;C:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib;C:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages;C:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages
_Python_INTERPRETER_SIGNATURE:INTERNAL=0a9f8137d2a58419f97d1d2f7ec6526f
//Interpreter reason failure
_Python_Interpreter_REASON_FAILURE:INTERNAL=
//Path to a library.
_Python_LIBRARY_DEBUG:INTERNAL=_Python_LIBRARY_DEBUG-NOTFOUND
//Path to a library.
_Python_LIBRARY_RELEASE:INTERNAL=C:/Users/Administrator/miniconda3/envs/cmvr-head-client/libs/python310.lib
//NumPy reason failure
_Python_NumPy_REASON_FAILURE:INTERNAL=
//Path to a library.
_Python_RUNTIME_LIBRARY_RELEASE:INTERNAL=C:/Users/Administrator/miniconda3/envs/cmvr-head-client/python310.dll
//Directories where pybind11 and possibly Python headers are located
pybind11_INCLUDE_DIRS:INTERNAL=C:/Users/Administrator/miniconda3/envs/cmvr-head-client/Lib/site-packages/pybind11/include;C:/Users/Administrator/miniconda3/envs/cmvr-head-client/include

View File

@ -0,0 +1,85 @@
set(CMAKE_CXX_COMPILER "C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/cl.exe")
set(CMAKE_CXX_COMPILER_ARG1 "")
set(CMAKE_CXX_COMPILER_ID "MSVC")
set(CMAKE_CXX_COMPILER_VERSION "19.50.35722.0")
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
set(CMAKE_CXX_COMPILER_WRAPPER "")
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "14")
set(CMAKE_CXX_EXTENSIONS_COMPUTED_DEFAULT "OFF")
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23")
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
set(CMAKE_CXX23_COMPILE_FEATURES "cxx_std_23")
set(CMAKE_CXX_PLATFORM_ID "Windows")
set(CMAKE_CXX_SIMULATE_ID "")
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "MSVC")
set(CMAKE_CXX_SIMULATE_VERSION "")
set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID x64)
set(MSVC_CXX_ARCHITECTURE_ID x64)
set(CMAKE_AR "C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/lib.exe")
set(CMAKE_CXX_COMPILER_AR "")
set(CMAKE_RANLIB ":")
set(CMAKE_CXX_COMPILER_RANLIB "")
set(CMAKE_LINKER "C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/link.exe")
set(CMAKE_MT "C:/Program Files (x86)/Windows Kits/10/bin/10.0.26100.0/x64/mt.exe")
set(CMAKE_TAPI "")
set(CMAKE_COMPILER_IS_GNUCXX )
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_CXX_ABI_COMPILED TRUE)
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm;ccm;cxxm;c++m)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
foreach (lang C OBJC OBJCXX)
if (CMAKE_${lang}_COMPILER_ID_RUN)
foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
endforeach()
endif()
endforeach()
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
set(CMAKE_CXX_LINKER_DEPFILE_SUPPORTED )
# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "8")
set(CMAKE_CXX_COMPILER_ABI "")
set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN")
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")
if(CMAKE_CXX_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_CXX_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
endif()
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "")
endif()
set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "注意: 包含文件: ")
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "")
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

View File

@ -0,0 +1,6 @@
set(CMAKE_RC_COMPILER "C:/Program Files (x86)/Windows Kits/10/bin/10.0.26100.0/x64/rc.exe")
set(CMAKE_RC_COMPILER_ARG1 "")
set(CMAKE_RC_COMPILER_LOADED 1)
set(CMAKE_RC_SOURCE_FILE_EXTENSIONS rc;RC)
set(CMAKE_RC_OUTPUT_EXTENSION .res)
set(CMAKE_RC_COMPILER_ENV_VAR "RC")

View File

@ -0,0 +1,15 @@
set(CMAKE_HOST_SYSTEM "Windows-10.0.26100")
set(CMAKE_HOST_SYSTEM_NAME "Windows")
set(CMAKE_HOST_SYSTEM_VERSION "10.0.26100")
set(CMAKE_HOST_SYSTEM_PROCESSOR "AMD64")
set(CMAKE_SYSTEM "Windows-10.0.26100")
set(CMAKE_SYSTEM_NAME "Windows")
set(CMAKE_SYSTEM_VERSION "10.0.26100")
set(CMAKE_SYSTEM_PROCESSOR "AMD64")
set(CMAKE_CROSSCOMPILING "FALSE")
set(CMAKE_SYSTEM_LOADED 1)

View File

@ -0,0 +1,869 @@
/* This source file must have a .cpp extension so that all C++ compilers
recognize the extension without flags. Borland does not know .cxx for
example. */
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__COMO__)
# define COMPILER_ID "Comeau"
/* __COMO_VERSION__ = VRR */
# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
#elif defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_CC)
# define COMPILER_ID "SunPro"
# if __SUNPRO_CC >= 0x5100
/* __SUNPRO_CC = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# endif
#elif defined(__HP_aCC)
# define COMPILER_ID "HP"
/* __HP_aCC = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
#elif defined(__DECCXX)
# define COMPILER_ID "Compaq"
/* __DECCXX_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__open_xl__) && defined(__clang__)
# define COMPILER_ID "IBMClang"
# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
# define COMPILER_ID "XL"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(__clang__) && defined(__cray__)
# define COMPILER_ID "CrayClang"
# define COMPILER_VERSION_MAJOR DEC(__cray_major__)
# define COMPILER_VERSION_MINOR DEC(__cray_minor__)
# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__TASKING__)
# define COMPILER_ID "Tasking"
# define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000)
# define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100)
# define COMPILER_VERSION_INTERNAL DEC(__VERSION__)
#elif defined(__ORANGEC__)
# define COMPILER_ID "OrangeC"
# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__)
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
# define COMPILER_ID "LCC"
# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100)
# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100)
# if defined(__LCC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
# endif
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define SIMULATE_ID "GNU"
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_ID "GNU"
# if defined(__GNUC__)
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# else
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(_ADI_COMPILER)
# define COMPILER_ID "ADSP"
#if defined(__VERSIONNUM__)
/* __VERSIONNUM__ = 0xVVRRPPTT */
# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
# elif defined(_ADI_COMPILER)
# define PLATFORM_ID "ADSP"
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
# elif defined(__ADSPSHARC__)
# define ARCHITECTURE_ID "SHARC"
# elif defined(__ADSPBLACKFIN__)
# define ARCHITECTURE_ID "Blackfin"
#elif defined(__TASKING__)
# if defined(__CTC__) || defined(__CPTC__)
# define ARCHITECTURE_ID "TriCore"
# elif defined(__CMCS__)
# define ARCHITECTURE_ID "MCS"
# elif defined(__CARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__CARC__)
# define ARCHITECTURE_ID "ARC"
# elif defined(__C51__)
# define ARCHITECTURE_ID "8051"
# elif defined(__CPCP__)
# define ARCHITECTURE_ID "PCP"
# else
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L
# if defined(__INTEL_CXX11_MODE__)
# if defined(__cpp_aggregate_nsdmi)
# define CXX_STD 201402L
# else
# define CXX_STD 201103L
# endif
# else
# define CXX_STD 199711L
# endif
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
# define CXX_STD _MSVC_LANG
#else
# define CXX_STD __cplusplus
#endif
const char* info_language_standard_default = "INFO" ":" "standard_default["
#if CXX_STD > 202002L
"23"
#elif CXX_STD > 201703L
"20"
#elif CXX_STD >= 201703L
"17"
#elif CXX_STD >= 201402L
"14"
#elif CXX_STD >= 201103L
"11"
#else
"98"
#endif
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
#endif
"]";
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
require += info_arch[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_standard_default[argc];
require += info_language_extensions_default[argc];
(void)argv;
return require;
}

View File

@ -0,0 +1,118 @@
---
events:
-
kind: "message-v1"
backtrace:
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineSystem.cmake:233 (message)"
- "CMakeLists.txt:3 (project)"
message: |
The system is: Windows - 10.0.26100 - AMD64
-
kind: "message-v1"
backtrace:
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineCompilerId.cmake:17 (message)"
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)"
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineCXXCompiler.cmake:126 (CMAKE_DETERMINE_COMPILER_ID)"
- "CMakeLists.txt:3 (project)"
message: |
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
Compiler: C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/cl.exe
Build flags:
Id flags:
The output was:
0
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.50.35722 版
版权所有(C) Microsoft Corporation。保留所有权利。
CMakeCXXCompilerId.cpp
Microsoft (R) Incremental Linker Version 14.50.35722.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:CMakeCXXCompilerId.exe
CMakeCXXCompilerId.obj
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "CMakeCXXCompilerId.exe"
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "CMakeCXXCompilerId.obj"
The CXX compiler identification is MSVC, found in:
D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/3.28.1/CompilerIdCXX/CMakeCXXCompilerId.exe
-
kind: "message-v1"
backtrace:
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineCompilerId.cmake:1182 (message)"
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineCompilerId.cmake:247 (CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX)"
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineCXXCompiler.cmake:126 (CMAKE_DETERMINE_COMPILER_ID)"
- "CMakeLists.txt:3 (project)"
message: |
Detecting CXX compiler /showIncludes prefix:
main.c
注意: 包含文件: D:\\cmvr\\0-worksapce\\cmvr-head-client\\cpp\\common\\curve\\build\\CMakeFiles\\ShowIncludes\\foo.h
Found prefix "注意: 包含文件: "
-
kind: "try_compile-v1"
backtrace:
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeDetermineCompilerABI.cmake:57 (try_compile)"
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
- "CMakeLists.txt:3 (project)"
checks:
- "Detecting CXX compiler ABI info"
directories:
source: "D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/CMakeScratch/TryCompile-pxs2x3"
binary: "D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/CMakeScratch/TryCompile-pxs2x3"
cmakeVariables:
CMAKE_CXX_FLAGS: "/DWIN32 /D_WINDOWS /EHsc"
CMAKE_CXX_FLAGS_DEBUG: "/Zi /Ob0 /Od /RTC1"
CMAKE_EXE_LINKER_FLAGS: "/machine:x64"
buildResult:
variable: "CMAKE_CXX_ABI_COMPILED"
cached: true
stdout: |
Change Dir: 'D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/CMakeScratch/TryCompile-pxs2x3'
Run Build Command(s): C:/PROGRA~1/STM32/STM32C~1.0/Ninja/bin/ninja.exe -v cmTC_04a14
[1/2] C:\\PROGRA~1\\MIB055~1\\18\\COMMUN~1\\VC\\Tools\\MSVC\\1450~1.357\\bin\\Hostx64\\x64\\cl.exe /nologo /TP /DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -MDd /showIncludes /FoCMakeFiles\\cmTC_04a14.dir\\CMakeCXXCompilerABI.cpp.obj /FdCMakeFiles\\cmTC_04a14.dir\\ /FS -c "C:\\Program Files\\STM32\\STM32CubeCLT_1.20.0\\CMake\\share\\cmake-3.28\\Modules\\CMakeCXXCompilerABI.cpp"
[2/2] C:\\windows\\system32\\cmd.exe /C "cd . && "C:\\Program Files\\STM32\\STM32CubeCLT_1.20.0\\CMake\\bin\\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\\cmTC_04a14.dir --rc=C:\\PROGRA~2\\WINDOW~4\\10\\bin\\100261~1.0\\x64\\rc.exe --mt=C:\\PROGRA~2\\WINDOW~4\\10\\bin\\100261~1.0\\x64\\mt.exe --manifests -- C:\\PROGRA~1\\MIB055~1\\18\\COMMUN~1\\VC\\Tools\\MSVC\\1450~1.357\\bin\\Hostx64\\x64\\link.exe /nologo CMakeFiles\\cmTC_04a14.dir\\CMakeCXXCompilerABI.cpp.obj /out:cmTC_04a14.exe /implib:cmTC_04a14.lib /pdb:cmTC_04a14.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
exitCode: 0
...
---
events:
-
kind: "try_compile-v1"
backtrace:
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/Internal/CheckSourceCompiles.cmake:101 (try_compile)"
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/Internal/CheckCompilerFlag.cmake:18 (cmake_check_source_compiles)"
- "C:/Program Files/STM32/STM32CubeCLT_1.20.0/CMake/share/cmake-3.28/Modules/CheckCXXCompilerFlag.cmake:34 (cmake_check_compiler_flag)"
- "C:/Users/Administrator/miniconda3/envs/cmvr-head-client/Lib/site-packages/pybind11/share/cmake/pybind11/pybind11Common.cmake:332 (check_cxx_compiler_flag)"
- "C:/Users/Administrator/miniconda3/envs/cmvr-head-client/Lib/site-packages/pybind11/share/cmake/pybind11/pybind11Common.cmake:404 (_pybind11_return_if_cxx_and_linker_flags_work)"
- "C:/Users/Administrator/miniconda3/envs/cmvr-head-client/Lib/site-packages/pybind11/share/cmake/pybind11/pybind11Common.cmake:438 (_pybind11_generate_lto)"
- "C:/Users/Administrator/miniconda3/envs/cmvr-head-client/Lib/site-packages/pybind11/share/cmake/pybind11/pybind11Config.cmake:257 (include)"
- "CMakeLists.txt:13 (find_package)"
checks:
- "Performing Test HAS_MSVC_GL_LTCG"
directories:
source: "D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/CMakeScratch/TryCompile-n8t4hj"
binary: "D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/CMakeScratch/TryCompile-n8t4hj"
cmakeVariables:
CMAKE_CXX_FLAGS: "/DWIN32 /D_WINDOWS /EHsc"
CMAKE_CXX_FLAGS_DEBUG: "/Zi /Ob0 /Od /RTC1"
CMAKE_EXE_LINKER_FLAGS: "/machine:x64"
buildResult:
variable: "HAS_MSVC_GL_LTCG"
cached: true
stdout: |
Change Dir: 'D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/CMakeScratch/TryCompile-n8t4hj'
Run Build Command(s): C:/PROGRA~1/STM32/STM32C~1.0/Ninja/bin/ninja.exe -v cmTC_1814a
[1/2] C:\\PROGRA~1\\MIB055~1\\18\\COMMUN~1\\VC\\Tools\\MSVC\\1450~1.357\\bin\\Hostx64\\x64\\cl.exe /nologo /TP -DHAS_MSVC_GL_LTCG /DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -MDd /GL /showIncludes /FoCMakeFiles\\cmTC_1814a.dir\\src.cxx.obj /FdCMakeFiles\\cmTC_1814a.dir\\ /FS -c D:\\cmvr\\0-worksapce\\cmvr-head-client\\cpp\\common\\curve\\build\\CMakeFiles\\CMakeScratch\\TryCompile-n8t4hj\\src.cxx
[2/2] C:\\windows\\system32\\cmd.exe /C "cd . && "C:\\Program Files\\STM32\\STM32CubeCLT_1.20.0\\CMake\\bin\\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\\cmTC_1814a.dir --rc=C:\\PROGRA~2\\WINDOW~4\\10\\bin\\100261~1.0\\x64\\rc.exe --mt=C:\\PROGRA~2\\WINDOW~4\\10\\bin\\100261~1.0\\x64\\mt.exe --manifests -- C:\\PROGRA~1\\MIB055~1\\18\\COMMUN~1\\VC\\Tools\\MSVC\\1450~1.357\\bin\\Hostx64\\x64\\link.exe /nologo CMakeFiles\\cmTC_1814a.dir\\src.cxx.obj /out:cmTC_1814a.exe /implib:cmTC_1814a.lib /pdb:cmTC_1814a.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console -LTCG kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
exitCode: 0
...

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,2 @@
#include "foo.h"
int main(){}

View File

@ -0,0 +1,3 @@
D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/_s_curve_native.dir
D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/edit_cache.dir
D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/CMakeFiles/rebuild_cache.dir

View File

@ -0,0 +1 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file

View File

@ -0,0 +1,69 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by "Ninja" Generator, CMake Version 3.28
# This file contains all the rules used to get the outputs files
# built from the input files.
# It is included in the main 'build.ninja'.
# =============================================================================
# Project: cmvr_scurve
# Configurations: Release
# =============================================================================
# =============================================================================
#############################################
# localized /showIncludes string
msvc_deps_prefix = ×¢Òâ: °üº¬Îļþ:
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER___s_curve_native_unscanned_Release
deps = msvc
command = ${LAUNCHER}${CODE_CHECK}C:\PROGRA~1\MIB055~1\18\COMMUN~1\VC\Tools\MSVC\1450~1.357\bin\Hostx64\x64\cl.exe /nologo /TP $DEFINES $INCLUDES $FLAGS /showIncludes /Fo$out /Fd$TARGET_COMPILE_PDB /FS -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX shared module.
rule CXX_MODULE_LIBRARY_LINKER___s_curve_native_Release
command = C:\windows\system32\cmd.exe /C "$PRE_LINK && "C:\Program Files\STM32\STM32CubeCLT_1.20.0\CMake\bin\cmake.exe" -E vs_link_dll --intdir=$OBJECT_DIR --rc=C:\PROGRA~2\WINDOW~4\10\bin\100261~1.0\x64\rc.exe --mt=C:\PROGRA~2\WINDOW~4\10\bin\100261~1.0\x64\mt.exe --manifests $MANIFESTS -- C:\PROGRA~1\MIB055~1\18\COMMUN~1\VC\Tools\MSVC\1450~1.357\bin\Hostx64\x64\link.exe /nologo $in /out:$TARGET_FILE /implib:$TARGET_IMPLIB /pdb:$TARGET_PDB /dll /version:0.0 $LINK_FLAGS $LINK_PATH $LINK_LIBRARIES && $POST_BUILD"
description = Linking CXX shared module $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for running custom commands.
rule CUSTOM_COMMAND
command = $COMMAND
description = $DESC
#############################################
# Rule for re-running cmake.
rule RERUN_CMAKE
command = "C:\Program Files\STM32\STM32CubeCLT_1.20.0\CMake\bin\cmake.exe" --regenerate-during-build -SD:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve -BD:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\build
description = Re-running CMake...
generator = 1
#############################################
# Rule for cleaning all built files.
rule CLEAN
command = C:\PROGRA~1\STM32\STM32C~1.0\Ninja\bin\ninja.exe $FILE_ARG -t clean $TARGETS
description = Cleaning all built files...
#############################################
# Rule for printing all primary targets available.
rule HELP
command = C:\PROGRA~1\STM32\STM32C~1.0\Ninja\bin\ninja.exe -t targets
description = All primary targets available:

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,179 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by "Ninja" Generator, CMake Version 3.28
# This file contains all the build statements describing the
# compilation DAG.
# =============================================================================
# Write statements declared in CMakeLists.txt:
#
# Which is the root file.
# =============================================================================
# =============================================================================
# Project: cmvr_scurve
# Configurations: Release
# =============================================================================
#############################################
# Minimal version of Ninja required by this file
ninja_required_version = 1.5
#############################################
# Set configuration variable for custom commands.
CONFIGURATION = Release
# =============================================================================
# Include auxiliary files.
#############################################
# Include rules file.
include CMakeFiles\rules.ninja
# =============================================================================
#############################################
# Logical path to working directory; prefix for absolute paths.
cmake_ninja_workdir = D$:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\build\
# =============================================================================
# Object build statements for MODULE_LIBRARY target _s_curve_native
#############################################
# Order-only phony target for _s_curve_native
build cmake_object_order_depends_target__s_curve_native: phony || CMakeFiles\_s_curve_native.dir
build CMakeFiles\_s_curve_native.dir\src\s_curve.cpp.obj: CXX_COMPILER___s_curve_native_unscanned_Release D$:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\src\s_curve.cpp || cmake_object_order_depends_target__s_curve_native
DEFINES = -D_s_curve_native_EXPORTS
FLAGS = /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -std:c++17 -MD /GL /bigobj /MP
INCLUDES = -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\..\.. -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\include -external:W0
OBJECT_DIR = CMakeFiles\_s_curve_native.dir
OBJECT_FILE_DIR = CMakeFiles\_s_curve_native.dir\src
TARGET_COMPILE_PDB = CMakeFiles\_s_curve_native.dir\
TARGET_PDB = _s_curve_native.pdb
build CMakeFiles\_s_curve_native.dir\src\s_curve_pybind.cpp.obj: CXX_COMPILER___s_curve_native_unscanned_Release D$:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\src\s_curve_pybind.cpp || cmake_object_order_depends_target__s_curve_native
DEFINES = -D_s_curve_native_EXPORTS
FLAGS = /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -std:c++17 -MD /GL /bigobj /MP
INCLUDES = -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\..\.. -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\include -external:W0
OBJECT_DIR = CMakeFiles\_s_curve_native.dir
OBJECT_FILE_DIR = CMakeFiles\_s_curve_native.dir\src
TARGET_COMPILE_PDB = CMakeFiles\_s_curve_native.dir\
TARGET_PDB = _s_curve_native.pdb
build CMakeFiles\_s_curve_native.dir\D_\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src\s_curve_velocity_planner.cpp.obj: CXX_COMPILER___s_curve_native_unscanned_Release D$:\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src\s_curve_velocity_planner.cpp || cmake_object_order_depends_target__s_curve_native
DEFINES = -D_s_curve_native_EXPORTS
FLAGS = /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -std:c++17 -MD /GL /bigobj /MP
INCLUDES = -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\..\.. -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\include -external:W0
OBJECT_DIR = CMakeFiles\_s_curve_native.dir
OBJECT_FILE_DIR = CMakeFiles\_s_curve_native.dir\D_\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src
TARGET_COMPILE_PDB = CMakeFiles\_s_curve_native.dir\
TARGET_PDB = _s_curve_native.pdb
build CMakeFiles\_s_curve_native.dir\D_\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src\s_curve_position_planner.cpp.obj: CXX_COMPILER___s_curve_native_unscanned_Release D$:\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src\s_curve_position_planner.cpp || cmake_object_order_depends_target__s_curve_native
DEFINES = -D_s_curve_native_EXPORTS
FLAGS = /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -std:c++17 -MD /GL /bigobj /MP
INCLUDES = -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\..\.. -ID:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\include -external:IC:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\include -external:W0
OBJECT_DIR = CMakeFiles\_s_curve_native.dir
OBJECT_FILE_DIR = CMakeFiles\_s_curve_native.dir\D_\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src
TARGET_COMPILE_PDB = CMakeFiles\_s_curve_native.dir\
TARGET_PDB = _s_curve_native.pdb
# =============================================================================
# Link build statements for MODULE_LIBRARY target _s_curve_native
#############################################
# Link the shared module _s_curve_native.cp310-win_amd64.pyd
build _s_curve_native.cp310-win_amd64.pyd: CXX_MODULE_LIBRARY_LINKER___s_curve_native_Release CMakeFiles\_s_curve_native.dir\src\s_curve.cpp.obj CMakeFiles\_s_curve_native.dir\src\s_curve_pybind.cpp.obj CMakeFiles\_s_curve_native.dir\D_\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src\s_curve_velocity_planner.cpp.obj CMakeFiles\_s_curve_native.dir\D_\cmvr\0-worksapce\cmvr-head-client\cpp\planner\s_curve_planner\src\s_curve_position_planner.cpp.obj | C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\libs\python310.lib
LANGUAGE_COMPILE_FLAGS = /DWIN32 /D_WINDOWS /EHsc /O2 /Ob2 /DNDEBUG -MD
LINK_FLAGS = /machine:x64 /INCREMENTAL:NO -LTCG
LINK_LIBRARIES = C:\Users\Administrator\miniconda3\envs\cmvr-head-client\libs\python310.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
OBJECT_DIR = CMakeFiles\_s_curve_native.dir
POST_BUILD = cd .
PRE_LINK = cd .
TARGET_COMPILE_PDB = CMakeFiles\_s_curve_native.dir\
TARGET_FILE = _s_curve_native.cp310-win_amd64.pyd
TARGET_IMPLIB = _s_curve_native.lib
TARGET_PDB = _s_curve_native.pdb
#############################################
# Utility command for edit_cache
build CMakeFiles\edit_cache.util: CUSTOM_COMMAND
COMMAND = C:\windows\system32\cmd.exe /C "cd /D D:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\build && "C:\Program Files\STM32\STM32CubeCLT_1.20.0\CMake\bin\cmake-gui.exe" -SD:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve -BD:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\build"
DESC = Running CMake cache editor...
pool = console
restat = 1
build edit_cache: phony CMakeFiles\edit_cache.util
#############################################
# Utility command for rebuild_cache
build CMakeFiles\rebuild_cache.util: CUSTOM_COMMAND
COMMAND = C:\windows\system32\cmd.exe /C "cd /D D:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\build && "C:\Program Files\STM32\STM32CubeCLT_1.20.0\CMake\bin\cmake.exe" --regenerate-during-build -SD:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve -BD:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\build"
DESC = Running CMake to regenerate build system...
pool = console
restat = 1
build rebuild_cache: phony CMakeFiles\rebuild_cache.util
# =============================================================================
# Target aliases.
build _s_curve_native: phony _s_curve_native.cp310-win_amd64.pyd
# =============================================================================
# Folder targets.
# =============================================================================
#############################################
# Folder: D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build
build all: phony _s_curve_native.cp310-win_amd64.pyd
# =============================================================================
# Built-in targets
#############################################
# Re-run CMake if any of its inputs changed.
build build.ninja: RERUN_CMAKE | C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeCXXInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeCheckCompilerFlagCommonPatterns.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeCommonLanguageInclude.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeGenericSystem.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeInitializeConfigs.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeLanguageInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeRCInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeSystemSpecificInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeSystemSpecificInitialize.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CheckCXXCompilerFlag.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CheckCXXSourceCompiles.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Compiler\CMakeCommonCompilerMacros.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Compiler\MSVC-CXX.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Compiler\MSVC.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPackageHandleStandardArgs.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPackageMessage.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPython.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPython\Support.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Internal\CheckCompilerFlag.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Internal\CheckFlagCommonConfig.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Internal\CheckSourceCompiles.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows-Initialize.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows-MSVC-CXX.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows-MSVC.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\WindowsPaths.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11Common.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11Config.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11ConfigVersion.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11NewTools.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11Targets.cmake CMakeCache.txt CMakeFiles\3.28.1\CMakeCXXCompiler.cmake CMakeFiles\3.28.1\CMakeRCCompiler.cmake CMakeFiles\3.28.1\CMakeSystem.cmake D$:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\CMakeLists.txt
pool = console
#############################################
# A missing CMake input file is not an error.
build C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeCXXInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeCheckCompilerFlagCommonPatterns.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeCommonLanguageInclude.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeGenericSystem.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeInitializeConfigs.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeLanguageInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeRCInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeSystemSpecificInformation.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CMakeSystemSpecificInitialize.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CheckCXXCompilerFlag.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\CheckCXXSourceCompiles.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Compiler\CMakeCommonCompilerMacros.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Compiler\MSVC-CXX.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Compiler\MSVC.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPackageHandleStandardArgs.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPackageMessage.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPython.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\FindPython\Support.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Internal\CheckCompilerFlag.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Internal\CheckFlagCommonConfig.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Internal\CheckSourceCompiles.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows-Initialize.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows-MSVC-CXX.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows-MSVC.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\Windows.cmake C$:\Program$ Files\STM32\STM32CubeCLT_1.20.0\CMake\share\cmake-3.28\Modules\Platform\WindowsPaths.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11Common.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11Config.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11ConfigVersion.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11NewTools.cmake C$:\Users\Administrator\miniconda3\envs\cmvr-head-client\Lib\site-packages\pybind11\share\cmake\pybind11\pybind11Targets.cmake CMakeCache.txt CMakeFiles\3.28.1\CMakeCXXCompiler.cmake CMakeFiles\3.28.1\CMakeRCCompiler.cmake CMakeFiles\3.28.1\CMakeSystem.cmake D$:\cmvr\0-worksapce\cmvr-head-client\cpp\common\curve\CMakeLists.txt: phony
#############################################
# Clean all the built files.
build clean: CLEAN
#############################################
# Print all primary targets available.
build help: HELP
#############################################
# Make the all target the default.
default all

View File

@ -0,0 +1,44 @@
# Install script for directory: D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "C:/Program Files (x86)/cmvr_scurve")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
# Set the install configuration name.
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
if(BUILD_TYPE)
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
else()
set(CMAKE_INSTALL_CONFIG_NAME "Release")
endif()
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
endif()
# Set the component getting installed.
if(NOT CMAKE_INSTALL_COMPONENT)
if(COMPONENT)
message(STATUS "Install component: \"${COMPONENT}\"")
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
else()
set(CMAKE_INSTALL_COMPONENT)
endif()
endif()
# Is this installation the result of a crosscompile?
if(NOT DEFINED CMAKE_CROSSCOMPILING)
set(CMAKE_CROSSCOMPILING "FALSE")
endif()
if(CMAKE_INSTALL_COMPONENT)
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
else()
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
endif()
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
"${CMAKE_INSTALL_MANIFEST_FILES}")
file(WRITE "D:/cmvr/0-worksapce/cmvr-head-client/cpp/common/curve/build/${CMAKE_INSTALL_MANIFEST}"
"${CMAKE_INSTALL_MANIFEST_CONTENT}")

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,35 @@
param(
[string]$PythonExecutable = "C:\Users\Administrator\miniconda3\envs\cmvr-head-client\python.exe"
)
$ErrorActionPreference = "Stop"
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\\..\\..")
$sourceDir = Join-Path $repoRoot "cpp\\common\\curve"
$buildDir = Join-Path $sourceDir "build"
$vsDevCmd = "C:\\Program Files\\Microsoft Visual Studio\\18\\Community\\Common7\\Tools\\VsDevCmd.bat"
if (-not (Test-Path $vsDevCmd)) {
throw "VsDevCmd.bat not found at $vsDevCmd"
}
if (-not (Test-Path $PythonExecutable)) {
throw "Python executable not found at $PythonExecutable"
}
New-Item -ItemType Directory -Force -Path $buildDir | Out-Null
$configure = "call `"$vsDevCmd`" -arch=x64 && cmake -S `"$sourceDir`" -B `"$buildDir`" -G Ninja -DCMAKE_BUILD_TYPE=Release -DPython_EXECUTABLE=`"$PythonExecutable`""
cmd /c $configure
if ($LASTEXITCODE -ne 0) {
throw "CMake configure failed."
}
$build = "call `"$vsDevCmd`" -arch=x64 && cmake --build `"$buildDir`" --config Release"
cmd /c $build
if ($LASTEXITCODE -ne 0) {
throw "CMake build failed."
}
Write-Host "Built Python module:"
Get-ChildItem $buildDir -Filter "_s_curve_native*.pyd" -Recurse | Select-Object FullName

View File

@ -0,0 +1,167 @@
//
// Created by lgv on 2026/3/2.
//
/**
* @file s_curve.h
* @brief S 线
*
* 7 S 线
* 1.
* 2.
* 3. 0
* 4.
* 5.
* 6.
* 7. 0
*
* profile
*/
#pragma once
#include <algorithm>
#include <cmath>
#include <vector>
namespace cmvr
{
/**
* @brief S 线
*/
struct SCurveProfile
{
// 7 个阶段的持续时间
double t1; // 加加速度上升时间(加速阶段)
double t2; // 匀加速时间
double t3; // 加加速度下降时间(加速阶段结束)
double t4; // 匀速时间(巡航)
double t5; // 加加速度下降时间(减速阶段)
double t6; // 匀减速时间
double t7; // 加加速度上升时间(减速阶段结束)
double total_time;
// 运动约束
double j_max; // 最大加加速度 (rad/s³)
double a_max; // 最大加速度 (rad/s²)
double v_max; // 最大速度 (rad/s)
// 运动参数
double distance; // 运动总距离
double direction; // +1 或 -1
double v_cruise; // 实际达到的巡航速度
double a_limit; // 实际达到的加速度上限
// 初始条件
double p0; // 初始位置
double v0; // 初始速度
double a0; // 初始加速度
double vf; // 终止速度
SCurveProfile()
: t1(0), t2(0), t3(0), t4(0), t5(0), t6(0), t7(0)
, total_time(0)
, j_max(50.0), a_max(10.0), v_max(3.0)
, distance(0), direction(1.0), v_cruise(0), a_limit(0)
, p0(0), v0(0), a0(0), vf(0)
{}
};
/**
* @brief S 线
*/
class SCurve
{
public:
/**
* @brief
* @param max_velocity (rad/s)
* @param max_acceleration (rad/s²)
* @param max_jerk (rad/s³)
*/
SCurve(double max_velocity = 3.0,
double max_acceleration = 10.0,
double max_jerk = 50.0);
/**
* @brief
*/
void setConstraints(double max_velocity, double max_acceleration, double max_jerk);
/**
* @brief
*/
void getConstraints(double& max_velocity, double& max_acceleration, double& max_jerk) const;
/**
* @brief S 线
* @param start_position
* @param end_position
* @param start_velocity 0
* @param end_velocity 0
* @return
*/
SCurveProfile calculateProfile(double start_position, double end_position,
double start_velocity = 0.0, double end_velocity = 0.0);
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getPositionAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getVelocityAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getAccelerationAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getJerkAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief
* @param profile S 线
* @param dt
* @param positions
* @param velocities
* @param accelerations
*/
void generateTrajectory(const SCurveProfile& profile, double dt,
std::vector<double>& positions,
std::vector<double>& velocities,
std::vector<double>& accelerations) const;
private:
double max_velocity_;
double max_acceleration_;
double max_jerk_;
static constexpr double EPSILON = 1e-9;
static constexpr double VELOCITY_THRESHOLD = 1e-6;
double computeSegmentJerk(const SCurveProfile& profile, double t) const;
void calculateShortProfile(SCurveProfile& profile) const;
void calculateLongProfile(SCurveProfile& profile) const;
};
} // namespace cmvr

View File

@ -0,0 +1,542 @@
//
// Created by lgv on 2026/3/2.
//
/**
* @file s_curve_generator.cpp
* @brief S 线
*/
#include "common/curve/include/s_curve.h"
#include <cmath>
#include <algorithm>
#include <stdexcept>
namespace cmvr
{
SCurve::SCurve(double max_velocity, double max_acceleration, double max_jerk)
: max_velocity_(std::abs(max_velocity))
, max_acceleration_(std::abs(max_acceleration))
, max_jerk_(std::abs(max_jerk))
{}
void SCurve::setConstraints(double max_velocity, double max_acceleration, double max_jerk)
{
max_velocity_ = std::abs(max_velocity);
max_acceleration_ = std::abs(max_acceleration);
max_jerk_ = std::abs(max_jerk);
}
void SCurve::getConstraints(double& max_velocity, double& max_acceleration, double& max_jerk) const
{
max_velocity = max_velocity_;
max_acceleration = max_acceleration_;
max_jerk = max_jerk_;
}
SCurveProfile SCurve::calculateProfile(double start_position, double end_position,
double start_velocity, double end_velocity)
{
SCurveProfile profile;
profile.j_max = max_jerk_;
profile.a_max = max_acceleration_;
profile.v_max = max_velocity_;
profile.p0 = start_position;
profile.v0 = start_velocity;
profile.a0 = 0.0; // Assume starting from zero acceleration
profile.vf = end_velocity;
double displacement = end_position - start_position;
profile.distance = std::abs(displacement);
profile.direction = (displacement >= 0) ? 1.0 : -1.0;
if (profile.distance < EPSILON) {
// 无需运动
profile.total_time = 0.0;
return profile;
}
const double start_speed = profile.direction * start_velocity;
const double end_speed = profile.direction * end_velocity;
if (start_speed < -VELOCITY_THRESHOLD || end_speed < -VELOCITY_THRESHOLD) {
profile.total_time = 0.0;
return profile;
}
if (std::abs(start_speed) > VELOCITY_THRESHOLD ||
std::abs(end_speed) > VELOCITY_THRESHOLD) {
auto calc_transition = [&](double v_from, double v_to,
double& t_j, double& t_a,
double& duration, double& distance) {
t_j = 0.0;
t_a = 0.0;
duration = 0.0;
distance = 0.0;
const double dv = std::abs(v_to - v_from);
if (dv <= 1e-12 || profile.a_max <= 1e-12 || profile.j_max <= 1e-12) {
return;
}
const double dv_switch = profile.a_max * profile.a_max / profile.j_max;
if (dv < dv_switch) {
t_j = std::sqrt(dv / profile.j_max);
t_a = 0.0;
} else {
t_j = profile.a_max / profile.j_max;
t_a = dv / profile.a_max - t_j;
}
duration = 2.0 * t_j + t_a;
distance = 0.5 * (v_from + v_to) * duration;
};
const double v_cap = std::max({profile.v_max, start_speed, end_speed});
const double v_peak_min = std::max(start_speed, end_speed);
double acc_tj = 0.0, acc_ta = 0.0, acc_duration = 0.0, acc_distance = 0.0;
double dec_tj = 0.0, dec_ta = 0.0, dec_duration = 0.0, dec_distance = 0.0;
calc_transition(start_speed, v_peak_min,
acc_tj, acc_ta, acc_duration, acc_distance);
calc_transition(v_peak_min, end_speed,
dec_tj, dec_ta, dec_duration, dec_distance);
const double d_min = acc_distance + dec_distance;
if (profile.distance + EPSILON < d_min) {
profile.total_time = 0.0;
return profile;
}
calc_transition(start_speed, v_cap,
acc_tj, acc_ta, acc_duration, acc_distance);
calc_transition(v_cap, end_speed,
dec_tj, dec_ta, dec_duration, dec_distance);
const double d_cap = acc_distance + dec_distance;
double v_peak = v_cap;
double t4 = 0.0;
if (profile.distance > d_cap + EPSILON) {
t4 = (profile.distance - d_cap) / std::max(v_peak, EPSILON);
} else {
double lo = v_peak_min;
double hi = v_cap;
for (int iter = 0; iter < 80; ++iter) {
const double mid = 0.5 * (lo + hi);
double mid_acc_tj = 0.0, mid_acc_ta = 0.0, mid_acc_duration = 0.0, mid_acc_distance = 0.0;
double mid_dec_tj = 0.0, mid_dec_ta = 0.0, mid_dec_duration = 0.0, mid_dec_distance = 0.0;
calc_transition(start_speed, mid,
mid_acc_tj, mid_acc_ta, mid_acc_duration, mid_acc_distance);
calc_transition(mid, end_speed,
mid_dec_tj, mid_dec_ta, mid_dec_duration, mid_dec_distance);
const double d_mid = mid_acc_distance + mid_dec_distance;
if (d_mid < profile.distance) {
lo = mid;
} else {
hi = mid;
}
}
v_peak = hi;
calc_transition(start_speed, v_peak,
acc_tj, acc_ta, acc_duration, acc_distance);
calc_transition(v_peak, end_speed,
dec_tj, dec_ta, dec_duration, dec_distance);
}
profile.t1 = acc_tj;
profile.t2 = acc_ta;
profile.t3 = acc_tj;
profile.t4 = t4;
profile.t5 = dec_tj;
profile.t6 = dec_ta;
profile.t7 = dec_tj;
profile.v_cruise = v_peak;
profile.a_limit = std::max(profile.j_max * profile.t1, profile.j_max * profile.t5);
profile.total_time = profile.t1 + profile.t2 + profile.t3 + profile.t4 +
profile.t5 + profile.t6 + profile.t7;
return profile;
}
const double j = profile.j_max;
const double a = profile.a_max;
const double v = profile.v_max;
const double t_j_a = a / j;
if (v < a * t_j_a) {
const double t_j_v = std::sqrt(v / j);
const double s_min = 2.0 * j * t_j_v * t_j_v * t_j_v;
if (profile.distance > s_min + EPSILON) {
calculateLongProfile(profile);
} else {
calculateShortProfile(profile);
}
} else {
const double t_a_v = v / a - t_j_a;
const double s_half_v =
a * (t_j_a * t_j_a + 1.5 * t_j_a * t_a_v + 0.5 * t_a_v * t_a_v);
const double s_min = 2.0 * s_half_v;
if (profile.distance > s_min + EPSILON) {
calculateLongProfile(profile);
} else {
calculateShortProfile(profile);
}
}
return profile;
}
void SCurve::calculateShortProfile(SCurveProfile& profile) const
{
// 短距离无巡航段t4 = 0与 moveL_SCurveLocal 中的 SCurveProfile1D 保持一致。
const double j = profile.j_max;
const double a = profile.a_max;
const double v = profile.v_max;
const double d = profile.distance;
const double t_j_a = a / j;
if (v < a * t_j_a) {
// 达不到 a_max极短距离时只有 4 个 jerk 段。
const double t1 = std::cbrt(d / (2.0 * j));
profile.t1 = t1;
profile.t2 = 0.0;
profile.t3 = t1;
profile.t4 = 0.0;
profile.t5 = t1;
profile.t6 = 0.0;
profile.t7 = t1;
profile.v_cruise = j * t1 * t1;
profile.a_limit = j * t1;
} else {
// 能达到 a_max但达不到 v_max求无巡航的匀加速持续时间。
const double D = t_j_a * t_j_a + 4.0 * (d / a);
double t2 = (-3.0 * t_j_a + std::sqrt(std::max(0.0, D))) * 0.5;
if (t2 < 0.0) {
const double t1 = std::cbrt(d / (2.0 * j));
profile.t1 = t1;
profile.t2 = 0.0;
profile.t3 = t1;
profile.t4 = 0.0;
profile.t5 = t1;
profile.t6 = 0.0;
profile.t7 = t1;
profile.v_cruise = j * t1 * t1;
profile.a_limit = j * t1;
} else {
profile.t1 = t_j_a;
profile.t2 = t2;
profile.t3 = t_j_a;
profile.t4 = 0.0;
profile.t5 = t_j_a;
profile.t6 = t2;
profile.t7 = t_j_a;
profile.v_cruise = a * (t2 + t_j_a);
profile.a_limit = a;
}
}
profile.total_time = profile.t1 + profile.t2 + profile.t3 + profile.t4 +
profile.t5 + profile.t6 + profile.t7;
}
void SCurve::calculateLongProfile(SCurveProfile& profile) const
{
// 含巡航段的完整 7 段式 S 曲线;与 SCurveProfile1D 的 full-profile 公式一致。
const double j = profile.j_max;
const double a = profile.a_max;
const double v = profile.v_max;
const double d = profile.distance;
const double t_j_a = a / j;
if (v < a * t_j_a) {
// 达不到 a_max但可以达到 v_max 并进入巡航。
const double t_j_v = std::sqrt(v / j);
const double s_min = 2.0 * j * t_j_v * t_j_v * t_j_v;
profile.t1 = t_j_v;
profile.t2 = 0.0;
profile.t3 = t_j_v;
profile.t4 = std::max(0.0, (d - s_min) / v);
profile.t5 = t_j_v;
profile.t6 = 0.0;
profile.t7 = t_j_v;
profile.v_cruise = v;
profile.a_limit = j * t_j_v;
} else {
// 能达到 a_max 和 v_max。
const double t_a = v / a - t_j_a;
const double s_half =
a * (t_j_a * t_j_a + 1.5 * t_j_a * t_a + 0.5 * t_a * t_a);
const double s_min = 2.0 * s_half;
profile.t1 = t_j_a;
profile.t2 = t_a;
profile.t3 = t_j_a;
profile.t4 = std::max(0.0, (d - s_min) / v);
profile.t5 = t_j_a;
profile.t6 = t_a;
profile.t7 = t_j_a;
profile.v_cruise = v;
profile.a_limit = a;
}
profile.total_time = profile.t1 + profile.t2 + profile.t3 + profile.t4 +
profile.t5 + profile.t6 + profile.t7;
}
double SCurve::computeSegmentJerk(const SCurveProfile& profile, double t) const
{
double j = profile.j_max * profile.direction;
// 判断所处阶段
double t_end1 = profile.t1;
double t_end2 = t_end1 + profile.t2;
double t_end3 = t_end2 + profile.t3;
double t_end4 = t_end3 + profile.t4;
double t_end5 = t_end4 + profile.t5;
double t_end6 = t_end5 + profile.t6;
// double t_end7 = t_end6 + profile.t7; // = total_time
if (t < t_end1) {
return j; // 段 1正加加速度加速
} else if (t < t_end2) {
return 0.0; // 段 2加加速度为 0匀加速
} else if (t < t_end3) {
return -j; // 段 3负加加速度减小加速度
} else if (t < t_end4) {
return 0.0; // 段 4加加速度为 0巡航
} else if (t < t_end5) {
return -j; // 段 5负加加速度开始减速
} else if (t < t_end6) {
return 0.0; // 段 6加加速度为 0匀减速
} else {
return j; // 段 7正加加速度减速结束
}
}
double SCurve::getPositionAtTime(const SCurveProfile& profile, double t) const
{
if (t <= 0) return profile.p0;
if (t >= profile.total_time) return profile.p0 + profile.distance * profile.direction;
double j = profile.j_max * profile.direction;
double p = profile.p0;
double v = profile.v0;
double a = profile.a0;
// 时间边界
double t_end1 = profile.t1;
double t_end2 = t_end1 + profile.t2;
double t_end3 = t_end2 + profile.t3;
double t_end4 = t_end3 + profile.t4;
double t_end5 = t_end4 + profile.t5;
double t_end6 = t_end5 + profile.t6;
// 依次处理各阶段
auto processSegment = [&](double dt, double jerk) {
p += v * dt + 0.5 * a * dt * dt + (1.0/6.0) * jerk * dt * dt * dt;
v += a * dt + 0.5 * jerk * dt * dt;
a += jerk * dt;
};
// 段 1
if (t <= t_end1) {
processSegment(t, j);
return p;
}
processSegment(profile.t1, j);
// 段 2
if (t <= t_end2) {
processSegment(t - t_end1, 0.0);
return p;
}
processSegment(profile.t2, 0.0);
// 段 3
if (t <= t_end3) {
processSegment(t - t_end2, -j);
return p;
}
processSegment(profile.t3, -j);
// 段 4巡航
if (t <= t_end4) {
processSegment(t - t_end3, 0.0);
return p;
}
processSegment(profile.t4, 0.0);
// 段 5
if (t <= t_end5) {
processSegment(t - t_end4, -j);
return p;
}
processSegment(profile.t5, -j);
// 段 6
if (t <= t_end6) {
processSegment(t - t_end5, 0.0);
return p;
}
processSegment(profile.t6, 0.0);
// 段 7
processSegment(t - t_end6, j);
return p;
}
double SCurve::getVelocityAtTime(const SCurveProfile& profile, double t) const
{
if (t <= 0) return profile.v0;
if (t >= profile.total_time) return profile.vf;
double j = profile.j_max * profile.direction;
double v = profile.v0;
double a = profile.a0;
// 时间边界
double t_end1 = profile.t1;
double t_end2 = t_end1 + profile.t2;
double t_end3 = t_end2 + profile.t3;
double t_end4 = t_end3 + profile.t4;
double t_end5 = t_end4 + profile.t5;
double t_end6 = t_end5 + profile.t6;
auto processSegment = [&](double dt, double jerk) {
v += a * dt + 0.5 * jerk * dt * dt;
a += jerk * dt;
};
if (t <= t_end1) {
v += a * t + 0.5 * j * t * t;
return v;
}
processSegment(profile.t1, j);
if (t <= t_end2) {
v += a * (t - t_end1);
return v;
}
processSegment(profile.t2, 0.0);
if (t <= t_end3) {
double dt = t - t_end2;
v += a * dt + 0.5 * (-j) * dt * dt;
return v;
}
processSegment(profile.t3, -j);
if (t <= t_end4) {
v += a * (t - t_end3);
return v;
}
processSegment(profile.t4, 0.0);
if (t <= t_end5) {
double dt = t - t_end4;
v += a * dt + 0.5 * (-j) * dt * dt;
return v;
}
processSegment(profile.t5, -j);
if (t <= t_end6) {
v += a * (t - t_end5);
return v;
}
processSegment(profile.t6, 0.0);
double dt = t - t_end6;
v += a * dt + 0.5 * j * dt * dt;
return v;
}
double SCurve::getAccelerationAtTime(const SCurveProfile& profile, double t) const
{
if (t <= 0 || t >= profile.total_time) return 0.0;
double j = profile.j_max * profile.direction;
double a = profile.a0;
// 时间边界
double t_end1 = profile.t1;
double t_end2 = t_end1 + profile.t2;
double t_end3 = t_end2 + profile.t3;
double t_end4 = t_end3 + profile.t4;
double t_end5 = t_end4 + profile.t5;
double t_end6 = t_end5 + profile.t6;
if (t <= t_end1) {
return a + j * t;
}
a += j * profile.t1;
if (t <= t_end2) {
return a;
}
if (t <= t_end3) {
return a + (-j) * (t - t_end2);
}
a += (-j) * profile.t3;
if (t <= t_end4) {
return a; // Should be ~0
}
if (t <= t_end5) {
return a + (-j) * (t - t_end4);
}
a += (-j) * profile.t5;
if (t <= t_end6) {
return a;
}
return a + j * (t - t_end6);
}
double SCurve::getJerkAtTime(const SCurveProfile& profile, double t) const
{
if (t <= 0.0 || t >= profile.total_time) {
return 0.0;
}
return computeSegmentJerk(profile, t);
}
void SCurve::generateTrajectory(const SCurveProfile& profile, double dt,
std::vector<double>& positions,
std::vector<double>& velocities,
std::vector<double>& accelerations) const
{
positions.clear();
velocities.clear();
accelerations.clear();
if (profile.total_time <= 0 || dt <= 0) {
positions.push_back(profile.p0);
velocities.push_back(profile.v0);
accelerations.push_back(profile.a0);
return;
}
int num_points = static_cast<int>(std::ceil(profile.total_time / dt)) + 1;
positions.reserve(num_points);
velocities.reserve(num_points);
accelerations.reserve(num_points);
for (double t = 0; t <= profile.total_time; t += dt) {
positions.push_back(getPositionAtTime(profile, t));
velocities.push_back(getVelocityAtTime(profile, t));
accelerations.push_back(getAccelerationAtTime(profile, t));
}
// 确保包含最终点
if (positions.empty() ||
std::abs(positions.back() - (profile.p0 + profile.distance * profile.direction)) > EPSILON) {
positions.push_back(profile.p0 + profile.distance * profile.direction);
velocities.push_back(profile.vf);
accelerations.push_back(0.0);
}
}
}

View File

@ -0,0 +1,171 @@
#include "common/curve/include/s_curve.h"
#include "planner/s_curve_planner/include/s_curve_position_planner.h"
#include <algorithm>
#include <stdexcept>
#include <vector>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
namespace {
py::dict sample_trajectory(const cmvr::SCurve& curve, const cmvr::SCurveProfile& profile, double dt)
{
if (dt <= 0.0) {
throw std::invalid_argument("dt must be > 0");
}
std::vector<double> times;
std::vector<double> positions;
std::vector<double> velocities;
std::vector<double> accelerations;
std::vector<double> jerks;
if (profile.total_time <= 0.0) {
times.push_back(0.0);
positions.push_back(profile.p0);
velocities.push_back(profile.v0);
accelerations.push_back(profile.a0);
jerks.push_back(0.0);
} else {
for (double t = 0.0; t <= profile.total_time + 1e-12; t += dt) {
const double sample_time = std::min(t, profile.total_time);
times.push_back(sample_time);
positions.push_back(curve.getPositionAtTime(profile, sample_time));
velocities.push_back(curve.getVelocityAtTime(profile, sample_time));
accelerations.push_back(curve.getAccelerationAtTime(profile, sample_time));
jerks.push_back(curve.getJerkAtTime(profile, sample_time));
}
if (std::abs(times.back() - profile.total_time) > 1e-9) {
times.push_back(profile.total_time);
positions.push_back(curve.getPositionAtTime(profile, profile.total_time));
velocities.push_back(curve.getVelocityAtTime(profile, profile.total_time));
accelerations.push_back(curve.getAccelerationAtTime(profile, profile.total_time));
jerks.push_back(curve.getJerkAtTime(profile, profile.total_time));
}
}
py::dict result;
result["times"] = times;
result["positions"] = positions;
result["velocities"] = velocities;
result["accelerations"] = accelerations;
result["jerks"] = jerks;
return result;
}
} // namespace
PYBIND11_MODULE(_s_curve_native, m)
{
m.doc() = "pybind11 bindings for cmvr::SCurve";
py::class_<cmvr::SCurveProfile>(m, "SCurveProfile")
.def(py::init<>())
.def_readwrite("t1", &cmvr::SCurveProfile::t1)
.def_readwrite("t2", &cmvr::SCurveProfile::t2)
.def_readwrite("t3", &cmvr::SCurveProfile::t3)
.def_readwrite("t4", &cmvr::SCurveProfile::t4)
.def_readwrite("t5", &cmvr::SCurveProfile::t5)
.def_readwrite("t6", &cmvr::SCurveProfile::t6)
.def_readwrite("t7", &cmvr::SCurveProfile::t7)
.def_readwrite("total_time", &cmvr::SCurveProfile::total_time)
.def_readwrite("j_max", &cmvr::SCurveProfile::j_max)
.def_readwrite("a_max", &cmvr::SCurveProfile::a_max)
.def_readwrite("v_max", &cmvr::SCurveProfile::v_max)
.def_readwrite("distance", &cmvr::SCurveProfile::distance)
.def_readwrite("direction", &cmvr::SCurveProfile::direction)
.def_readwrite("v_cruise", &cmvr::SCurveProfile::v_cruise)
.def_readwrite("a_limit", &cmvr::SCurveProfile::a_limit)
.def_readwrite("p0", &cmvr::SCurveProfile::p0)
.def_readwrite("v0", &cmvr::SCurveProfile::v0)
.def_readwrite("a0", &cmvr::SCurveProfile::a0)
.def_readwrite("vf", &cmvr::SCurveProfile::vf);
py::class_<cmvr::SCurve>(m, "SCurve")
.def(py::init<double, double, double>(),
py::arg("max_velocity") = 3.0,
py::arg("max_acceleration") = 10.0,
py::arg("max_jerk") = 50.0)
.def("setConstraints", &cmvr::SCurve::setConstraints,
py::arg("max_velocity"),
py::arg("max_acceleration"),
py::arg("max_jerk"))
.def("getConstraints", [](const cmvr::SCurve& self) {
double max_velocity = 0.0;
double max_acceleration = 0.0;
double max_jerk = 0.0;
self.getConstraints(max_velocity, max_acceleration, max_jerk);
return py::make_tuple(max_velocity, max_acceleration, max_jerk);
})
.def("calculateProfile", &cmvr::SCurve::calculateProfile,
py::arg("start_position"),
py::arg("end_position"),
py::arg("start_velocity") = 0.0,
py::arg("end_velocity") = 0.0)
.def("getPositionAtTime", &cmvr::SCurve::getPositionAtTime,
py::arg("profile"),
py::arg("t"))
.def("getVelocityAtTime", &cmvr::SCurve::getVelocityAtTime,
py::arg("profile"),
py::arg("t"))
.def("getAccelerationAtTime", &cmvr::SCurve::getAccelerationAtTime,
py::arg("profile"),
py::arg("t"))
.def("getJerkAtTime", &cmvr::SCurve::getJerkAtTime,
py::arg("profile"),
py::arg("t"))
.def("sampleTrajectory", &sample_trajectory,
py::arg("profile"),
py::arg("dt"));
py::class_<cmvr::SCurvePositionPlannerState>(m, "SCurvePositionPlannerState")
.def(py::init<>())
.def_readwrite("position", &cmvr::SCurvePositionPlannerState::position)
.def_readwrite("velocity", &cmvr::SCurvePositionPlannerState::velocity)
.def_readwrite("acceleration", &cmvr::SCurvePositionPlannerState::acceleration)
.def_readwrite("jerk", &cmvr::SCurvePositionPlannerState::jerk)
.def_readwrite("target_position", &cmvr::SCurvePositionPlannerState::target_position)
.def_readwrite("is_moving", &cmvr::SCurvePositionPlannerState::is_moving);
py::class_<cmvr::SCurvePositionPlanner1D>(m, "SCurvePositionPlanner1D")
.def(py::init<double, double, double>(),
py::arg("max_velocity") = 3.0,
py::arg("max_acceleration") = 10.0,
py::arg("max_jerk") = 50.0)
.def("setConstraints", &cmvr::SCurvePositionPlanner1D::setConstraints,
py::arg("max_velocity"),
py::arg("max_acceleration"),
py::arg("max_jerk"))
.def("getConstraints", [](const cmvr::SCurvePositionPlanner1D& self) {
double max_velocity = 0.0;
double max_acceleration = 0.0;
double max_jerk = 0.0;
self.getConstraints(max_velocity, max_acceleration, max_jerk);
return py::make_tuple(max_velocity, max_acceleration, max_jerk);
})
.def("setPositionGain", &cmvr::SCurvePositionPlanner1D::setPositionGain,
py::arg("position_gain"))
.def("getPositionGain", &cmvr::SCurvePositionPlanner1D::getPositionGain)
.def("initialize", &cmvr::SCurvePositionPlanner1D::initialize,
py::arg("position"),
py::arg("velocity") = 0.0,
py::arg("acceleration") = 0.0)
.def("reset", &cmvr::SCurvePositionPlanner1D::reset)
.def("setTarget", &cmvr::SCurvePositionPlanner1D::setTarget,
py::arg("target_position"))
.def("update", &cmvr::SCurvePositionPlanner1D::update,
py::arg("dt"))
.def("getState", &cmvr::SCurvePositionPlanner1D::getState,
py::return_value_policy::reference_internal)
.def("getPosition", &cmvr::SCurvePositionPlanner1D::getPosition)
.def("getVelocity", &cmvr::SCurvePositionPlanner1D::getVelocity)
.def("getAcceleration", &cmvr::SCurvePositionPlanner1D::getAcceleration)
.def("getJerk", &cmvr::SCurvePositionPlanner1D::getJerk)
.def("getTargetPosition", &cmvr::SCurvePositionPlanner1D::getTargetPosition)
.def("isMoving", &cmvr::SCurvePositionPlanner1D::isMoving);
}

View File

@ -0,0 +1,100 @@
//
// Created by lgv on 2026/3/10.
//
#pragma once
#include "s_curve_velocity_planner.h"
#include <algorithm>
#include <cmath>
namespace cmvr
{
struct SCurvePositionPlannerState
{
double position;
double velocity;
double acceleration;
double jerk;
double target_position;
bool is_moving;
SCurvePositionPlannerState()
: position(0.0)
, velocity(0.0)
, acceleration(0.0)
, jerk(0.0)
, target_position(0.0)
, is_moving(false)
{}
};
/**
* @brief
*
*
* - position_error -> desired_velocity
* - SCurveVelocityPlanner1D jerk-limited
*
* profile
*/
class SCurvePositionPlanner1D
{
public:
SCurvePositionPlanner1D(double max_velocity = 3.0,
double max_acceleration = 10.0,
double max_jerk = 50.0);
void setConstraints(double max_velocity, double max_acceleration, double max_jerk);
void getConstraints(double& max_velocity, double& max_acceleration, double& max_jerk) const;
void setPositionGain(double position_gain);
double getPositionGain() const { return position_gain_; }
void initialize(double position, double velocity = 0.0, double acceleration = 0.0);
void reset();
void setTarget(double target_position);
double update(double dt);
const SCurvePositionPlannerState& getState() const { return state_; }
double getPosition() const { return state_.position; }
double getVelocity() const { return state_.velocity; }
double getAcceleration() const { return state_.acceleration; }
double getJerk() const { return state_.jerk; }
double getTargetPosition() const { return state_.target_position; }
bool isMoving() const { return state_.is_moving; }
private:
double max_velocity_;
double max_acceleration_;
double max_jerk_;
SCurvePositionPlannerState state_;
SCurveVelocityPlanner1D velocity_planner_;
double position_gain_;
static constexpr double EPSILON = 1e-9;
static constexpr double VELOCITY_THRESHOLD = 1e-6;
static constexpr double ACCELERATION_THRESHOLD = 1e-6;
static constexpr double POSITION_THRESHOLD = 1e-7;
double computeDesiredVelocity(double position_error) const;
double computePlannerStoppingDistance(double velocity, double acceleration) const;
static double clamp(double value, double min_val, double max_val)
{
return std::max(min_val, std::min(max_val, value));
}
static double sign(double value)
{
if (value > EPSILON) return 1.0;
if (value < -EPSILON) return -1.0;
return 0.0;
}
};
} // namespace cmvr

View File

@ -0,0 +1,240 @@
//
// Created by lgv on 2026/3/9.
//
#pragma once
#include <algorithm>
#include <cmath>
#include <vector>
namespace cmvr
{
/**
* @brief S 线
*
* (v0, a0) (vf, 0) 3 jerk-limited profile
*
* seg1: jerk = j1, duration = t1
* seg2: jerk = j2, duration = t2 ( j2 = 0)
* seg3: jerk = j3, duration = t3
*
* j1/j3 ±j_maxj2 0
*/
struct SCurveVelocityProfile
{
double t1;
double t2;
double t3;
double total_time;
double j1;
double j2;
double j3;
double v0;
double a0;
double vf;
bool valid;
SCurveVelocityProfile()
: t1(0.0), t2(0.0), t3(0.0)
, total_time(0.0)
, j1(0.0), j2(0.0), j3(0.0)
, v0(0.0), a0(0.0), vf(0.0)
, valid(false)
{}
};
/**
* @brief S 线
*/
struct SCurveVelocityPlannerState
{
double velocity;
double acceleration;
double jerk;
double target_velocity;
double elapsed_time;
bool has_active_profile;
bool is_moving;
SCurveVelocityPlannerState()
: velocity(0.0)
, acceleration(0.0)
, jerk(0.0)
, target_velocity(0.0)
, elapsed_time(0.0)
, has_active_profile(false)
, is_moving(false)
{}
};
/**
* @brief S 线
*
*
* - setTargetVelocity(v):
* - update(dt): active profile
* - overwriteState(v,a): profile
* - synchronizeAndReplan(v,a):
*
*
* - (v0, a0) (vf, 0)
* - |v| <= v_max, |a| <= a_max, |j| <= j_max
*/
class SCurveVelocityPlanner1D
{
public:
SCurveVelocityPlanner1D(double max_velocity = 1.0,
double max_acceleration = 1.0,
double max_jerk = 5.0);
void setConstraints(double max_velocity, double max_acceleration, double max_jerk);
void getConstraints(double& max_velocity, double& max_acceleration, double& max_jerk) const;
/**
* @brief
*
*
*/
void setTargetReplanThreshold(double threshold);
/**
* @brief
*
* profile
* synchronizeAndReplan() profile
*/
void setSynchronizeReplanThreshold(double threshold);
void initialize(double velocity = 0.0, double acceleration = 0.0);
void reset();
/**
* @brief profile
*
*
* -
* -
*/
void overwriteState(double velocity,
double acceleration = 0.0,
bool keep_target_velocity = true);
/**
* @brief
*
*
*/
void synchronizeAndReplan(double velocity,
double acceleration = 0.0);
/**
* @brief
*/
void setTargetVelocity(double target_velocity);
/**
* @brief
*/
void stop() { setTargetVelocity(0.0); }
/**
* @brief
* @param dt
* @return
*/
double update(double dt);
/**
* @brief
*/
SCurveVelocityProfile calculateProfile(double start_velocity,
double end_velocity,
double start_acceleration = 0.0) const;
/**
* @brief t
*/
double getVelocityAtTime(const SCurveVelocityProfile& profile, double t) const;
/**
* @brief t
*/
double getAccelerationAtTime(const SCurveVelocityProfile& profile, double t) const;
/**
* @brief t jerk
*/
double getJerkAtTime(const SCurveVelocityProfile& profile, double t) const;
/**
* @brief
*/
void generateTrajectory(const SCurveVelocityProfile& profile, double dt,
std::vector<double>& velocities,
std::vector<double>& accelerations,
std::vector<double>& jerks) const;
const SCurveVelocityPlannerState& getState() const { return state_; }
const SCurveVelocityProfile& getActiveProfile() const { return active_profile_; }
double getVelocity() const { return state_.velocity; }
double getAcceleration() const { return state_.acceleration; }
double getJerk() const { return state_.jerk; }
double getTargetVelocity() const { return state_.target_velocity; }
bool hasActiveProfile() const { return state_.has_active_profile; }
bool isMoving() const { return state_.is_moving; }
private:
double max_velocity_;
double max_acceleration_;
double max_jerk_;
double target_replan_threshold_;
double synchronize_replan_threshold_;
SCurveVelocityPlannerState state_;
SCurveVelocityProfile active_profile_;
static constexpr double EPSILON = 1e-9;
static constexpr double VELOCITY_THRESHOLD = 1e-6;
static constexpr double ACCELERATION_THRESHOLD = 1e-6;
static constexpr double DEFAULT_TARGET_REPLAN_THRESHOLD = 1e-9;
static constexpr double DEFAULT_SYNCHRONIZE_REPLAN_THRESHOLD = 5e-2;
private:
void updateIsMovingFlag();
/**
* @brief profile
*/
bool isVelocityLimitSatisfied(const SCurveVelocityProfile& profile) const;
/**
* @brief
*/
void integrateWholeProfile(const SCurveVelocityProfile& profile,
double& v_end,
double& a_end) const;
static double clamp(double value, double min_val, double max_val)
{
return std::max(min_val, std::min(max_val, value));
}
static double sign(double value)
{
if (value > EPSILON) return 1.0;
if (value < -EPSILON) return -1.0;
return 0.0;
}
};
} // namespace cmvr

View File

@ -0,0 +1,193 @@
//
// Created by lgv on 2026/3/10.
//
#include "planner/s_curve_planner/include/s_curve_position_planner.h"
#include <algorithm>
#include <cmath>
namespace cmvr
{
SCurvePositionPlanner1D::SCurvePositionPlanner1D(double max_velocity,
double max_acceleration,
double max_jerk)
: max_velocity_(std::abs(max_velocity))
, max_acceleration_(std::abs(max_acceleration))
, max_jerk_(std::abs(max_jerk))
, velocity_planner_(max_velocity_, max_acceleration_, max_jerk_)
, position_gain_(1.0)
{
velocity_planner_.setTargetReplanThreshold(std::max(1e-3, 0.02 * max_velocity_));
reset();
}
void SCurvePositionPlanner1D::setConstraints(double max_velocity,
double max_acceleration,
double max_jerk)
{
max_velocity_ = std::abs(max_velocity);
max_acceleration_ = std::abs(max_acceleration);
max_jerk_ = std::abs(max_jerk);
velocity_planner_.setConstraints(max_velocity_, max_acceleration_, max_jerk_);
velocity_planner_.setTargetReplanThreshold(std::max(1e-3, 0.02 * max_velocity_));
}
void SCurvePositionPlanner1D::getConstraints(double& max_velocity,
double& max_acceleration,
double& max_jerk) const
{
max_velocity = max_velocity_;
max_acceleration = max_acceleration_;
max_jerk = max_jerk_;
}
void SCurvePositionPlanner1D::setPositionGain(double position_gain)
{
position_gain_ = std::max(0.0, position_gain);
}
void SCurvePositionPlanner1D::initialize(double position, double velocity, double acceleration)
{
state_.position = position;
velocity_planner_.initialize(velocity, acceleration);
state_.velocity = velocity_planner_.getVelocity();
state_.acceleration = velocity_planner_.getAcceleration();
state_.jerk = 0.0;
state_.target_position = position;
state_.is_moving = false;
}
void SCurvePositionPlanner1D::reset()
{
state_ = SCurvePositionPlannerState();
velocity_planner_.reset();
}
void SCurvePositionPlanner1D::setTarget(double target_position)
{
state_.target_position = target_position;
}
double SCurvePositionPlanner1D::update(double dt)
{
if (dt <= 0.0 || dt > 0.1) {
return state_.position;
}
const double position_error = state_.target_position - state_.position;
if (std::abs(position_error) < POSITION_THRESHOLD &&
std::abs(velocity_planner_.getVelocity()) < VELOCITY_THRESHOLD &&
std::abs(velocity_planner_.getAcceleration()) < ACCELERATION_THRESHOLD) {
velocity_planner_.overwriteState(0.0, 0.0, false);
state_.position = state_.target_position;
state_.velocity = 0.0;
state_.acceleration = 0.0;
state_.jerk = 0.0;
state_.is_moving = false;
return state_.position;
}
velocity_planner_.setTargetVelocity(computeDesiredVelocity(position_error));
const double old_velocity = velocity_planner_.getVelocity();
const double new_velocity = velocity_planner_.update(dt);
state_.velocity = new_velocity;
state_.acceleration = velocity_planner_.getAcceleration();
state_.jerk = velocity_planner_.getJerk();
state_.position += 0.5 * (old_velocity + new_velocity) * dt;
const double updated_error = state_.target_position - state_.position;
if (std::abs(updated_error) < POSITION_THRESHOLD &&
std::abs(state_.velocity) < VELOCITY_THRESHOLD &&
std::abs(state_.acceleration) < ACCELERATION_THRESHOLD) {
velocity_planner_.overwriteState(0.0, 0.0, false);
state_.position = state_.target_position;
state_.velocity = 0.0;
state_.acceleration = 0.0;
state_.jerk = 0.0;
state_.is_moving = false;
return state_.position;
}
state_.is_moving = velocity_planner_.isMoving() ||
std::abs(updated_error) > POSITION_THRESHOLD;
return state_.position;
}
double SCurvePositionPlanner1D::computeDesiredVelocity(double position_error) const
{
if (std::abs(position_error) <= POSITION_THRESHOLD) {
return 0.0;
}
const double proportional_velocity =
clamp(position_gain_ * position_error, -max_velocity_, max_velocity_);
return proportional_velocity;
const double current_velocity = velocity_planner_.getVelocity();
const double current_acceleration = velocity_planner_.getAcceleration();
const double stopping_distance =
computePlannerStoppingDistance(current_velocity, current_acceleration);
if (std::abs(current_velocity) > VELOCITY_THRESHOLD &&
sign(current_velocity) != sign(position_error)) {
return 0.0;
}
if (std::abs(current_velocity) > VELOCITY_THRESHOLD &&
sign(current_velocity) == sign(position_error) &&
std::abs(position_error) <= std::abs(stopping_distance) * 1.05) {
return 0.0;
}
double low = 0.0;
double high = max_velocity_;
for (int i = 0; i < 40; ++i) {
const double mid = 0.5 * (low + high);
const double distance =
std::abs(computePlannerStoppingDistance(sign(position_error) * mid, 0.0));
if (distance <= std::abs(position_error)) {
low = mid;
} else {
high = mid;
}
}
return sign(position_error) *
std::min(std::abs(proportional_velocity), low);
}
double SCurvePositionPlanner1D::computePlannerStoppingDistance(double velocity,
double acceleration) const
{
if (std::abs(velocity) <= VELOCITY_THRESHOLD &&
std::abs(acceleration) <= ACCELERATION_THRESHOLD) {
return 0.0;
}
const auto profile = velocity_planner_.calculateProfile(velocity, 0.0, acceleration);
if (!profile.valid || profile.total_time <= EPSILON) {
return 0.0;
}
const int steps = std::max(16, static_cast<int>(std::ceil(profile.total_time / 0.002)));
const double dt = profile.total_time / static_cast<double>(steps);
double distance = 0.0;
double previous_time = 0.0;
double previous_velocity = velocity_planner_.getVelocityAtTime(profile, 0.0);
for (int i = 1; i <= steps; ++i) {
const double t = (i == steps) ? profile.total_time : i * dt;
const double current_velocity = velocity_planner_.getVelocityAtTime(profile, t);
distance += 0.5 * (previous_velocity + current_velocity) * (t - previous_time);
previous_time = t;
previous_velocity = current_velocity;
}
return distance;
}
} // namespace cmvr

View File

@ -0,0 +1,549 @@
//
// Created by lgv on 2026/3/9.
//
#include "../include/s_curve_velocity_planner.h"
#include <cmath>
#include <limits>
namespace cmvr
{
SCurveVelocityPlanner1D::SCurveVelocityPlanner1D(double max_velocity,
double max_acceleration,
double max_jerk)
: max_velocity_(std::abs(max_velocity))
, max_acceleration_(std::abs(max_acceleration))
, max_jerk_(std::abs(max_jerk))
, target_replan_threshold_(DEFAULT_TARGET_REPLAN_THRESHOLD)
, synchronize_replan_threshold_(DEFAULT_SYNCHRONIZE_REPLAN_THRESHOLD)
{
reset();
}
void SCurveVelocityPlanner1D::setConstraints(double max_velocity,
double max_acceleration,
double max_jerk)
{
max_velocity_ = std::abs(max_velocity);
max_acceleration_ = std::abs(max_acceleration);
max_jerk_ = std::abs(max_jerk);
state_.velocity = clamp(state_.velocity, -max_velocity_, max_velocity_);
state_.acceleration = clamp(state_.acceleration, -max_acceleration_, max_acceleration_);
state_.target_velocity = clamp(state_.target_velocity, -max_velocity_, max_velocity_);
if (state_.has_active_profile) {
active_profile_ = calculateProfile(state_.velocity,
state_.target_velocity,
state_.acceleration);
state_.elapsed_time = 0.0;
state_.has_active_profile = active_profile_.valid && active_profile_.total_time > EPSILON;
}
updateIsMovingFlag();
}
void SCurveVelocityPlanner1D::getConstraints(double& max_velocity,
double& max_acceleration,
double& max_jerk) const
{
max_velocity = max_velocity_;
max_acceleration = max_acceleration_;
max_jerk = max_jerk_;
}
void SCurveVelocityPlanner1D::setTargetReplanThreshold(double threshold)
{
target_replan_threshold_ = std::max(0.0, threshold);
}
void SCurveVelocityPlanner1D::setSynchronizeReplanThreshold(double threshold)
{
synchronize_replan_threshold_ = std::max(0.0, threshold);
}
void SCurveVelocityPlanner1D::initialize(double velocity, double acceleration)
{
state_ = SCurveVelocityPlannerState();
state_.velocity = clamp(velocity, -max_velocity_, max_velocity_);
state_.acceleration = clamp(acceleration, -max_acceleration_, max_acceleration_);
state_.jerk = 0.0;
state_.target_velocity = state_.velocity;
state_.elapsed_time = 0.0;
state_.has_active_profile = false;
active_profile_ = SCurveVelocityProfile();
active_profile_.v0 = state_.velocity;
active_profile_.a0 = state_.acceleration;
active_profile_.vf = state_.velocity;
active_profile_.valid = false;
updateIsMovingFlag();
}
void SCurveVelocityPlanner1D::reset()
{
state_ = SCurveVelocityPlannerState();
active_profile_ = SCurveVelocityProfile();
}
void SCurveVelocityPlanner1D::overwriteState(double velocity,
double acceleration,
bool keep_target_velocity)
{
state_.velocity = clamp(velocity, -max_velocity_, max_velocity_);
state_.acceleration = clamp(acceleration, -max_acceleration_, max_acceleration_);
state_.jerk = 0.0;
state_.elapsed_time = 0.0;
state_.has_active_profile = false;
if (!keep_target_velocity) {
state_.target_velocity = state_.velocity;
} else {
state_.target_velocity = clamp(state_.target_velocity, -max_velocity_, max_velocity_);
}
active_profile_ = SCurveVelocityProfile();
active_profile_.v0 = state_.velocity;
active_profile_.a0 = state_.acceleration;
active_profile_.vf = state_.target_velocity;
active_profile_.valid = false;
updateIsMovingFlag();
}
void SCurveVelocityPlanner1D::synchronizeAndReplan(double velocity,
double acceleration)
{
const double measured_velocity = clamp(velocity, -max_velocity_, max_velocity_);
const double measured_acceleration =
clamp(acceleration, -max_acceleration_, max_acceleration_);
if (!state_.has_active_profile &&
std::abs(measured_velocity - state_.target_velocity) <= VELOCITY_THRESHOLD) {
state_.velocity = state_.target_velocity;
state_.acceleration = 0.0;
state_.jerk = 0.0;
updateIsMovingFlag();
return;
}
// If the measured state is still close to the active profile sample, keep
// following that profile instead of restarting the plan every cycle.
if (state_.has_active_profile &&
std::abs(measured_velocity - state_.velocity) <= synchronize_replan_threshold_) {
state_.velocity = measured_velocity;
state_.acceleration = measured_acceleration;
state_.jerk = getJerkAtTime(active_profile_, state_.elapsed_time);
updateIsMovingFlag();
return;
}
state_.velocity = measured_velocity;
state_.acceleration = measured_acceleration;
state_.jerk = 0.0;
active_profile_ = calculateProfile(state_.velocity,
state_.target_velocity,
state_.acceleration);
state_.elapsed_time = 0.0;
state_.has_active_profile = active_profile_.total_time > EPSILON;
updateIsMovingFlag();
}
void SCurveVelocityPlanner1D::setTargetVelocity(double target_velocity)
{
const double new_target = clamp(target_velocity, -max_velocity_, max_velocity_);
const bool same_target =
std::abs(new_target - state_.target_velocity) <= target_replan_threshold_;
if (same_target &&
state_.has_active_profile) {
return;
}
if (same_target &&
!state_.has_active_profile &&
std::abs(state_.velocity - new_target) <= VELOCITY_THRESHOLD &&
std::abs(state_.acceleration) <= ACCELERATION_THRESHOLD) {
return;
}
state_.target_velocity = new_target;
active_profile_ = calculateProfile(state_.velocity,
state_.target_velocity,
state_.acceleration);
state_.elapsed_time = 0.0;
state_.has_active_profile = active_profile_.valid && active_profile_.total_time > EPSILON;
updateIsMovingFlag();
}
double SCurveVelocityPlanner1D::getVelocityAtTime(const SCurveVelocityProfile& profile, double t) const
{
if (!profile.valid) {
return profile.v0;
}
if (t <= 0.0) {
return profile.v0;
}
if (t >= profile.total_time) {
return profile.vf;
}
double v = profile.v0;
double a = profile.a0;
auto process_segment = [&](double dt, double jerk) {
v += a * dt + 0.5 * jerk * dt * dt;
a += jerk * dt;
};
if (t <= profile.t1) {
process_segment(t, profile.j1);
return v;
}
process_segment(profile.t1, profile.j1);
const double t_after_1 = t - profile.t1;
if (t_after_1 <= profile.t2) {
process_segment(t_after_1, profile.j2);
return v;
}
process_segment(profile.t2, profile.j2);
const double t_after_2 = t_after_1 - profile.t2;
process_segment(t_after_2, profile.j3);
return v;
}
double SCurveVelocityPlanner1D::getAccelerationAtTime(const SCurveVelocityProfile& profile, double t) const
{
if (!profile.valid) {
return profile.a0;
}
if (t <= 0.0) {
return profile.a0;
}
if (t >= profile.total_time) {
return 0.0;
}
double a = profile.a0;
auto process_segment = [&](double dt, double jerk) {
a += jerk * dt;
};
if (t <= profile.t1) {
process_segment(t, profile.j1);
return a;
}
process_segment(profile.t1, profile.j1);
const double t_after_1 = t - profile.t1;
if (t_after_1 <= profile.t2) {
process_segment(t_after_1, profile.j2);
return a;
}
process_segment(profile.t2, profile.j2);
const double t_after_2 = t_after_1 - profile.t2;
process_segment(t_after_2, profile.j3);
return a;
}
double SCurveVelocityPlanner1D::getJerkAtTime(const SCurveVelocityProfile& profile, double t) const
{
if (!profile.valid) {
return 0.0;
}
if (t <= 0.0 || t >= profile.total_time) {
return 0.0;
}
if (t <= profile.t1) {
return profile.j1;
}
if (t <= profile.t1 + profile.t2) {
return profile.j2;
}
return profile.j3;
}
void SCurveVelocityPlanner1D::integrateWholeProfile(const SCurveVelocityProfile& profile,
double& v_end,
double& a_end) const
{
double v = profile.v0;
double a = profile.a0;
auto process_segment = [&](double dt, double jerk) {
v += a * dt + 0.5 * jerk * dt * dt;
a += jerk * dt;
};
process_segment(profile.t1, profile.j1);
process_segment(profile.t2, profile.j2);
process_segment(profile.t3, profile.j3);
v_end = v;
a_end = a;
}
bool SCurveVelocityPlanner1D::isVelocityLimitSatisfied(const SCurveVelocityProfile& profile) const
{
if (!profile.valid) {
return true;
}
std::vector<double> check_times;
check_times.reserve(8);
check_times.push_back(0.0);
check_times.push_back(profile.t1);
check_times.push_back(profile.t1 + profile.t2);
check_times.push_back(profile.total_time);
// If acceleration crosses zero inside segment 1, velocity may reach an
// extremum within the segment and needs to be checked explicitly.
if (std::abs(profile.j1) > EPSILON && profile.t1 > EPSILON) {
const double tz = -profile.a0 / profile.j1;
if (tz > EPSILON && tz < profile.t1 - EPSILON) {
check_times.push_back(tz);
}
}
for (double t : check_times) {
const double v = getVelocityAtTime(profile, t);
if (std::abs(v) > max_velocity_ + 1e-7) {
return false;
}
}
return true;
}
SCurveVelocityProfile SCurveVelocityPlanner1D::calculateProfile(double start_velocity,
double end_velocity,
double start_acceleration) const
{
SCurveVelocityProfile best;
best.v0 = clamp(start_velocity, -max_velocity_, max_velocity_);
best.a0 = clamp(start_acceleration, -max_acceleration_, max_acceleration_);
best.vf = clamp(end_velocity, -max_velocity_, max_velocity_);
if (max_jerk_ <= EPSILON || max_acceleration_ <= EPSILON) {
return best;
}
const double v0 = best.v0;
const double a0 = best.a0;
const double vf = best.vf;
// Work in a signed frame where the requested delta velocity is non-negative.
double s = sign(vf - v0);
if (std::abs(vf - v0) <= VELOCITY_THRESHOLD) {
s = 1.0;
}
const double dv = s * (vf - v0);
const double a0s = s * a0;
const double j = max_jerk_;
const double amax = max_acceleration_;
auto normalize_nonnegative = [](double x) {
return (x < 0.0 && x > -1e-10) ? 0.0 : x;
};
auto try_candidate = [&](double t1, double t2, double t3,
double j1s, double j2s, double j3s) {
t1 = normalize_nonnegative(t1);
t2 = normalize_nonnegative(t2);
t3 = normalize_nonnegative(t3);
if (t1 < 0.0 || t2 < 0.0 || t3 < 0.0) {
return;
}
SCurveVelocityProfile cand;
cand.t1 = t1;
cand.t2 = t2;
cand.t3 = t3;
cand.total_time = t1 + t2 + t3;
cand.j1 = s * j1s;
cand.j2 = s * j2s;
cand.j3 = s * j3s;
cand.v0 = v0;
cand.a0 = a0;
cand.vf = vf;
cand.valid = true;
double vend = 0.0;
double aend = 0.0;
integrateWholeProfile(cand, vend, aend);
if (std::abs(vend - vf) > 1e-5) {
return;
}
if (std::abs(aend) > 1e-5) {
return;
}
if (!isVelocityLimitSatisfied(cand)) {
return;
}
if (!best.valid || cand.total_time < best.total_time) {
best = cand;
}
};
{
const double A2 = 0.5 * (2.0 * j * dv + a0s * a0s);
if (A2 >= -1e-10) {
const double A = std::sqrt(std::max(0.0, A2));
if (A <= amax + 1e-10 && A >= a0s - 1e-10) {
const double t1 = (A - a0s) / j;
const double t2 = 0.0;
const double t3 = A / j;
try_candidate(t1, t2, t3, +j, 0.0, -j);
}
}
}
{
const double A = amax;
if (A > EPSILON && A >= a0s - 1e-10) {
const double base = (2.0 * A * A - a0s * a0s) / (2.0 * j);
const double t1 = (A - a0s) / j;
const double t2 = (dv - base) / A;
const double t3 = A / j;
try_candidate(t1, t2, t3, +j, 0.0, -j);
}
}
{
const double B2 = 0.5 * (a0s * a0s - 2.0 * j * dv);
if (B2 >= -1e-10) {
const double B = std::sqrt(std::max(0.0, B2));
if (B <= amax + 1e-10 && B >= -a0s - 1e-10) {
const double t1 = (a0s + B) / j;
const double t2 = 0.0;
const double t3 = B / j;
try_candidate(t1, t2, t3, -j, 0.0, +j);
}
}
}
{
const double B = amax;
if (B > EPSILON && B >= -a0s - 1e-10) {
const double base = (a0s * a0s - 2.0 * B * B) / (2.0 * j);
const double t1 = (a0s + B) / j;
const double t2 = (base - dv) / B;
const double t3 = B / j;
try_candidate(t1, t2, t3, -j, 0.0, +j);
}
}
if (!best.valid &&
std::abs(vf - v0) <= VELOCITY_THRESHOLD &&
std::abs(a0) <= ACCELERATION_THRESHOLD) {
best.valid = false;
best.total_time = 0.0;
best.v0 = v0;
best.a0 = a0;
best.vf = vf;
}
return best;
}
void SCurveVelocityPlanner1D::generateTrajectory(const SCurveVelocityProfile& profile, double dt,
std::vector<double>& velocities,
std::vector<double>& accelerations,
std::vector<double>& jerks) const
{
velocities.clear();
accelerations.clear();
jerks.clear();
if (!profile.valid || profile.total_time <= 0.0 || dt <= 0.0) {
velocities.push_back(profile.v0);
accelerations.push_back(profile.a0);
jerks.push_back(0.0);
return;
}
const int num_points = static_cast<int>(std::ceil(profile.total_time / dt)) + 1;
velocities.reserve(num_points);
accelerations.reserve(num_points);
jerks.reserve(num_points);
for (double t = 0.0; t <= profile.total_time; t += dt) {
velocities.push_back(getVelocityAtTime(profile, t));
accelerations.push_back(getAccelerationAtTime(profile, t));
jerks.push_back(getJerkAtTime(profile, t));
}
if (velocities.empty() || std::abs(velocities.back() - profile.vf) > VELOCITY_THRESHOLD) {
velocities.push_back(profile.vf);
accelerations.push_back(0.0);
jerks.push_back(0.0);
}
}
double SCurveVelocityPlanner1D::update(double dt)
{
if (dt <= 0.0) {
return state_.velocity;
}
if (!state_.has_active_profile || !active_profile_.valid) {
state_.jerk = 0.0;
updateIsMovingFlag();
return state_.velocity;
}
state_.elapsed_time += dt;
if (state_.elapsed_time >= active_profile_.total_time) {
state_.elapsed_time = active_profile_.total_time;
state_.velocity = active_profile_.vf;
state_.acceleration = 0.0;
state_.jerk = 0.0;
state_.has_active_profile = false;
updateIsMovingFlag();
return state_.velocity;
}
state_.velocity = getVelocityAtTime(active_profile_, state_.elapsed_time);
state_.acceleration = getAccelerationAtTime(active_profile_, state_.elapsed_time);
state_.jerk = getJerkAtTime(active_profile_, state_.elapsed_time);
updateIsMovingFlag();
return state_.velocity;
}
void SCurveVelocityPlanner1D::updateIsMovingFlag()
{
state_.is_moving =
state_.has_active_profile ||
std::abs(state_.velocity) > VELOCITY_THRESHOLD ||
std::abs(state_.target_velocity) > VELOCITY_THRESHOLD ||
std::abs(state_.acceleration) > ACCELERATION_THRESHOLD;
}
} // namespace cmvr

11
file_service.erpc Normal file
View File

@ -0,0 +1,11 @@
// file_service.erpc
program file_service
@id(2)
interface file_service
{
fileWriteBegin(string path, uint32 total_size) -> int32
fileWriteChunk(binary data) -> int32
fileWriteEnd() -> int32
fileWriteAbort() -> int32
}

19
file_service/__init__.py Normal file
View File

@ -0,0 +1,19 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:45 2026.
#
# AUTOGENERATED - DO NOT EDIT
#
try:
from erpc import erpc_version
version = erpc_version.ERPC_VERSION
except ImportError:
version = "unknown"
if version != "1.14.0":
raise ValueError("The generated shim code version (1.14.0) is different to the rest of eRPC code (%s). \
Install newer version by running \"python setup.py install\" in folder erpc/erpc_python/." % repr(version))
from . import common
from . import client
from . import server
from . import interface

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

85
file_service/client.py Normal file
View File

@ -0,0 +1,85 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:45 2026.
#
# AUTOGENERATED - DO NOT EDIT
#
import erpc
from . import common, interface
# Client for file_service
class file_serviceClient(interface.Ifile_service):
def __init__(self, manager):
super(file_serviceClient, self).__init__()
self._clientManager = manager
def fileWriteBegin(self, path, total_size):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.FILEWRITEBEGIN_ID,
sequence=request.sequence))
if path is None:
raise ValueError("path is None")
codec.write_string(path)
if total_size is None:
raise ValueError("total_size is None")
codec.write_uint32(total_size)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_int32()
return _result
def fileWriteChunk(self, data):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.FILEWRITECHUNK_ID,
sequence=request.sequence))
if data is None:
raise ValueError("data is None")
codec.write_binary(data)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_int32()
return _result
def fileWriteEnd(self):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.FILEWRITEEND_ID,
sequence=request.sequence))
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_int32()
return _result
def fileWriteAbort(self):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.FILEWRITEABORT_ID,
sequence=request.sequence))
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_int32()
return _result

7
file_service/common.py Normal file
View File

@ -0,0 +1,7 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:45 2026.
#
# AUTOGENERATED - DO NOT EDIT
#

27
file_service/interface.py Normal file
View File

@ -0,0 +1,27 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:45 2026.
#
# AUTOGENERATED - DO NOT EDIT
#
# Abstract base class for file_service
class Ifile_service(object):
SERVICE_ID = 2
FILEWRITEBEGIN_ID = 1
FILEWRITECHUNK_ID = 2
FILEWRITEEND_ID = 3
FILEWRITEABORT_ID = 4
def fileWriteBegin(self, path, total_size):
raise NotImplementedError()
def fileWriteChunk(self, data):
raise NotImplementedError()
def fileWriteEnd(self):
raise NotImplementedError()
def fileWriteAbort(self):
raise NotImplementedError()

93
file_service/server.py Normal file
View File

@ -0,0 +1,93 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:45 2026.
#
# AUTOGENERATED - DO NOT EDIT
#
import erpc
from . import common, interface
# Client for file_service
class file_serviceService(erpc.server.Service):
def __init__(self, handler):
super(file_serviceService, self).__init__(interface.Ifile_service.SERVICE_ID)
self._handler = handler
self._methods = {
interface.Ifile_service.FILEWRITEBEGIN_ID: self._handle_fileWriteBegin,
interface.Ifile_service.FILEWRITECHUNK_ID: self._handle_fileWriteChunk,
interface.Ifile_service.FILEWRITEEND_ID: self._handle_fileWriteEnd,
interface.Ifile_service.FILEWRITEABORT_ID: self._handle_fileWriteAbort,
}
def _handle_fileWriteBegin(self, sequence, codec):
# Read incoming parameters.
path = codec.read_string()
total_size = codec.read_uint32()
# Invoke user implementation of remote function.
_result = self._handler.fileWriteBegin(path, total_size)
# Prepare codec for reply message.
codec.reset()
# Construct reply message.
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kReplyMessage,
service=interface.Ifile_service.SERVICE_ID,
request=interface.Ifile_service.FILEWRITEBEGIN_ID,
sequence=sequence))
codec.write_int32(_result)
def _handle_fileWriteChunk(self, sequence, codec):
# Read incoming parameters.
data = codec.read_binary()
# Invoke user implementation of remote function.
_result = self._handler.fileWriteChunk(data)
# Prepare codec for reply message.
codec.reset()
# Construct reply message.
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kReplyMessage,
service=interface.Ifile_service.SERVICE_ID,
request=interface.Ifile_service.FILEWRITECHUNK_ID,
sequence=sequence))
codec.write_int32(_result)
def _handle_fileWriteEnd(self, sequence, codec):
# Read incoming parameters.
# Invoke user implementation of remote function.
_result = self._handler.fileWriteEnd()
# Prepare codec for reply message.
codec.reset()
# Construct reply message.
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kReplyMessage,
service=interface.Ifile_service.SERVICE_ID,
request=interface.Ifile_service.FILEWRITEEND_ID,
sequence=sequence))
codec.write_int32(_result)
def _handle_fileWriteAbort(self, sequence, codec):
# Read incoming parameters.
# Invoke user implementation of remote function.
_result = self._handler.fileWriteAbort()
# Prepare codec for reply message.
codec.reset()
# Construct reply message.
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kReplyMessage,
service=interface.Ifile_service.SERVICE_ID,
request=interface.Ifile_service.FILEWRITEABORT_ID,
sequence=sequence))
codec.write_int32(_result)

View File

@ -0,0 +1,77 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "c_file_service_client.h"
#include "file_service_client.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
file_service_client *s_file_service_client = nullptr;
#else
ERPC_MANUALLY_CONSTRUCTED_STATIC(file_service_client, s_file_service_client);
#endif
int32_t fileWriteBegin(const char * path, uint32_t total_size)
{
int32_t result;
result = s_file_service_client->fileWriteBegin(path, total_size);
return result;
}
int32_t fileWriteChunk(const binary_t * data)
{
int32_t result;
result = s_file_service_client->fileWriteChunk(data);
return result;
}
int32_t fileWriteEnd(void)
{
int32_t result;
result = s_file_service_client->fileWriteEnd();
return result;
}
int32_t fileWriteAbort(void)
{
int32_t result;
result = s_file_service_client->fileWriteAbort();
return result;
}
void initfile_service_client(erpc_client_t client)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
erpc_assert(s_file_service_client == nullptr);
s_file_service_client = new file_service_client(reinterpret_cast<ClientManager *>(client));
#else
erpc_assert(!s_file_service_client.isUsed());
s_file_service_client.construct(reinterpret_cast<ClientManager *>(client));
#endif
}
void deinitfile_service_client(void)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (s_file_service_client != nullptr)
{
delete s_file_service_client;
s_file_service_client = nullptr;
}
#else
s_file_service_client.destroy();
#endif
}

View File

@ -0,0 +1,54 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_file_service_client_h_)
#define _c_file_service_client_h_
#include "file_service_common.h"
#include "erpc_client_manager.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief file_service identifiers */
enum _file_service_ids
{
kfile_service_service_id = 2,
kfile_service_fileWriteBegin_id = 1,
kfile_service_fileWriteChunk_id = 2,
kfile_service_fileWriteEnd_id = 3,
kfile_service_fileWriteAbort_id = 4,
};
//! @name file_service
//@{
int32_t fileWriteBegin(const char * path, uint32_t total_size);
int32_t fileWriteChunk(const binary_t * data);
int32_t fileWriteEnd(void);
int32_t fileWriteAbort(void);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
void initfile_service_client(erpc_client_t client);
void deinitfile_service_client(void);
#if defined(__cplusplus)
}
#endif
#endif // _c_file_service_client_h_

View File

@ -0,0 +1,97 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include <new>
#include "c_file_service_server.h"
#include "file_service_server.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
class file_service_server: public file_service_interface
{
public:
virtual ~file_service_server() {};
int32_t fileWriteBegin(const char * path, uint32_t total_size)
{
int32_t result;
result = ::fileWriteBegin(path, total_size);
return result;
}
int32_t fileWriteChunk(const binary_t * data)
{
int32_t result;
result = ::fileWriteChunk(data);
return result;
}
int32_t fileWriteEnd(void)
{
int32_t result;
result = ::fileWriteEnd();
return result;
}
int32_t fileWriteAbort(void)
{
int32_t result;
result = ::fileWriteAbort();
return result;
}
};
ERPC_MANUALLY_CONSTRUCTED_STATIC(file_service_service, s_file_service_service);
ERPC_MANUALLY_CONSTRUCTED_STATIC(file_service_server, s_file_service_server);
erpc_service_t create_file_service_service(void)
{
erpc_service_t service;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
service = new (nothrow) file_service_service(new (nothrow)file_service_server());
#else
if (s_file_service_service.isUsed())
{
service = NULL;
}
else
{
s_file_service_server.construct();
s_file_service_service.construct(s_file_service_server.get());
service = s_file_service_service.get();
}
#endif
return service;
}
void destroy_file_service_service(erpc_service_t service)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (service)
{
delete (file_service_server *)(((file_service_service *)service)->getHandler());
delete (file_service_service *)service;
}
#else
(void)service;
erpc_assert(service == s_file_service_service.get());
s_file_service_service.destroy();
s_file_service_server.destroy();
#endif
}

View File

@ -0,0 +1,59 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_file_service_server_h_)
#define _c_file_service_server_h_
#include "file_service_common.h"
#if defined(__cplusplus)
extern "C"
{
#endif
typedef void * erpc_service_t;
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief file_service identifiers */
enum _file_service_ids
{
kfile_service_service_id = 2,
kfile_service_fileWriteBegin_id = 1,
kfile_service_fileWriteChunk_id = 2,
kfile_service_fileWriteEnd_id = 3,
kfile_service_fileWriteAbort_id = 4,
};
//! @name file_service
//@{
int32_t fileWriteBegin(const char * path, uint32_t total_size);
int32_t fileWriteChunk(const binary_t * data);
int32_t fileWriteEnd(void);
int32_t fileWriteAbort(void);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
/*! @brief Return file_service_service service object. */
erpc_service_t create_file_service_service(void);
/*! @brief Destroy file_service_service service object. */
void destroy_file_service_service(erpc_service_t service);
#if defined(__cplusplus)
}
#endif
#endif // _c_file_service_server_h_

View File

@ -0,0 +1,93 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "c_servo_service_client.h"
#include "servo_service_client.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
servo_service_client *s_servo_service_client = nullptr;
#else
ERPC_MANUALLY_CONSTRUCTED_STATIC(servo_service_client, s_servo_service_client);
#endif
bool setConstraints(const char * id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad)
{
bool result;
result = s_servo_service_client->setConstraints(id, max_velocity_rad, max_acceleration_rad, max_jerk_rad);
return result;
}
bool setPositionGain(const char * id, float position_gain)
{
bool result;
result = s_servo_service_client->setPositionGain(id, position_gain);
return result;
}
bool setMode(RpcMotionMode mode)
{
bool result;
result = s_servo_service_client->setMode(mode);
return result;
}
bool setUpdatePeriodMs(uint32_t ms)
{
bool result;
result = s_servo_service_client->setUpdatePeriodMs(ms);
return result;
}
int32_t move(const list_ServoCmd_1_t * cmds)
{
int32_t result;
result = s_servo_service_client->move(cmds);
return result;
}
int32_t moveJ(const list_float_1_t * angles_rad)
{
int32_t result;
result = s_servo_service_client->moveJ(angles_rad);
return result;
}
void initservo_service_client(erpc_client_t client)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
erpc_assert(s_servo_service_client == nullptr);
s_servo_service_client = new servo_service_client(reinterpret_cast<ClientManager *>(client));
#else
erpc_assert(!s_servo_service_client.isUsed());
s_servo_service_client.construct(reinterpret_cast<ClientManager *>(client));
#endif
}
void deinitservo_service_client(void)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (s_servo_service_client != nullptr)
{
delete s_servo_service_client;
s_servo_service_client = nullptr;
}
#else
s_servo_service_client.destroy();
#endif
}

View File

@ -0,0 +1,60 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_servo_service_client_h_)
#define _c_servo_service_client_h_
#include "servo_service_common.h"
#include "erpc_client_manager.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief servo_service identifiers */
enum _servo_service_ids
{
kservo_service_service_id = 1,
kservo_service_setConstraints_id = 1,
kservo_service_setPositionGain_id = 2,
kservo_service_setMode_id = 3,
kservo_service_setUpdatePeriodMs_id = 4,
kservo_service_move_id = 5,
kservo_service_moveJ_id = 6,
};
//! @name servo_service
//@{
bool setConstraints(const char * id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad);
bool setPositionGain(const char * id, float position_gain);
bool setMode(RpcMotionMode mode);
bool setUpdatePeriodMs(uint32_t ms);
int32_t move(const list_ServoCmd_1_t * cmds);
int32_t moveJ(const list_float_1_t * angles_rad);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
void initservo_service_client(erpc_client_t client);
void deinitservo_service_client(void);
#if defined(__cplusplus)
}
#endif
#endif // _c_servo_service_client_h_

View File

@ -0,0 +1,113 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include <new>
#include "c_servo_service_server.h"
#include "servo_service_server.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
class servo_service_server: public servo_service_interface
{
public:
virtual ~servo_service_server() {};
bool setConstraints(const char * id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad)
{
bool result;
result = ::setConstraints(id, max_velocity_rad, max_acceleration_rad, max_jerk_rad);
return result;
}
bool setPositionGain(const char * id, float position_gain)
{
bool result;
result = ::setPositionGain(id, position_gain);
return result;
}
bool setMode(RpcMotionMode mode)
{
bool result;
result = ::setMode(mode);
return result;
}
bool setUpdatePeriodMs(uint32_t ms)
{
bool result;
result = ::setUpdatePeriodMs(ms);
return result;
}
int32_t move(const list_ServoCmd_1_t * cmds)
{
int32_t result;
result = ::move(cmds);
return result;
}
int32_t moveJ(const list_float_1_t * angles_rad)
{
int32_t result;
result = ::moveJ(angles_rad);
return result;
}
};
ERPC_MANUALLY_CONSTRUCTED_STATIC(servo_service_service, s_servo_service_service);
ERPC_MANUALLY_CONSTRUCTED_STATIC(servo_service_server, s_servo_service_server);
erpc_service_t create_servo_service_service(void)
{
erpc_service_t service;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
service = new (nothrow) servo_service_service(new (nothrow)servo_service_server());
#else
if (s_servo_service_service.isUsed())
{
service = NULL;
}
else
{
s_servo_service_server.construct();
s_servo_service_service.construct(s_servo_service_server.get());
service = s_servo_service_service.get();
}
#endif
return service;
}
void destroy_servo_service_service(erpc_service_t service)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (service)
{
delete (servo_service_server *)(((servo_service_service *)service)->getHandler());
delete (servo_service_service *)service;
}
#else
(void)service;
erpc_assert(service == s_servo_service_service.get());
s_servo_service_service.destroy();
s_servo_service_server.destroy();
#endif
}

View File

@ -0,0 +1,65 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_servo_service_server_h_)
#define _c_servo_service_server_h_
#include "servo_service_common.h"
#if defined(__cplusplus)
extern "C"
{
#endif
typedef void * erpc_service_t;
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief servo_service identifiers */
enum _servo_service_ids
{
kservo_service_service_id = 1,
kservo_service_setConstraints_id = 1,
kservo_service_setPositionGain_id = 2,
kservo_service_setMode_id = 3,
kservo_service_setUpdatePeriodMs_id = 4,
kservo_service_move_id = 5,
kservo_service_moveJ_id = 6,
};
//! @name servo_service
//@{
bool setConstraints(const char * id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad);
bool setPositionGain(const char * id, float position_gain);
bool setMode(RpcMotionMode mode);
bool setUpdatePeriodMs(uint32_t ms);
int32_t move(const list_ServoCmd_1_t * cmds);
int32_t moveJ(const list_float_1_t * angles_rad);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
/*! @brief Return servo_service_service service object. */
erpc_service_t create_servo_service_service(void);
/*! @brief Destroy servo_service_service service object. */
void destroy_servo_service_service(erpc_service_t service);
#if defined(__cplusplus)
}
#endif
#endif // _c_servo_service_server_h_

View File

@ -0,0 +1,302 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include "erpc_port.h"
#endif
#include "erpc_codec.hpp"
#include "file_service_client.hpp"
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
//! @brief Function to write struct binary_t
static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data);
// Write struct binary_t function implementation
static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data)
{
if(NULL == data)
{
return;
}
codec->writeBinary(data->dataLength, data->data);
}
file_service_client::file_service_client(ClientManager *manager)
:m_clientManager(manager)
{
}
file_service_client::~file_service_client()
{
}
// file_service interface fileWriteBegin function client shim.
int32_t file_service_client::fileWriteBegin(const char * path, uint32_t total_size)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_fileWriteBeginId, request.getSequence());
{
uint32_t path_len = strlen((const char*)path);
codec->writeString(path_len, (const char*)path);
}
codec->write(total_size);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_fileWriteBeginId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}
// file_service interface fileWriteChunk function client shim.
int32_t file_service_client::fileWriteChunk(const binary_t * data)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_fileWriteChunkId, request.getSequence());
write_binary_t_struct(codec, data);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_fileWriteChunkId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}
// file_service interface fileWriteEnd function client shim.
int32_t file_service_client::fileWriteEnd(void)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_fileWriteEndId, request.getSequence());
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_fileWriteEndId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}
// file_service interface fileWriteAbort function client shim.
int32_t file_service_client::fileWriteAbort(void)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_fileWriteAbortId, request.getSequence());
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_fileWriteAbortId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}

View File

@ -0,0 +1,40 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_client_hpp_)
#define _file_service_client_hpp_
#include "file_service_interface.hpp"
#include "erpc_client_manager.h"
namespace erpcShim
{
class file_service_client: public file_service_interface
{
public:
file_service_client(erpc::ClientManager *manager);
virtual ~file_service_client();
virtual int32_t fileWriteBegin(const char * path, uint32_t total_size);
virtual int32_t fileWriteChunk(const binary_t * data);
virtual int32_t fileWriteEnd(void);
virtual int32_t fileWriteAbort(void);
protected:
erpc::ClientManager *m_clientManager;
};
} // erpcShim
#endif // _file_service_client_hpp_

View File

@ -0,0 +1,47 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_common_h_)
#define _file_service_common_h_
#if defined(__cplusplus)
extern "C"
{
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_FILE_SERVICE)
#define ERPC_TYPE_DEFINITIONS_FILE_SERVICE
// Aliases data types declarations
typedef struct binary_t binary_t;
// Structures/unions data types declarations
struct binary_t
{
uint8_t * data;
uint32_t dataLength;
};
#endif // ERPC_TYPE_DEFINITIONS_FILE_SERVICE
#if defined(__cplusplus)
}
#endif
#endif // _file_service_common_h_

View File

@ -0,0 +1,39 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_common_hpp_)
#define _file_service_common_hpp_
#include <cstddef>
#include <cstdint>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_FILE_SERVICE)
#define ERPC_TYPE_DEFINITIONS_FILE_SERVICE
// Aliases data types declarations
typedef struct binary_t binary_t;
// Structures/unions data types declarations
struct binary_t
{
uint8_t * data;
uint32_t dataLength;
};
#endif // ERPC_TYPE_DEFINITIONS_FILE_SERVICE
#endif // _file_service_common_hpp_

View File

@ -0,0 +1,20 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "file_service_interface.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace std;
using namespace erpcShim;
file_service_interface::~file_service_interface(void)
{
}

View File

@ -0,0 +1,41 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_interface_hpp_)
#define _file_service_interface_hpp_
#include "file_service_common.hpp"
namespace erpcShim
{
// Abstract base class for file_service
class file_service_interface
{
public:
static const uint8_t m_serviceId = 2;
static const uint8_t m_fileWriteBeginId = 1;
static const uint8_t m_fileWriteChunkId = 2;
static const uint8_t m_fileWriteEndId = 3;
static const uint8_t m_fileWriteAbortId = 4;
virtual ~file_service_interface(void);
virtual int32_t fileWriteBegin(const char * path, uint32_t total_size) = 0;
virtual int32_t fileWriteChunk(const binary_t * data) = 0;
virtual int32_t fileWriteEnd(void) = 0;
virtual int32_t fileWriteAbort(void) = 0;
private:
};
} // erpcShim
#endif // _file_service_interface_hpp_

View File

@ -0,0 +1,327 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "file_service_server.hpp"
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include <new>
#include "erpc_port.h"
#endif
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_NESTED_CALLS_DETECTION
extern bool nestingDetection;
#endif
//! @brief Function to read struct binary_t
static void read_binary_t_struct(erpc::Codec * codec, binary_t * data);
// Read struct binary_t function implementation
static void read_binary_t_struct(erpc::Codec * codec, binary_t * data)
{
if(NULL == data)
{
return;
}
uint8_t * data_local;
codec->readBinary(data->dataLength, &data_local);
if (data->dataLength > 0)
{
data->data = (uint8_t *) erpc_malloc(data->dataLength * sizeof(uint8_t));
if (data->data == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(data->data, data_local, data->dataLength);
}
}
else
{
data->data = NULL;
}
}
//! @brief Function to free space allocated inside struct binary_t
static void free_binary_t_struct(binary_t * data);
// Free space allocated inside struct binary_t function implementation
static void free_binary_t_struct(binary_t * data)
{
erpc_free(data->data);
}
file_service_service::file_service_service(file_service_interface *_file_service_interface)
: erpc::Service(file_service_interface::m_serviceId)
, m_handler(_file_service_interface)
{
}
file_service_service::~file_service_service()
{
}
// return service interface handler.
file_service_interface* file_service_service::getHandler(void)
{
return m_handler;
}
// Call the correct server shim based on method unique ID.
erpc_status_t file_service_service::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory, Transport * transport)
{
erpc_status_t erpcStatus;
switch (methodId)
{
case file_service_interface::m_fileWriteBeginId:
{
erpcStatus = fileWriteBegin_shim(codec, messageFactory, transport, sequence);
break;
}
case file_service_interface::m_fileWriteChunkId:
{
erpcStatus = fileWriteChunk_shim(codec, messageFactory, transport, sequence);
break;
}
case file_service_interface::m_fileWriteEndId:
{
erpcStatus = fileWriteEnd_shim(codec, messageFactory, transport, sequence);
break;
}
case file_service_interface::m_fileWriteAbortId:
{
erpcStatus = fileWriteAbort_shim(codec, messageFactory, transport, sequence);
break;
}
default:
{
erpcStatus = kErpcStatus_InvalidArgument;
break;
}
}
return erpcStatus;
}
// Server shim for fileWriteBegin of file_service interface.
erpc_status_t file_service_service::fileWriteBegin_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
char * path = NULL;
uint32_t total_size;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
{
uint32_t path_len;
char * path_local;
codec->readString(path_len, &path_local);
path = (char*) erpc_malloc((path_len + 1) * sizeof(char));
if ((path == NULL) || (path_local == NULL))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(path, path_local, path_len);
(path)[path_len] = 0;
}
}
codec->read(total_size);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteBegin(path, total_size);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, file_service_interface::m_serviceId, file_service_interface::m_fileWriteBeginId, sequence);
codec->write(result);
err = codec->getStatus();
}
erpc_free(path);
return err;
}
// Server shim for fileWriteChunk of file_service interface.
erpc_status_t file_service_service::fileWriteChunk_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
binary_t *data = NULL;
data = (binary_t *) erpc_malloc(sizeof(binary_t));
if (data == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
int32_t result;
// startReadMessage() was already called before this shim was invoked.
read_binary_t_struct(codec, data);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteChunk(data);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, file_service_interface::m_serviceId, file_service_interface::m_fileWriteChunkId, sequence);
codec->write(result);
err = codec->getStatus();
}
if (data)
{
free_binary_t_struct(data);
}
erpc_free(data);
return err;
}
// Server shim for fileWriteEnd of file_service interface.
erpc_status_t file_service_service::fileWriteEnd_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteEnd();
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, file_service_interface::m_serviceId, file_service_interface::m_fileWriteEndId, sequence);
codec->write(result);
err = codec->getStatus();
}
return err;
}
// Server shim for fileWriteAbort of file_service interface.
erpc_status_t file_service_service::fileWriteAbort_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteAbort();
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, file_service_interface::m_serviceId, file_service_interface::m_fileWriteAbortId, sequence);
codec->write(result);
err = codec->getStatus();
}
return err;
}

View File

@ -0,0 +1,58 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:37 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_server_hpp_)
#define _file_service_server_hpp_
#include "file_service_interface.hpp"
#include "erpc_server.hpp"
#include "erpc_codec.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
namespace erpcShim
{
/*!
* @brief Service subclass for file_service.
*/
class file_service_service : public erpc::Service
{
public:
file_service_service(file_service_interface *_file_service_interface);
virtual ~file_service_service();
/*! @brief return service interface handler. */
file_service_interface* getHandler(void);
/*! @brief Call the correct server shim based on method unique ID. */
virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport);
private:
file_service_interface *m_handler;
/*! @brief Server shim for fileWriteBegin of file_service interface. */
erpc_status_t fileWriteBegin_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for fileWriteChunk of file_service interface. */
erpc_status_t fileWriteChunk_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for fileWriteEnd of file_service interface. */
erpc_status_t fileWriteEnd_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for fileWriteAbort of file_service interface. */
erpc_status_t fileWriteAbort_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
};
} // erpcShim
#endif // _file_service_server_hpp_

View File

@ -0,0 +1,484 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include "erpc_port.h"
#endif
#include "erpc_codec.hpp"
#include "servo_service_client.hpp"
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
//! @brief Function to write struct ServoCmd
static void write_ServoCmd_struct(erpc::Codec * codec, const ServoCmd * data);
//! @brief Function to write struct list_ServoCmd_1_t
static void write_list_ServoCmd_1_t_struct(erpc::Codec * codec, const list_ServoCmd_1_t * data);
//! @brief Function to write struct list_float_1_t
static void write_list_float_1_t_struct(erpc::Codec * codec, const list_float_1_t * data);
// Write struct ServoCmd function implementation
static void write_ServoCmd_struct(erpc::Codec * codec, const ServoCmd * data)
{
if(NULL == data)
{
return;
}
{
uint32_t id_len = strlen((const char*)data->id);
codec->writeString(id_len, (const char*)data->id);
}
codec->write(data->angle_rad);
}
// Write struct list_ServoCmd_1_t function implementation
static void write_list_ServoCmd_1_t_struct(erpc::Codec * codec, const list_ServoCmd_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startWriteList(data->elementsCount);
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
write_ServoCmd_struct(codec, &(data->elements[listCount]));
}
}
// Write struct list_float_1_t function implementation
static void write_list_float_1_t_struct(erpc::Codec * codec, const list_float_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startWriteList(data->elementsCount);
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
codec->write(data->elements[listCount]);
}
}
servo_service_client::servo_service_client(ClientManager *manager)
:m_clientManager(manager)
{
}
servo_service_client::~servo_service_client()
{
}
// servo_service interface setConstraints function client shim.
bool servo_service_client::setConstraints(const char * id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad)
{
erpc_status_t err = kErpcStatus_Success;
bool result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_setConstraintsId, request.getSequence());
{
uint32_t id_len = strlen((const char*)id);
codec->writeString(id_len, (const char*)id);
}
codec->write(max_velocity_rad);
codec->write(max_acceleration_rad);
codec->write(max_jerk_rad);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_setConstraintsId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = false;
}
return result;
}
// servo_service interface setPositionGain function client shim.
bool servo_service_client::setPositionGain(const char * id, float position_gain)
{
erpc_status_t err = kErpcStatus_Success;
bool result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_setPositionGainId, request.getSequence());
{
uint32_t id_len = strlen((const char*)id);
codec->writeString(id_len, (const char*)id);
}
codec->write(position_gain);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_setPositionGainId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = false;
}
return result;
}
// servo_service interface setMode function client shim.
bool servo_service_client::setMode(RpcMotionMode mode)
{
erpc_status_t err = kErpcStatus_Success;
bool result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_setModeId, request.getSequence());
codec->write(static_cast<int32_t>(mode));
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_setModeId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = false;
}
return result;
}
// servo_service interface setUpdatePeriodMs function client shim.
bool servo_service_client::setUpdatePeriodMs(uint32_t ms)
{
erpc_status_t err = kErpcStatus_Success;
bool result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_setUpdatePeriodMsId, request.getSequence());
codec->write(ms);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_setUpdatePeriodMsId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = false;
}
return result;
}
// servo_service interface move function client shim.
int32_t servo_service_client::move(const list_ServoCmd_1_t * cmds)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_moveId, request.getSequence());
write_list_ServoCmd_1_t_struct(codec, cmds);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_moveId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}
// servo_service interface moveJ function client shim.
int32_t servo_service_client::moveJ(const list_float_1_t * angles_rad)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_moveJId, request.getSequence());
write_list_float_1_t_struct(codec, angles_rad);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_moveJId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}

View File

@ -0,0 +1,44 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_servo_service_client_hpp_)
#define _servo_service_client_hpp_
#include "servo_service_interface.hpp"
#include "erpc_client_manager.h"
namespace erpcShim
{
class servo_service_client: public servo_service_interface
{
public:
servo_service_client(erpc::ClientManager *manager);
virtual ~servo_service_client();
virtual bool setConstraints(const char * id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad);
virtual bool setPositionGain(const char * id, float position_gain);
virtual bool setMode(RpcMotionMode mode);
virtual bool setUpdatePeriodMs(uint32_t ms);
virtual int32_t move(const list_ServoCmd_1_t * cmds);
virtual int32_t moveJ(const list_float_1_t * angles_rad);
protected:
erpc::ClientManager *m_clientManager;
};
} // erpcShim
#endif // _servo_service_client_hpp_

View File

@ -0,0 +1,69 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_servo_service_common_h_)
#define _servo_service_common_h_
#if defined(__cplusplus)
extern "C"
{
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_SERVO_SERVICE)
#define ERPC_TYPE_DEFINITIONS_SERVO_SERVICE
// Enumerators data types declarations
typedef enum RpcMotionMode
{
RpcMotionModeImmediate = 0,
RpcMotionModeSCurve = 1,
RpcMotionModeFollow = 2
} RpcMotionMode;
// Aliases data types declarations
typedef struct list_float_1_t list_float_1_t;
typedef struct ServoCmd ServoCmd;
typedef struct list_ServoCmd_1_t list_ServoCmd_1_t;
// Structures/unions data types declarations
struct list_float_1_t
{
float * elements;
uint32_t elementsCount;
};
struct ServoCmd
{
char * id;
float angle_rad;
};
struct list_ServoCmd_1_t
{
ServoCmd * elements;
uint32_t elementsCount;
};
#endif // ERPC_TYPE_DEFINITIONS_SERVO_SERVICE
#if defined(__cplusplus)
}
#endif
#endif // _servo_service_common_h_

View File

@ -0,0 +1,61 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_servo_service_common_hpp_)
#define _servo_service_common_hpp_
#include <cstddef>
#include <cstdint>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_SERVO_SERVICE)
#define ERPC_TYPE_DEFINITIONS_SERVO_SERVICE
// Enumerators data types declarations
typedef enum RpcMotionMode
{
RpcMotionModeImmediate = 0,
RpcMotionModeSCurve = 1,
RpcMotionModeFollow = 2
} RpcMotionMode;
// Aliases data types declarations
typedef struct list_float_1_t list_float_1_t;
typedef struct ServoCmd ServoCmd;
typedef struct list_ServoCmd_1_t list_ServoCmd_1_t;
// Structures/unions data types declarations
struct list_float_1_t
{
float * elements;
uint32_t elementsCount;
};
struct ServoCmd
{
char * id;
float angle_rad;
};
struct list_ServoCmd_1_t
{
ServoCmd * elements;
uint32_t elementsCount;
};
#endif // ERPC_TYPE_DEFINITIONS_SERVO_SERVICE
#endif // _servo_service_common_hpp_

View File

@ -0,0 +1,20 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "servo_service_interface.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace std;
using namespace erpcShim;
servo_service_interface::~servo_service_interface(void)
{
}

View File

@ -0,0 +1,47 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_servo_service_interface_hpp_)
#define _servo_service_interface_hpp_
#include "servo_service_common.hpp"
namespace erpcShim
{
// Abstract base class for servo_service
class servo_service_interface
{
public:
static const uint8_t m_serviceId = 1;
static const uint8_t m_setConstraintsId = 1;
static const uint8_t m_setPositionGainId = 2;
static const uint8_t m_setModeId = 3;
static const uint8_t m_setUpdatePeriodMsId = 4;
static const uint8_t m_moveId = 5;
static const uint8_t m_moveJId = 6;
virtual ~servo_service_interface(void);
virtual bool setConstraints(const char * id, float max_velocity_rad, float max_acceleration_rad, float max_jerk_rad) = 0;
virtual bool setPositionGain(const char * id, float position_gain) = 0;
virtual bool setMode(RpcMotionMode mode) = 0;
virtual bool setUpdatePeriodMs(uint32_t ms) = 0;
virtual int32_t move(const list_ServoCmd_1_t * cmds) = 0;
virtual int32_t moveJ(const list_float_1_t * angles_rad) = 0;
private:
};
} // erpcShim
#endif // _servo_service_interface_hpp_

View File

@ -0,0 +1,539 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "servo_service_server.hpp"
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include <new>
#include "erpc_port.h"
#endif
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_NESTED_CALLS_DETECTION
extern bool nestingDetection;
#endif
//! @brief Function to read struct ServoCmd
static void read_ServoCmd_struct(erpc::Codec * codec, ServoCmd * data);
//! @brief Function to read struct list_ServoCmd_1_t
static void read_list_ServoCmd_1_t_struct(erpc::Codec * codec, list_ServoCmd_1_t * data);
//! @brief Function to read struct list_float_1_t
static void read_list_float_1_t_struct(erpc::Codec * codec, list_float_1_t * data);
// Read struct ServoCmd function implementation
static void read_ServoCmd_struct(erpc::Codec * codec, ServoCmd * data)
{
if(NULL == data)
{
return;
}
{
uint32_t id_len;
char * id_local;
codec->readString(id_len, &id_local);
data->id = (char*) erpc_malloc((id_len + 1) * sizeof(char));
if ((data->id == NULL) || (id_local == NULL))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(data->id, id_local, id_len);
(data->id)[id_len] = 0;
}
}
codec->read(data->angle_rad);
}
// Read struct list_ServoCmd_1_t function implementation
static void read_list_ServoCmd_1_t_struct(erpc::Codec * codec, list_ServoCmd_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startReadList(data->elementsCount);
data->elements = (ServoCmd *) erpc_malloc(data->elementsCount * sizeof(ServoCmd));
if ((data->elements == NULL) && (data->elementsCount > 0))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
read_ServoCmd_struct(codec, &(data->elements[listCount]));
}
}
// Read struct list_float_1_t function implementation
static void read_list_float_1_t_struct(erpc::Codec * codec, list_float_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startReadList(data->elementsCount);
data->elements = (float *) erpc_malloc(data->elementsCount * sizeof(float));
if ((data->elements == NULL) && (data->elementsCount > 0))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
codec->read(data->elements[listCount]);
}
}
//! @brief Function to free space allocated inside struct ServoCmd
static void free_ServoCmd_struct(ServoCmd * data);
//! @brief Function to free space allocated inside struct list_ServoCmd_1_t
static void free_list_ServoCmd_1_t_struct(list_ServoCmd_1_t * data);
//! @brief Function to free space allocated inside struct list_float_1_t
static void free_list_float_1_t_struct(list_float_1_t * data);
// Free space allocated inside struct ServoCmd function implementation
static void free_ServoCmd_struct(ServoCmd * data)
{
erpc_free(data->id);
}
// Free space allocated inside struct list_ServoCmd_1_t function implementation
static void free_list_ServoCmd_1_t_struct(list_ServoCmd_1_t * data)
{
for (uint32_t listCount = 0; listCount < data->elementsCount; ++listCount)
{
free_ServoCmd_struct(&data->elements[listCount]);
}
erpc_free(data->elements);
}
// Free space allocated inside struct list_float_1_t function implementation
static void free_list_float_1_t_struct(list_float_1_t * data)
{
erpc_free(data->elements);
}
servo_service_service::servo_service_service(servo_service_interface *_servo_service_interface)
: erpc::Service(servo_service_interface::m_serviceId)
, m_handler(_servo_service_interface)
{
}
servo_service_service::~servo_service_service()
{
}
// return service interface handler.
servo_service_interface* servo_service_service::getHandler(void)
{
return m_handler;
}
// Call the correct server shim based on method unique ID.
erpc_status_t servo_service_service::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory, Transport * transport)
{
erpc_status_t erpcStatus;
switch (methodId)
{
case servo_service_interface::m_setConstraintsId:
{
erpcStatus = setConstraints_shim(codec, messageFactory, transport, sequence);
break;
}
case servo_service_interface::m_setPositionGainId:
{
erpcStatus = setPositionGain_shim(codec, messageFactory, transport, sequence);
break;
}
case servo_service_interface::m_setModeId:
{
erpcStatus = setMode_shim(codec, messageFactory, transport, sequence);
break;
}
case servo_service_interface::m_setUpdatePeriodMsId:
{
erpcStatus = setUpdatePeriodMs_shim(codec, messageFactory, transport, sequence);
break;
}
case servo_service_interface::m_moveId:
{
erpcStatus = move_shim(codec, messageFactory, transport, sequence);
break;
}
case servo_service_interface::m_moveJId:
{
erpcStatus = moveJ_shim(codec, messageFactory, transport, sequence);
break;
}
default:
{
erpcStatus = kErpcStatus_InvalidArgument;
break;
}
}
return erpcStatus;
}
// Server shim for setConstraints of servo_service interface.
erpc_status_t servo_service_service::setConstraints_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
char * id = NULL;
float max_velocity_rad;
float max_acceleration_rad;
float max_jerk_rad;
bool result;
// startReadMessage() was already called before this shim was invoked.
{
uint32_t id_len;
char * id_local;
codec->readString(id_len, &id_local);
id = (char*) erpc_malloc((id_len + 1) * sizeof(char));
if ((id == NULL) || (id_local == NULL))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(id, id_local, id_len);
(id)[id_len] = 0;
}
}
codec->read(max_velocity_rad);
codec->read(max_acceleration_rad);
codec->read(max_jerk_rad);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->setConstraints(id, max_velocity_rad, max_acceleration_rad, max_jerk_rad);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, servo_service_interface::m_serviceId, servo_service_interface::m_setConstraintsId, sequence);
codec->write(result);
err = codec->getStatus();
}
erpc_free(id);
return err;
}
// Server shim for setPositionGain of servo_service interface.
erpc_status_t servo_service_service::setPositionGain_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
char * id = NULL;
float position_gain;
bool result;
// startReadMessage() was already called before this shim was invoked.
{
uint32_t id_len;
char * id_local;
codec->readString(id_len, &id_local);
id = (char*) erpc_malloc((id_len + 1) * sizeof(char));
if ((id == NULL) || (id_local == NULL))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(id, id_local, id_len);
(id)[id_len] = 0;
}
}
codec->read(position_gain);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->setPositionGain(id, position_gain);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, servo_service_interface::m_serviceId, servo_service_interface::m_setPositionGainId, sequence);
codec->write(result);
err = codec->getStatus();
}
erpc_free(id);
return err;
}
// Server shim for setMode of servo_service interface.
erpc_status_t servo_service_service::setMode_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
RpcMotionMode mode;
int32_t _tmp_local_i32;
bool result;
// startReadMessage() was already called before this shim was invoked.
codec->read(_tmp_local_i32);
mode = static_cast<RpcMotionMode>(_tmp_local_i32);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->setMode(mode);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, servo_service_interface::m_serviceId, servo_service_interface::m_setModeId, sequence);
codec->write(result);
err = codec->getStatus();
}
return err;
}
// Server shim for setUpdatePeriodMs of servo_service interface.
erpc_status_t servo_service_service::setUpdatePeriodMs_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
uint32_t ms;
bool result;
// startReadMessage() was already called before this shim was invoked.
codec->read(ms);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->setUpdatePeriodMs(ms);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, servo_service_interface::m_serviceId, servo_service_interface::m_setUpdatePeriodMsId, sequence);
codec->write(result);
err = codec->getStatus();
}
return err;
}
// Server shim for move of servo_service interface.
erpc_status_t servo_service_service::move_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
list_ServoCmd_1_t *cmds = NULL;
cmds = (list_ServoCmd_1_t *) erpc_malloc(sizeof(list_ServoCmd_1_t));
if (cmds == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
int32_t result;
// startReadMessage() was already called before this shim was invoked.
read_list_ServoCmd_1_t_struct(codec, cmds);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->move(cmds);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, servo_service_interface::m_serviceId, servo_service_interface::m_moveId, sequence);
codec->write(result);
err = codec->getStatus();
}
if (cmds)
{
free_list_ServoCmd_1_t_struct(cmds);
}
erpc_free(cmds);
return err;
}
// Server shim for moveJ of servo_service interface.
erpc_status_t servo_service_service::moveJ_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
list_float_1_t *angles_rad = NULL;
angles_rad = (list_float_1_t *) erpc_malloc(sizeof(list_float_1_t));
if (angles_rad == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
int32_t result;
// startReadMessage() was already called before this shim was invoked.
read_list_float_1_t_struct(codec, angles_rad);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->moveJ(angles_rad);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, servo_service_interface::m_serviceId, servo_service_interface::m_moveJId, sequence);
codec->write(result);
err = codec->getStatus();
}
if (angles_rad)
{
free_list_float_1_t_struct(angles_rad);
}
erpc_free(angles_rad);
return err;
}

View File

@ -0,0 +1,64 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:16:31 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_servo_service_server_hpp_)
#define _servo_service_server_hpp_
#include "servo_service_interface.hpp"
#include "erpc_server.hpp"
#include "erpc_codec.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
namespace erpcShim
{
/*!
* @brief Service subclass for servo_service.
*/
class servo_service_service : public erpc::Service
{
public:
servo_service_service(servo_service_interface *_servo_service_interface);
virtual ~servo_service_service();
/*! @brief return service interface handler. */
servo_service_interface* getHandler(void);
/*! @brief Call the correct server shim based on method unique ID. */
virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport);
private:
servo_service_interface *m_handler;
/*! @brief Server shim for setConstraints of servo_service interface. */
erpc_status_t setConstraints_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for setPositionGain of servo_service interface. */
erpc_status_t setPositionGain_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for setMode of servo_service interface. */
erpc_status_t setMode_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for setUpdatePeriodMs of servo_service interface. */
erpc_status_t setUpdatePeriodMs_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for move of servo_service interface. */
erpc_status_t move_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for moveJ of servo_service interface. */
erpc_status_t moveJ_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
};
} // erpcShim
#endif // _servo_service_server_hpp_

41
main.py Normal file
View File

@ -0,0 +1,41 @@
import statistics
import time
import erpc
from servo_service import client
PORT = "COM8"
BAUD = 115200
N = 180
JOINT_COUNT = 48
def main():
xport = erpc.transport.SerialTransport(PORT, BAUD)
client_mgr = erpc.client.ClientManager(xport, erpc.basic_codec.BasicCodec)
api = client.servo_serviceClient(client_mgr)
angles = [0.0] * JOINT_COUNT
while True:
costs_ms = []
for _ in range(N):
t0 = time.perf_counter()
api.moveJ(angles)
t1 = time.perf_counter()
costs_ms.append((t1 - t0) * 1000.0)
print(f"N={N}")
print(f"avg = {statistics.mean(costs_ms):.3f} ms")
print(f"min = {min(costs_ms):.3f} ms")
print(f"max = {max(costs_ms):.3f} ms")
if N >= 2:
print(f"p50 = {statistics.median(costs_ms):.3f} ms")
print(f"p95 ~= {sorted(costs_ms)[int(0.95 * (N - 1))]:.3f} ms")
if __name__ == "__main__":
main()

35
run_ui.ps1 Normal file
View File

@ -0,0 +1,35 @@
param(
[string]$PythonExecutable = "C:\Users\Administrator\miniconda3\envs\cmvr-head-client\python.exe",
[switch]$SkipBuild
)
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
$buildScript = Join-Path $repoRoot "cpp\common\curve\build_python.ps1"
$uiScript = Join-Path $repoRoot "ui\face_servo_control.py"
if (-not (Test-Path $PythonExecutable)) {
throw "Python executable not found at $PythonExecutable"
}
if (-not (Test-Path $uiScript)) {
throw "UI script not found at $uiScript"
}
if (-not $SkipBuild) {
if (-not (Test-Path $buildScript)) {
throw "Build script not found at $buildScript"
}
Write-Host "[1/2] Rebuilding _s_curve_native..."
powershell -ExecutionPolicy Bypass -File $buildScript -PythonExecutable $PythonExecutable
if ($LASTEXITCODE -ne 0) {
throw "Native module rebuild failed."
}
} else {
Write-Host "[1/2] Skipping native rebuild."
}
Write-Host "[2/2] Launching UI..."
& $PythonExecutable $uiScript

246
s_curve.py Normal file
View File

@ -0,0 +1,246 @@
import importlib.util
from pathlib import Path
import sys
REPO_ROOT = Path(__file__).resolve().parent
class SCurveError(RuntimeError):
pass
def _default_module_candidates():
search_roots = [
REPO_ROOT / "cpp" / "common" / "curve" / "build",
REPO_ROOT / "cpp" / "common" / "curve" / "build" / "Release",
]
patterns = [
"_s_curve_native*.pyd",
"_s_curve_native*.so",
]
candidates = []
for root in search_roots:
if not root.exists():
continue
for pattern in patterns:
candidates.extend(sorted(root.glob(pattern)))
return candidates
def _resolve_module_path(module_path=None):
if module_path:
path = Path(module_path)
if path.exists():
return path
raise FileNotFoundError(f"SCurve native module not found: {path}")
for candidate in _default_module_candidates():
if candidate.exists():
return candidate
candidate_text = "\n".join(str(path) for path in _default_module_candidates())
raise FileNotFoundError(
"SCurve native module not found. Build it first with:\n"
"powershell -ExecutionPolicy Bypass -File .\\cpp\\common\\curve\\build_python.ps1 "
"-PythonExecutable 'C:\\Users\\Administrator\\miniconda3\\envs\\cmvr-head-client\\python.exe'\n"
f"Expected one of:\n{candidate_text}"
)
class SCurve:
def __init__(self, max_velocity=3.0, max_acceleration=10.0, max_jerk=50.0, module_path=None, dll_path=None):
resolved_path = _resolve_module_path(module_path or dll_path)
try:
self._module = self._load_native_module(resolved_path)
self._native = self._module.SCurve(max_velocity, max_acceleration, max_jerk)
except Exception as exc:
raise SCurveError(f"Failed to create pybind11 SCurve instance: {exc}") from exc
@staticmethod
def _load_native_module(module_path):
module_name = "_s_curve_native"
if module_name in sys.modules:
return sys.modules[module_name]
spec = importlib.util.spec_from_file_location(module_name, module_path)
if spec is None or spec.loader is None:
raise ImportError(f"Unable to load module from {module_path}")
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
return module
@staticmethod
def _wrap_native_call(action, fn, *args, **kwargs):
try:
return fn(*args, **kwargs)
except Exception as exc:
raise SCurveError(f"{action} failed: {exc}") from exc
def setConstraints(self, max_velocity, max_acceleration, max_jerk):
return self._wrap_native_call(
"setConstraints",
self._native.setConstraints,
max_velocity,
max_acceleration,
max_jerk,
)
def getConstraints(self):
return self._wrap_native_call(
"getConstraints",
self._native.getConstraints,
)
def calculateProfile(self, start_position, end_position, start_velocity=0.0, end_velocity=0.0):
return self._wrap_native_call(
"calculateProfile",
self._native.calculateProfile,
start_position,
end_position,
start_velocity,
end_velocity,
)
def getPositionAtTime(self, profile, t):
return self._wrap_native_call("getPositionAtTime", self._native.getPositionAtTime, profile, t)
def getVelocityAtTime(self, profile, t):
return self._wrap_native_call("getVelocityAtTime", self._native.getVelocityAtTime, profile, t)
def getAccelerationAtTime(self, profile, t):
return self._wrap_native_call(
"getAccelerationAtTime",
self._native.getAccelerationAtTime,
profile,
t,
)
def getJerkAtTime(self, profile, t):
return self._wrap_native_call("getJerkAtTime", self._native.getJerkAtTime, profile, t)
def sampleTrajectory(self, profile, dt):
return self._wrap_native_call(
"sampleTrajectory",
self._native.sampleTrajectory,
profile,
dt,
)
class SCurvePositionPlanner1D:
def __init__(self, max_velocity=3.0, max_acceleration=10.0, max_jerk=50.0, module_path=None, dll_path=None):
resolved_path = _resolve_module_path(module_path or dll_path)
try:
self._module = SCurve._load_native_module(resolved_path)
self._native = self._module.SCurvePositionPlanner1D(
max_velocity,
max_acceleration,
max_jerk,
)
except Exception as exc:
raise SCurveError(f"Failed to create pybind11 SCurvePositionPlanner1D instance: {exc}") from exc
def setConstraints(self, max_velocity, max_acceleration, max_jerk):
return SCurve._wrap_native_call(
"setConstraints",
self._native.setConstraints,
max_velocity,
max_acceleration,
max_jerk,
)
def getConstraints(self):
return SCurve._wrap_native_call("getConstraints", self._native.getConstraints)
def setPositionGain(self, position_gain):
return SCurve._wrap_native_call("setPositionGain", self._native.setPositionGain, position_gain)
def getPositionGain(self):
return SCurve._wrap_native_call("getPositionGain", self._native.getPositionGain)
def initialize(self, position, velocity=0.0, acceleration=0.0):
return SCurve._wrap_native_call(
"initialize",
self._native.initialize,
position,
velocity,
acceleration,
)
def reset(self):
return SCurve._wrap_native_call("reset", self._native.reset)
def setTarget(self, target_position):
return SCurve._wrap_native_call("setTarget", self._native.setTarget, target_position)
def update(self, dt):
return SCurve._wrap_native_call("update", self._native.update, dt)
def getState(self):
return SCurve._wrap_native_call("getState", self._native.getState)
def sampleTrajectory(
self,
target_position,
dt,
duration,
initial_position=0.0,
initial_velocity=0.0,
initial_acceleration=0.0,
position_gain=None,
):
if dt <= 0:
raise ValueError("dt must be > 0")
if duration < 0:
raise ValueError("duration must be >= 0")
self.initialize(initial_position, initial_velocity, initial_acceleration)
if position_gain is not None:
self.setPositionGain(position_gain)
self.setTarget(target_position)
times = [0.0]
state = self.getState()
positions = [state.position]
velocities = [state.velocity]
accelerations = [state.acceleration]
jerks = [state.jerk]
targets = [state.target_position]
moving = [state.is_moving]
t = 0.0
while t + dt <= duration + 1e-12:
t = round(t + dt, 12)
self.update(dt)
state = self.getState()
times.append(t)
positions.append(state.position)
velocities.append(state.velocity)
accelerations.append(state.acceleration)
jerks.append(state.jerk)
targets.append(state.target_position)
moving.append(state.is_moving)
if abs(times[-1] - duration) > 1e-9:
final_dt = duration - times[-1]
if final_dt > 1e-12:
self.update(final_dt)
state = self.getState()
times.append(duration)
positions.append(state.position)
velocities.append(state.velocity)
accelerations.append(state.acceleration)
jerks.append(state.jerk)
targets.append(state.target_position)
moving.append(state.is_moving)
return {
"times": times,
"positions": positions,
"velocities": velocities,
"accelerations": accelerations,
"jerks": jerks,
"targets": targets,
"moving": moving,
}

34
servo_service.erpc Normal file
View File

@ -0,0 +1,34 @@
// servo_service.erpc
// Generator examples:
// .\erpcgen.exe -o .\generated\ -g c .\servo_service.erpc
// .\erpcgen.exe -g py .\servo_service.erpc
// 注意interface 客户端和服务端erpc里面的函数顺序一定要一样
program servo_service
enum RpcMotionMode {
RpcMotionModeImmediate = 0,
RpcMotionModeSCurve = 1,
RpcMotionModeFollow = 2
}
struct ServoCmd {
string id
float angle_rad
}
interface servo_service
{
setConstraints(string id,
float max_velocity_rad,
float max_acceleration_rad,
float max_jerk_rad) -> bool
setPositionGain(string id,
float position_gain) -> bool
setMode(RpcMotionMode mode)->bool
setUpdatePeriodMs(uint32 ms) -> bool
move(list<ServoCmd> cmds) -> int32
moveJ(list<float> angles_rad) -> int32
}

19
servo_service/__init__.py Normal file
View File

@ -0,0 +1,19 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:26 2026.
#
# AUTOGENERATED - DO NOT EDIT
#
try:
from erpc import erpc_version
version = erpc_version.ERPC_VERSION
except ImportError:
version = "unknown"
if version != "1.14.0":
raise ValueError("The generated shim code version (1.14.0) is different to the rest of eRPC code (%s). \
Install newer version by running \"python setup.py install\" in folder erpc/erpc_python/." % repr(version))
from . import common
from . import client
from . import server
from . import interface

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

142
servo_service/client.py Normal file
View File

@ -0,0 +1,142 @@
#
# Generated by erpcgen 1.14.0 on Tue Apr 28 12:25:26 2026.
#
# AUTOGENERATED - DO NOT EDIT
#
import erpc
from . import common, interface
# Client for servo_service
class servo_serviceClient(interface.Iservo_service):
def __init__(self, manager):
super(servo_serviceClient, self).__init__()
self._clientManager = manager
def setConstraints(self, id, max_velocity_rad, max_acceleration_rad, max_jerk_rad):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.SETCONSTRAINTS_ID,
sequence=request.sequence))
if id is None:
raise ValueError("id is None")
codec.write_string(id)
if max_velocity_rad is None:
raise ValueError("max_velocity_rad is None")
codec.write_float(max_velocity_rad)
if max_acceleration_rad is None:
raise ValueError("max_acceleration_rad is None")
codec.write_float(max_acceleration_rad)
if max_jerk_rad is None:
raise ValueError("max_jerk_rad is None")
codec.write_float(max_jerk_rad)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_bool()
return _result
def setPositionGain(self, id, position_gain):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.SETPOSITIONGAIN_ID,
sequence=request.sequence))
if id is None:
raise ValueError("id is None")
codec.write_string(id)
if position_gain is None:
raise ValueError("position_gain is None")
codec.write_float(position_gain)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_bool()
return _result
def setMode(self, mode):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.SETMODE_ID,
sequence=request.sequence))
if mode is None:
raise ValueError("mode is None")
codec.write_int32(mode)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_bool()
return _result
def setUpdatePeriodMs(self, ms):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.SETUPDATEPERIODMS_ID,
sequence=request.sequence))
if ms is None:
raise ValueError("ms is None")
codec.write_uint32(ms)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_bool()
return _result
def move(self, cmds):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.MOVE_ID,
sequence=request.sequence))
if cmds is None:
raise ValueError("cmds is None")
codec.start_write_list(len(cmds))
for _i0 in cmds:
_i0._write(codec)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_int32()
return _result
def moveJ(self, angles_rad):
# Build remote function invocation message.
request = self._clientManager.create_request()
codec = request.codec
codec.start_write_message(erpc.codec.MessageInfo(
type=erpc.codec.MessageType.kInvocationMessage,
service=self.SERVICE_ID,
request=self.MOVEJ_ID,
sequence=request.sequence))
if angles_rad is None:
raise ValueError("angles_rad is None")
codec.start_write_list(len(angles_rad))
for _i0 in angles_rad:
codec.write_float(_i0)
# Send request and process reply.
self._clientManager.perform_request(request)
_result = codec.read_int32()
return _result

Some files were not shown because too many files have changed in this diff Show More