Skip to content

Commit 5a8e543

Browse files
author
Luca Toniolo
committed
Replace C++ Ruckig with pure C cruckig to fix RTAI builds
The C++ Ruckig library cannot compile in RTAI kernel space (no C++ in kernel modules). Replace it with cruckig, a pure C99 port that produces identical trajectories (validated to 5.9e-12 position error). - Vendor cruckig source (MIT license) from github.com/mika4128/cruckig - Rewrite ruckig_wrapper.c to use cruckig API (same ruckig_wrapper.h interface, zero changes needed in tp.c, tc.c, sp_scurve.c) - Add cruckig_compat.h for RTAPI kernel/userspace portability (rtapi_slab.h for malloc/free, rtapi_math.h for math functions) - Update Makefile and motion-logger Submakefile for C-only build - Remove C++ Ruckig source tree and ruckig_wrapper.cc Fixes: #3875
1 parent 4025bf9 commit 5a8e543

121 files changed

Lines changed: 7320 additions & 52610 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Makefile

Lines changed: 49 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -279,37 +279,25 @@ $(sort $(CUSEROBJS)) : objects/%.o: %.c
279279
-MP -MD -MF "${@:.o=.d}" -MT "$@" \
280280
$< -o $@
281281

282-
# Ruckig files need C++20
283-
RUCKIG_CXX_FILES := $(filter emc/tp/ruckig%,$(CXXUSERSRCS))
284-
NON_RUCKIG_CXX_FILES := $(filter-out emc/tp/ruckig%,$(CXXUSERSRCS))
285-
286-
$(sort $(patsubst %.cpp,objects/%.o,$(filter %.cpp,$(RUCKIG_CXX_FILES)))) : objects/%.o: %.cpp
282+
# Cruckig (pure C) source files — compiled as C, no C++ needed
283+
# Headers are local ("" includes relative to cruckig/), no -I needed
284+
objects/emc/tp/cruckig/%.o : emc/tp/cruckig/%.c
287285
$(ECHO) Compiling $<
288286
@mkdir -p $(dir $@)
289287
@rm -f $@
290-
$(Q)$(CXX) -c $(CXXFLAGS) $(EXTRAFLAGS) -std=c++20 \
291-
-I$(BASEPWD)/emc/tp/ruckig/include \
292-
-MP -MD -MF "${@:.o=.d}" -MT "$@" \
293-
$< -o $@
294-
295-
$(sort $(patsubst %.cc,objects/%.o,$(filter %.cc,$(RUCKIG_CXX_FILES)))) : objects/%.o: %.cc
296-
$(ECHO) Compiling $<
297-
@mkdir -p $(dir $@)
298-
@rm -f $@
299-
$(Q)$(CXX) -c $(CXXFLAGS) $(EXTRAFLAGS) -std=c++20 \
300-
-I$(BASEPWD)/emc/tp/ruckig/include \
288+
$(Q)$(CC) -c $(CFLAGS) $(EXTRAFLAGS) \
301289
-MP -MD -MF "${@:.o=.d}" -MT "$@" \
302290
$< -o $@
303291

304-
$(sort $(patsubst %.cpp,objects/%.o,$(filter %.cpp,$(NON_RUCKIG_CXX_FILES)))) : objects/%.o: %.cpp
292+
$(sort $(patsubst %.cpp,objects/%.o,$(filter %.cpp,$(CXXUSERSRCS)))) : objects/%.o: %.cpp
305293
$(ECHO) Compiling $<
306294
@mkdir -p $(dir $@)
307295
@rm -f $@
308296
$(Q)$(CXX) -c $(CXXFLAGS) $(EXTRAFLAGS) \
309297
-MP -MD -MF "${@:.o=.d}" -MT "$@" \
310298
$< -o $@
311299

312-
$(sort $(patsubst %.cc,objects/%.o,$(filter %.cc,$(NON_RUCKIG_CXX_FILES)))) : objects/%.o: %.cc
300+
$(sort $(patsubst %.cc,objects/%.o,$(filter %.cc,$(CXXUSERSRCS)))) : objects/%.o: %.cc
313301
$(ECHO) Compiling $<
314302
@mkdir -p $(dir $@)
315303
@rm -f $@
@@ -1198,17 +1186,25 @@ motmod-objs += emc/motion/stashf.o
11981186
motmod-objs += emc/motion/dbuf.o
11991187
motmod-objs += emc/tp/sp_scurve.o
12001188
motmod-objs += emc/tp/ruckig_wrapper.o
1201-
motmod-objs += emc/tp/ruckig/src/ruckig/brake.o
1202-
motmod-objs += emc/tp/ruckig/src/ruckig/position_first_step1.o
1203-
motmod-objs += emc/tp/ruckig/src/ruckig/position_first_step2.o
1204-
motmod-objs += emc/tp/ruckig/src/ruckig/position_second_step1.o
1205-
motmod-objs += emc/tp/ruckig/src/ruckig/position_second_step2.o
1206-
motmod-objs += emc/tp/ruckig/src/ruckig/position_third_step1.o
1207-
motmod-objs += emc/tp/ruckig/src/ruckig/position_third_step2.o
1208-
motmod-objs += emc/tp/ruckig/src/ruckig/velocity_second_step1.o
1209-
motmod-objs += emc/tp/ruckig/src/ruckig/velocity_second_step2.o
1210-
motmod-objs += emc/tp/ruckig/src/ruckig/velocity_third_step1.o
1211-
motmod-objs += emc/tp/ruckig/src/ruckig/velocity_third_step2.o
1189+
motmod-objs += emc/tp/cruckig/block.o
1190+
motmod-objs += emc/tp/cruckig/brake.o
1191+
motmod-objs += emc/tp/cruckig/calculator.o
1192+
motmod-objs += emc/tp/cruckig/cruckig.o
1193+
motmod-objs += emc/tp/cruckig/input_parameter.o
1194+
motmod-objs += emc/tp/cruckig/output_parameter.o
1195+
motmod-objs += emc/tp/cruckig/profile.o
1196+
motmod-objs += emc/tp/cruckig/roots.o
1197+
motmod-objs += emc/tp/cruckig/trajectory.o
1198+
motmod-objs += emc/tp/cruckig/position_first_step1.o
1199+
motmod-objs += emc/tp/cruckig/position_first_step2.o
1200+
motmod-objs += emc/tp/cruckig/position_second_step1.o
1201+
motmod-objs += emc/tp/cruckig/position_second_step2.o
1202+
motmod-objs += emc/tp/cruckig/position_third_step1.o
1203+
motmod-objs += emc/tp/cruckig/position_third_step2.o
1204+
motmod-objs += emc/tp/cruckig/velocity_second_step1.o
1205+
motmod-objs += emc/tp/cruckig/velocity_second_step2.o
1206+
motmod-objs += emc/tp/cruckig/velocity_third_step1.o
1207+
motmod-objs += emc/tp/cruckig/velocity_third_step2.o
12121208

12131209
obj-m += homemod.o
12141210
homemod-objs := emc/motion/homemod.o
@@ -1225,17 +1221,25 @@ tpmod-objs += emc/nml_intf/emcpose.o
12251221
tpmod-objs += libnml/posemath/_posemath.o
12261222
tpmod-objs += emc/tp/sp_scurve.o
12271223
tpmod-objs += emc/tp/ruckig_wrapper.o
1228-
tpmod-objs += emc/tp/ruckig/src/ruckig/brake.o
1229-
tpmod-objs += emc/tp/ruckig/src/ruckig/position_first_step1.o
1230-
tpmod-objs += emc/tp/ruckig/src/ruckig/position_first_step2.o
1231-
tpmod-objs += emc/tp/ruckig/src/ruckig/position_second_step1.o
1232-
tpmod-objs += emc/tp/ruckig/src/ruckig/position_second_step2.o
1233-
tpmod-objs += emc/tp/ruckig/src/ruckig/position_third_step1.o
1234-
tpmod-objs += emc/tp/ruckig/src/ruckig/position_third_step2.o
1235-
tpmod-objs += emc/tp/ruckig/src/ruckig/velocity_second_step1.o
1236-
tpmod-objs += emc/tp/ruckig/src/ruckig/velocity_second_step2.o
1237-
tpmod-objs += emc/tp/ruckig/src/ruckig/velocity_third_step1.o
1238-
tpmod-objs += emc/tp/ruckig/src/ruckig/velocity_third_step2.o
1224+
tpmod-objs += emc/tp/cruckig/block.o
1225+
tpmod-objs += emc/tp/cruckig/brake.o
1226+
tpmod-objs += emc/tp/cruckig/calculator.o
1227+
tpmod-objs += emc/tp/cruckig/cruckig.o
1228+
tpmod-objs += emc/tp/cruckig/input_parameter.o
1229+
tpmod-objs += emc/tp/cruckig/output_parameter.o
1230+
tpmod-objs += emc/tp/cruckig/profile.o
1231+
tpmod-objs += emc/tp/cruckig/roots.o
1232+
tpmod-objs += emc/tp/cruckig/trajectory.o
1233+
tpmod-objs += emc/tp/cruckig/position_first_step1.o
1234+
tpmod-objs += emc/tp/cruckig/position_first_step2.o
1235+
tpmod-objs += emc/tp/cruckig/position_second_step1.o
1236+
tpmod-objs += emc/tp/cruckig/position_second_step2.o
1237+
tpmod-objs += emc/tp/cruckig/position_third_step1.o
1238+
tpmod-objs += emc/tp/cruckig/position_third_step2.o
1239+
tpmod-objs += emc/tp/cruckig/velocity_second_step1.o
1240+
tpmod-objs += emc/tp/cruckig/velocity_second_step2.o
1241+
tpmod-objs += emc/tp/cruckig/velocity_third_step1.o
1242+
tpmod-objs += emc/tp/cruckig/velocity_third_step2.o
12391243
tpmod-objs += libnml/posemath/sincos.o $(MATHSTUB)
12401244

12411245
TORTOBJS = $(foreach file,$($(patsubst %.o,%,$(1))-objs), objects/rt$(file))
@@ -1257,7 +1261,7 @@ modules: $(patsubst %.o,../rtlib/%.so,$(obj-m))
12571261
RTFLAGS += -fno-strict-aliasing -fwrapv
12581262

12591263
# Rules to make .o (object) files for C files
1260-
$(sort $(filter-out objects/rtemc/tp/ruckig_wrapper.o objects/rtemc/tp/ruckig/src/ruckig/%,$(RTOBJS))) : objects/rt%.o : %.c
1264+
$(sort $(filter-out objects/rtemc/tp/cruckig/%,$(RTOBJS))) : objects/rt%.o : %.c
12611265
$(ECHO) Compiling realtime $<
12621266
@rm -f $@
12631267
@mkdir -p $(dir $@)
@@ -1266,30 +1270,13 @@ $(sort $(filter-out objects/rtemc/tp/ruckig_wrapper.o objects/rtemc/tp/ruckig/sr
12661270
-MP -MD -MF "${@:.o=.d}" -MT "$@" \
12671271
$< -o $@
12681272

1269-
# C++ flags for Ruckig: drop C-only -Wno-declaration-after-statement, and suppress
1270-
# false-positive -Warray-bounds and -Wunused-parameter in Ruckig library
1271-
RUCKIG_CXXFLAGS := $(filter-out -Wno-declaration-after-statement,$(EXTRA_CFLAGS)) \
1272-
-Wno-array-bounds -Wno-unused-parameter
1273-
1274-
# Rules for C++ .cc files in realtime modules
1275-
objects/rtemc/tp/ruckig_wrapper.o : emc/tp/ruckig_wrapper.cc
1273+
# Rules for cruckig C files in realtime modules
1274+
objects/rtemc/tp/cruckig/%.o : emc/tp/cruckig/%.c
12761275
$(ECHO) Compiling realtime $<
12771276
@rm -f $@
12781277
@mkdir -p $(dir $@)
1279-
$(Q)$(CXX) -c $(OPT) $(DEBUG) $(EXTRA_DEBUG) -DRTAPI -std=c++20 \
1280-
-I$(BASEPWD)/emc/tp/ruckig/include \
1281-
$(RUCKIG_CXXFLAGS) \
1282-
-MP -MD -MF "${@:.o=.d}" -MT "$@" \
1283-
$< -o $@
1284-
1285-
# Rules for C++ .cpp files in realtime modules
1286-
objects/rtemc/tp/ruckig/src/ruckig/%.o : emc/tp/ruckig/src/ruckig/%.cpp
1287-
$(ECHO) Compiling realtime $<
1288-
@rm -f $@
1289-
@mkdir -p $(dir $@)
1290-
$(Q)$(CXX) -c $(OPT) $(DEBUG) $(EXTRA_DEBUG) -DRTAPI -std=c++20 \
1291-
-I$(BASEPWD)/emc/tp/ruckig/include \
1292-
$(RUCKIG_CXXFLAGS) \
1278+
$(Q)$(CC) -c $(OPT) $(DEBUG) $(EXTRA_DEBUG) -DRTAPI \
1279+
$(EXTRA_CFLAGS) \
12931280
-MP -MD -MF "${@:.o=.d}" -MT "$@" \
12941281
$< -o $@
12951282
endif

src/emc/motion-logger/Submakefile

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,31 @@ MOTION_LOGGER_SRCS := \
55
emc/motion/axis.c \
66
emc/motion/simple_tp.c \
77
emc/tp/sp_scurve.c \
8-
emc/tp/ruckig_wrapper.cc
8+
emc/tp/ruckig_wrapper.c
99

10-
RUCKIG_SRCS := \
11-
emc/tp/ruckig/src/ruckig/brake.cpp \
12-
emc/tp/ruckig/src/ruckig/position_first_step1.cpp \
13-
emc/tp/ruckig/src/ruckig/position_first_step2.cpp \
14-
emc/tp/ruckig/src/ruckig/position_second_step1.cpp \
15-
emc/tp/ruckig/src/ruckig/position_second_step2.cpp \
16-
emc/tp/ruckig/src/ruckig/position_third_step1.cpp \
17-
emc/tp/ruckig/src/ruckig/position_third_step2.cpp \
18-
emc/tp/ruckig/src/ruckig/velocity_second_step1.cpp \
19-
emc/tp/ruckig/src/ruckig/velocity_second_step2.cpp \
20-
emc/tp/ruckig/src/ruckig/velocity_third_step1.cpp \
21-
emc/tp/ruckig/src/ruckig/velocity_third_step2.cpp
10+
CRUCKIG_SRCS := \
11+
emc/tp/cruckig/block.c \
12+
emc/tp/cruckig/brake.c \
13+
emc/tp/cruckig/calculator.c \
14+
emc/tp/cruckig/cruckig.c \
15+
emc/tp/cruckig/input_parameter.c \
16+
emc/tp/cruckig/output_parameter.c \
17+
emc/tp/cruckig/profile.c \
18+
emc/tp/cruckig/roots.c \
19+
emc/tp/cruckig/trajectory.c \
20+
emc/tp/cruckig/position_first_step1.c \
21+
emc/tp/cruckig/position_first_step2.c \
22+
emc/tp/cruckig/position_second_step1.c \
23+
emc/tp/cruckig/position_second_step2.c \
24+
emc/tp/cruckig/position_third_step1.c \
25+
emc/tp/cruckig/position_third_step2.c \
26+
emc/tp/cruckig/velocity_second_step1.c \
27+
emc/tp/cruckig/velocity_second_step2.c \
28+
emc/tp/cruckig/velocity_third_step1.c \
29+
emc/tp/cruckig/velocity_third_step2.c
2230

23-
USERSRCS += $(MOTION_LOGGER_SRCS) $(RUCKIG_SRCS)
31+
USERSRCS += $(MOTION_LOGGER_SRCS) $(CRUCKIG_SRCS)
2432

25-
../bin/motion-logger: $(call TOOBJS, $(MOTION_LOGGER_SRCS) $(RUCKIG_SRCS)) ../lib/libnml.so.0 ../lib/liblinuxcnchal.so.0
33+
../bin/motion-logger: $(call TOOBJS, $(MOTION_LOGGER_SRCS) $(CRUCKIG_SRCS)) ../lib/libnml.so.0 ../lib/liblinuxcnchal.so.0
2634
$(ECHO) Linking $(notdir $@)
27-
$(Q)$(CXX) $(LDFLAGS) -o $@ $^ -lm
35+
$(Q)$(CC) $(LDFLAGS) -o $@ $^ -lm
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
MIT License
22

3+
cruckig - Pure C99 port of the Ruckig trajectory generation library
4+
Copyright (c) 2025 Yang Yang (mika-net@outlook.com)
5+
6+
Based on Ruckig (https://github.com/pantor/ruckig)
37
Copyright (c) 2021 Lars Berscheid
48

59
Permission is hereby granted, free of charge, to any person obtaining a copy

src/emc/tp/cruckig/block.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include "cruckig_compat.h"
2+
3+
#include "block.h"
4+
5+
static inline double cruckig_profile_total_duration(const CRuckigProfile *p) {
6+
return p->t_sum[6] + p->brake.duration + p->accel.duration;
7+
}
8+
9+
static void remove_profile(CRuckigProfile *valid_profiles, size_t *valid_profile_counter, size_t index) {
10+
for (size_t i = index; i < *valid_profile_counter - 1; ++i) {
11+
valid_profiles[i] = valid_profiles[i + 1];
12+
}
13+
*valid_profile_counter -= 1;
14+
}
15+
16+
static void interval_from_profiles(CRuckigInterval *iv, const CRuckigProfile *profile_left, const CRuckigProfile *profile_right) {
17+
const double left_duration = cruckig_profile_total_duration(profile_left);
18+
const double right_duration = cruckig_profile_total_duration(profile_right);
19+
if (left_duration < right_duration) {
20+
iv->left = left_duration;
21+
iv->right = right_duration;
22+
iv->profile = *profile_right;
23+
} else {
24+
iv->left = right_duration;
25+
iv->right = left_duration;
26+
iv->profile = *profile_left;
27+
}
28+
iv->valid = true;
29+
}
30+
31+
void cruckig_block_init(CRuckigBlock *block) {
32+
cruckig_profile_init(&block->p_min);
33+
block->t_min = 0.0;
34+
block->a.valid = false;
35+
block->b.valid = false;
36+
}
37+
38+
void cruckig_block_set_min_profile(CRuckigBlock *block, const CRuckigProfile *profile) {
39+
block->p_min = *profile;
40+
block->t_min = cruckig_profile_total_duration(profile);
41+
block->a.valid = false;
42+
block->b.valid = false;
43+
}
44+
45+
bool cruckig_block_calculate(CRuckigBlock *block, CRuckigProfile *valid_profiles,
46+
size_t valid_profile_counter, size_t max_profiles) {
47+
(void)max_profiles;
48+
49+
if (valid_profile_counter == 1) {
50+
cruckig_block_set_min_profile(block, &valid_profiles[0]);
51+
return true;
52+
53+
} else if (valid_profile_counter == 2) {
54+
if (fabs(valid_profiles[0].t_sum[6] - valid_profiles[1].t_sum[6]) < 8 * DBL_EPSILON) {
55+
cruckig_block_set_min_profile(block, &valid_profiles[0]);
56+
return true;
57+
}
58+
59+
/* numerical_robust = true */
60+
{
61+
const size_t idx_min = (valid_profiles[0].t_sum[6] < valid_profiles[1].t_sum[6]) ? 0 : 1;
62+
const size_t idx_else_1 = (idx_min + 1) % 2;
63+
64+
cruckig_block_set_min_profile(block, &valid_profiles[idx_min]);
65+
interval_from_profiles(&block->a, &valid_profiles[idx_min], &valid_profiles[idx_else_1]);
66+
return true;
67+
}
68+
69+
/* Only happens due to numerical issues */
70+
} else if (valid_profile_counter == 4) {
71+
/* Find "identical" profiles */
72+
if (fabs(valid_profiles[0].t_sum[6] - valid_profiles[1].t_sum[6]) < 32 * DBL_EPSILON && valid_profiles[0].direction != valid_profiles[1].direction) {
73+
remove_profile(valid_profiles, &valid_profile_counter, 1);
74+
} else if (fabs(valid_profiles[2].t_sum[6] - valid_profiles[3].t_sum[6]) < 256 * DBL_EPSILON && valid_profiles[2].direction != valid_profiles[3].direction) {
75+
remove_profile(valid_profiles, &valid_profile_counter, 3);
76+
} else if (fabs(valid_profiles[0].t_sum[6] - valid_profiles[3].t_sum[6]) < 256 * DBL_EPSILON && valid_profiles[0].direction != valid_profiles[3].direction) {
77+
remove_profile(valid_profiles, &valid_profile_counter, 3);
78+
} else {
79+
return false;
80+
}
81+
82+
} else if (valid_profile_counter % 2 == 0) {
83+
return false;
84+
}
85+
86+
/* Find index of fastest profile */
87+
size_t idx_min = 0;
88+
for (size_t i = 1; i < valid_profile_counter; ++i) {
89+
if (valid_profiles[i].t_sum[6] < valid_profiles[idx_min].t_sum[6]) {
90+
idx_min = i;
91+
}
92+
}
93+
94+
cruckig_block_set_min_profile(block, &valid_profiles[idx_min]);
95+
96+
if (valid_profile_counter == 3) {
97+
const size_t idx_else_1 = (idx_min + 1) % 3;
98+
const size_t idx_else_2 = (idx_min + 2) % 3;
99+
100+
interval_from_profiles(&block->a, &valid_profiles[idx_else_1], &valid_profiles[idx_else_2]);
101+
return true;
102+
103+
} else if (valid_profile_counter == 5) {
104+
const size_t idx_else_1 = (idx_min + 1) % 5;
105+
const size_t idx_else_2 = (idx_min + 2) % 5;
106+
const size_t idx_else_3 = (idx_min + 3) % 5;
107+
const size_t idx_else_4 = (idx_min + 4) % 5;
108+
109+
if (valid_profiles[idx_else_1].direction == valid_profiles[idx_else_2].direction) {
110+
interval_from_profiles(&block->a, &valid_profiles[idx_else_1], &valid_profiles[idx_else_2]);
111+
interval_from_profiles(&block->b, &valid_profiles[idx_else_3], &valid_profiles[idx_else_4]);
112+
} else {
113+
interval_from_profiles(&block->a, &valid_profiles[idx_else_1], &valid_profiles[idx_else_4]);
114+
interval_from_profiles(&block->b, &valid_profiles[idx_else_2], &valid_profiles[idx_else_3]);
115+
}
116+
return true;
117+
}
118+
119+
return false;
120+
}
121+
122+
/* cruckig_block_is_blocked is now inlined in block.h */
123+
124+
const CRuckigProfile* cruckig_block_get_profile(const CRuckigBlock *block, double t) {
125+
if (block->b.valid && t >= block->b.right) {
126+
return &block->b.profile;
127+
}
128+
if (block->a.valid && t >= block->a.right) {
129+
return &block->a.profile;
130+
}
131+
return &block->p_min;
132+
}

src/emc/tp/cruckig/block.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef CRUCKIG_BLOCK_H
2+
#define CRUCKIG_BLOCK_H
3+
4+
#include "cruckig_compat.h"
5+
#include "profile.h"
6+
#include "cruckig_config.h"
7+
8+
typedef struct {
9+
double left, right;
10+
CRuckigProfile profile;
11+
bool valid;
12+
} CRuckigInterval;
13+
14+
typedef struct {
15+
CRuckigProfile p_min;
16+
double t_min;
17+
CRuckigInterval a;
18+
CRuckigInterval b;
19+
} CRuckigBlock;
20+
21+
void cruckig_block_init(CRuckigBlock *block);
22+
void cruckig_block_set_min_profile(CRuckigBlock *block, const CRuckigProfile *profile);
23+
24+
/* Calculate block from valid profiles. Returns true if successful. */
25+
bool cruckig_block_calculate(CRuckigBlock *block, CRuckigProfile *valid_profiles,
26+
size_t valid_profile_counter, size_t max_profiles);
27+
28+
/* Inlined for hot-path performance (called in tight synchronization loop) */
29+
CRUCKIG_FORCE_INLINE bool cruckig_block_is_blocked(const CRuckigBlock *block, double t) {
30+
return (t < block->t_min)
31+
|| (block->a.valid && block->a.left < t && t < block->a.right)
32+
|| (block->b.valid && block->b.left < t && t < block->b.right);
33+
}
34+
35+
const CRuckigProfile* cruckig_block_get_profile(const CRuckigBlock *block, double t);
36+
37+
#endif /* CRUCKIG_BLOCK_H */

0 commit comments

Comments
 (0)