Skip to content

Commit 6a8db94

Browse files
author
shakuevda
committed
add pitch
1 parent bfa4d0f commit 6a8db94

File tree

2 files changed

+146
-22
lines changed

2 files changed

+146
-22
lines changed

src/stingray_core_control/stingray_core_control/controllers.py

Lines changed: 118 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def update(
186186
if self.debug_hook is not None:
187187
self.debug_hook({
188188
"err_position": err_position,
189-
"output_pi": 57.3 *measurement_rate,
189+
"output_pi": output_pi,
190190
"feedback_speed": feedback_speed,
191191
"measurement_rate": 57.3 *measurement_rate,
192192
"out": out,
@@ -195,33 +195,132 @@ def update(
195195
return out
196196

197197
class PitchController(BaseController):
198-
def update(self, setpoint: float, measurement: float, measurement_rate: float, dt: float) -> float:
199-
# same structure as yaw but error normalized for angles
200-
err = normalize_angle_deg(setpoint - measurement)
201-
stage = err * self.K_1
202-
res_p = stage * self.K_p
203-
res_i = self.trapezoidal_integrate(stage * self.K_i, dt)
204-
output_pi = res_p + res_i
198+
def update(
199+
self,
200+
setpoint: float,
201+
measurement: float,
202+
measurement_rate: float,
203+
dt: float,
204+
flag_setup_feedback_speed: bool,
205+
param_update: dict | None = None
206+
) -> float:
207+
208+
if param_update:
209+
self.apply_params(**param_update)
210+
211+
dt = max(min(dt, 0.05), 1e-3)
212+
213+
# --- позиционный контур ---
214+
if flag_setup_feedback_speed:
215+
err_position = 0.0
216+
output_pi = 0.0
217+
setspeed = setpoint
218+
else:
219+
err_position = normalize_angle_deg(setpoint - measurement)
220+
stage = err_position * self.K_1
221+
res_p = stage * self.K_p
222+
res_i = self.trapezoidal_integrate(stage * self.K_i, dt)
223+
output_pi = res_p + res_i
224+
setspeed = 0.0
225+
226+
# --- ОС по скорости ---
205227
ap = self.aperiodic_step(measurement_rate, dt)
206228
feedback_speed = ap * self.K_2
207-
out = output_pi - feedback_speed
229+
230+
error_speed = output_pi + setspeed - feedback_speed
231+
208232
if self.out_sat is not None:
209-
out = saturation(out, self.out_sat, -self.out_sat)
233+
out = saturation(error_speed, self.out_sat, -self.out_sat)
234+
else:
235+
out = error_speed
236+
237+
# --- DEBUG ---
238+
if self.debug_hook is not None:
239+
self.debug_hook({
240+
"err_position": err_position,
241+
"output_pi": output_pi,
242+
"measurement_rate": measurement_rate,
243+
"feedback_speed": feedback_speed,
244+
"error_speed": error_speed,
245+
"out": out,
246+
})
247+
210248
return out
211249

212250
class RollController(BaseController):
213-
def update(self, setpoint: float, measurement: float, measurement_rate: float, dt: float) -> float:
214-
# same as pitch
215-
err = normalize_angle_deg(setpoint - measurement)
216-
stage = err * self.K_1
217-
res_p = stage * self.K_p
218-
res_i = self.trapezoidal_integrate(stage * self.K_i, dt)
219-
output_pi = res_p + res_i
251+
def __init__(
252+
self,
253+
*args,
254+
grav_bias: float = 0.0,
255+
grav_gain: float = 0.0,
256+
grav_offset_deg: float = 0.0,
257+
**kwargs
258+
):
259+
super().__init__(*args, **kwargs)
260+
self.grav_bias = grav_bias
261+
self.grav_gain = grav_gain
262+
self.grav_offset_deg = grav_offset_deg
263+
264+
def update(
265+
self,
266+
setpoint: float,
267+
measurement: float,
268+
measurement_rate: float,
269+
dt: float,
270+
flag_setup_feedback_speed: bool,
271+
param_update: dict | None = None
272+
) -> float:
273+
274+
if param_update:
275+
self.apply_params(**param_update)
276+
277+
dt = max(min(dt, 0.05), 1e-3)
278+
279+
# -------- режим настройки скорости --------
280+
if flag_setup_feedback_speed:
281+
output_pi = 0.0
282+
err_position = 0.0
283+
setspeed = setpoint
284+
else:
285+
# -------- позиционный контур --------
286+
err_position = normalize_angle_deg(setpoint - measurement)
287+
stage = err_position * self.K_1
288+
res_p = stage * self.K_p
289+
res_i = self.trapezoidal_integrate(stage * self.K_i, dt)
290+
output_pi = res_p + res_i
291+
setspeed = 0.0
292+
293+
# -------- гравитационная компенсация --------
294+
grav = (
295+
self.grav_bias
296+
+ math.sin(math.radians(measurement - self.grav_offset_deg))
297+
* self.grav_gain
298+
)
299+
300+
# -------- ОС по скорости --------
220301
ap = self.aperiodic_step(measurement_rate, dt)
221302
feedback_speed = ap * self.K_2
222-
out = output_pi - feedback_speed
303+
304+
# -------- итог --------
305+
error_speed = output_pi + grav + setspeed - feedback_speed
306+
223307
if self.out_sat is not None:
224-
out = saturation(out, self.out_sat, -self.out_sat)
308+
out = saturation(error_speed, self.out_sat, -self.out_sat)
309+
else:
310+
out = error_speed
311+
312+
if self.debug_hook is not None:
313+
self.debug_hook({
314+
"err_position": err_position,
315+
"output_pi": output_pi,
316+
"measurement_rate": measurement_rate,
317+
"feedback_speed": feedback_speed,
318+
"grav": grav,
319+
"error_speed": error_speed,
320+
"out": out,
321+
})
322+
323+
225324
return out
226325

227326
# -----------------------

src/stingray_core_control/stingray_core_control/stingray_core_control_node.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,18 @@ def __init__(self):
223223
ap_T=self.controllers['heave'].ap_T
224224
)
225225

226-
# self.pitch_ctrl = PitchController(Kp=1.0, K_stage=1.0, out_sat=100.0, ap_K=1.0, ap_T=0.1)
226+
self.pitch_ctrl = PitchController(
227+
K_p=self.controllers['heave'].K_p,
228+
K_1=self.controllers['heave'].K_1,
229+
K_2=self.controllers['heave'].K_2,
230+
K_i=self.controllers['heave'].K_i,
231+
I_max=self.controllers['heave'].I_max,
232+
I_min=self.controllers['heave'].I_min,
233+
out_sat=self.controllers['heave'].out_sat,
234+
ap_K=self.controllers['heave'].ap_K,
235+
ap_T=self.controllers['heave'].ap_T
236+
)
237+
227238
# self.roll_ctrl = RollController(Kp=1.0, K_stage=1.0, out_sat=100.0, ap_K=1.0, ap_T=0.1)
228239
# self.surge_ctrl = SurgeController(Kp=1.0, out_sat=100.0)
229240
# self.sway_ctrl = SwayController(Kp=1.0, out_sat=100.0)
@@ -392,11 +403,25 @@ def compute_heave(self):
392403

393404
def compute_roll(self):
394405
dt = self.last_dt
395-
return self.roll_ctrl.update(self.impact_roll, self.imu_roll, self.imu_rate_x, dt)
406+
# return self.roll_ctrl.update(self.impact_roll, self.imu_roll, self.imu_rate_x, dt)
396407

397408
def compute_pitch(self):
398409
dt = self.last_dt
399-
return self.pitch_ctrl.update(self.impact_pitch, self.imu_pitch, self.imu_rate_y, dt)
410+
return self.pitch_ctrl.update(
411+
self.impact_pitch,
412+
self.imu_pitch,
413+
self.imu_rate_y,
414+
dt,
415+
self.flag_setup_feedback_speed,
416+
param_update={
417+
"K_p": self.controllers["pitch"].K_p,
418+
"K_i": self.controllers["pitch"].K_i,
419+
"K_1": self.controllers["pitch"].K_1,
420+
"K_2": self.controllers["pitch"].K_2,
421+
"ap_T": self.controllers["pitch"].ap_T,
422+
"ap_K": self.controllers["pitch"].ap_K,
423+
"out_sat": self.controllers["pitch"].out_sat,
424+
})
400425

401426
def compute_yaw(self):
402427
dt = self.last_dt

0 commit comments

Comments
 (0)