From 7613a5b7cbbd3d9cf8661401fe1c6127cc27e315 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Thu, 9 Oct 2025 14:24:29 +0200 Subject: [PATCH] =?UTF-8?q?Seite=20RollPitch=20funktionsf=C3=A4hig=20gemac?= =?UTF-8?q?ht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graph.py | 21 ++++++ obp60v.conf-sample | 5 ++ pages/rollpitch.py | 162 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 graph.py diff --git a/graph.py b/graph.py new file mode 100644 index 0000000..e23d991 --- /dev/null +++ b/graph.py @@ -0,0 +1,21 @@ +""" +Generische Klasse zum Diagramme-Zeichnen +""" + +class Graph(): + + def __init__(self): + self.title = "Title" + self.subtitle = "Subtitle" + self.title_x = "Title X" + self.title_y = "Title Y" + self.has_arrows = False + + def paint(self, ctx): + """ + Output Graph to Cairo context + """ + pass + + def add_series(self): + pass diff --git a/obp60v.conf-sample b/obp60v.conf-sample index 4fc0deb..0ad6a85 100644 --- a/obp60v.conf-sample +++ b/obp60v.conf-sample @@ -90,6 +90,11 @@ wind_speed_format = ln temperature_format = C date_format = ISO +[hardware] +roll_limit = 25 +roll_offset = 0 +pitch_offset = 0 + [display] hold_values = off backlight_color = red diff --git a/pages/rollpitch.py b/pages/rollpitch.py index d9fac18..aaa76be 100644 --- a/pages/rollpitch.py +++ b/pages/rollpitch.py @@ -1,13 +1,161 @@ import cairo from .page import Page + +""" +ROLL - Roll - Krängen / Rotation in Querrichtung +PTCH - Pitch - Stampfen / Rotation in Längsrichtung +YAW - Gieren + +XDR-Daten + xdrRoll + xdrPitch + xdrYaw + + +Wenn Limit überschritten ist, Warnung ausgeben + +Idee: Zusätzlich die Kieldaten anzeigen wenn ein Sensor dafür vorhanden ist + +""" + +import math + class RollPitch(Page): - def draw(self, ctx): - # Name - ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) - ctx.set_font_size(60) - ctx.move_to(20, 100) - ctx.show_text("RollPitch") + def __init__(self, pageno, cfg, appdata, boatdata): + super().__init__(pageno, cfg, appdata, boatdata) - # Graph anzeigen X/Y + self.valref_r = self.bd.getRef("ROLL") + self.valref_p = self.bd.getRef("PTCH") + + # Werte aus Konfiguration + self.roll_limit = cfg['_config'].getint('hardware', 'roll_limit') + self.roll_offset = cfg['_config'].getint('hardware', 'roll_offset') + self.pitch_offset = cfg['_config'].getint('hardware', 'pitch_offset') + + def draw(self, ctx): + + # Horizontale Trennlinien + ctx.rectangle(0, 149, 60, 3) + ctx.rectangle(340, 149, 60, 3) + ctx.fill() + + # Links oben: Limit + ctx.select_font_face("DSEG7 Classic") + ctx.set_font_size(40) + ctx.move_to(8, 70) + ctx.show_text(str(self.roll_limit)) + + ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) + ctx.set_font_size(20) + ctx.move_to(8, 95) + ctx.show_text("Limit") + + ctx.set_font_size(16) + ctx.move_to(8, 115) + ctx.show_text("deg") + ctx.stroke() + + # Links unten: Roll-Wert + ctx.set_font_size(16) + ctx.move_to(8, 180) + ctx.show_text(self.valref_r.unit) + + ctx.set_font_size(20) + ctx.move_to(8, 205) + ctx.show_text("Roll") + + ctx.select_font_face("DSEG7 Classic") + ctx.set_font_size(40) + ctx.move_to(8, 260) + ctx.show_text(str(self.valref_r.format())) + ctx.stroke() + + # Rechts unten: Pitch-Wert + ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) + ctx.set_font_size(16) + self.draw_text_ralign(ctx, 392, 180, self.valref_p.unit) + + ctx.set_font_size(20) + self.draw_text_ralign(ctx, 392, 205, "Pitch") + + ctx.select_font_face("DSEG7 Classic") + ctx.set_font_size(40) + ctx.move_to(290, 260) + ctx.show_text(str(self.valref_p.format())) + ctx.stroke() + + # Kreis mit Skala oben +/- 60° + + cx = 200 + cy = 160 + r = 110 + ctx.set_line_width(3) + ctx.arc(cx, cy, r, 0, 2*math.pi) + ctx.stroke() + + # Skala mit Strichen, Punkten und Beschriftung + char = { + -60: "60", + -40: "40", + -20: "20", + 0: "0", + 20: "20", + 40: "40", + 60: "60" + } + ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD) + ctx.set_font_size(16) + for i in range(-60, 70, 10): + fx = math.sin(i / 180 * math.pi) + fy = math.cos(i / 180 * math.pi) + if i in char: + x = cx + (r + 15) * fx + y = cy - (r + 15) * fy + self.draw_text_center(ctx, x, y, char[i]) + ctx.stroke() + if i % 20 == 0: + ctx.move_to(cx + r * fx, cy - r * fy) + ctx.line_to(cx + (r - 10) * fx, cy - (r - 10) * fy) + ctx.stroke() + else: + x = cx + (r - 5) * fx + y = cy - (r - 5) * fy + ctx.arc(x, y, 2, 0, 2*math.pi) + ctx.fill() + + # Meßwert + if self.cfg['simulation']: + angle = 45 + else: + angle = self.valref_r.getValueRaw() or 0 + angle = 22 + + # Wasserlinie + ctx.set_line_width(4) + ctx.move_to(150, cy + 10) + ctx.line_to(250, cy + 10) + ctx.stroke() + + # Rotierte Komponenten + ctx.save() + ctx.translate(cx, cy) + ctx.rotate(math.radians(angle)) + # Rumpf + ctx.arc(0, - 10, 28, 0, math.pi) + ctx.fill() + # Mast + ctx.move_to(0, 0) + ctx.line_to(0, -1 * (r - 15)) + ctx.stroke() + # Kiel + ctx.move_to(-5, 0) + ctx.line_to(5 , 0) + ctx.line_to(2 , r - 60) + ctx.line_to(-2 , r - 60) + ctx.close_path() + ctx.arc(0, r -60, 5, 0, 2*math.pi) + ctx.fill() + + ctx.restore()