wellenvogel / avnav

using the raspberry pi as a nav computer
MIT License
87 stars 27 forks source link

Nav.wp.courseCorrection and/or userValues #299

Closed teesix closed 8 months ago

teesix commented 1 year ago

For solo sailing the displayed information should be simple, without the need for additional interpretation. BRG (nav.wp.course) and COG (nav.gps.course) can be summarized as the courseCorection needed to reach the coming waypoint: If BRG-COG >-180 the courseCorection equals BRG-COG, else it equals BRG-COG +360. Zero means on course to the comming waypoint. It would be nice to have a nav.wp.courseCorrection value entry in the app, to be displayed with the default widget. A more general solution would be to allow for userValues to be defined (calculated with server values) and registered, in a similar way as the formatters.

wellenvogel commented 1 year ago

This can easily be done with a couple of lines of js code in your user.js. https://wellenvogel.de/software/avnav/docs/hints/userjs.html?lang=en#h2:Widgets Just define a widget with the storeKeys you want, a translateFunction that sets the value property in its result computed from the storeKeys - and a formatter. This will use the default widget for display but it is completely in your hand (translateFunction) how the value is computed.

PietKnot commented 1 year ago

@teesix: i had the same wish and made 2 widgets to display this: one as simple value, the other one as one as radialGauge. The name was "WPD" = waypoint direction. If you like to see the implementation, email me at piet.knoop at gmail.com. I could also include it here in a code tag, up-to-you. Sometimes last your, you may find a closed issue from me with screenshots if i recall correctly.

teesix commented 1 year ago

Right…… I already read the documentation and had a look at the examples but I still couldn’t figure out how to manipulate the value in a widget. After some testing it became clear to me that the props object is not only about all the canvas gauge options but also refers to other elements in the widget, like value. Is code works, or is there a better way to do this?

var WpCourseCorrection = { name: "userWpCourseCorrection", unit: "°", caption: "Waypoint course correction", formatter: avnav.api.formatter.formatDirection, storeKeys:{ navGpsCourse: 'nav.gps.course', navWPCourse: 'nav.wp.course' },
translateFunction: function (props) { if (props.navWPCourse - props.navGpsCourse < -180) { props.value = props.navWPCourse - props.navGpsCourse + 360 ; } else if (props.navWPCourse - props.navGpsCourse > 180) { props.value = props.navWPCourse - props.navGpsCourse - 360 ; } else { props.value = props.navWPCourse - props.navGpsCourse ; } return props;
} }; avnav.api.registerWidget(WpCourseCorrection);

wellenvogel commented 1 year ago

Yes, should work this way. Most probably caption should be a bit shorter - this is the name in the display. Maybe some error handling if one of the courses is undefined...

PietKnot commented 1 year ago

My solution was:

/*
* WaypointDirection Widget
*/
var wpdWidget = {
    name: "userWPD",
    storeKeys: {
        courseValue: 'nav.wp.course',
        gpsValue: 'nav.gps.course',
        wpDistance: 'nav.wp.distance'
    },
    translateFunction: function (props) {
        var direction = props.courseValue - props.gpsValue;
        if (props.wpDistance == 0)  props.value = "---";
        else if (direction > 180)   props.value = direction - 360;
        else if (direction < -180)  props.value = direction + 360;
        else                        props.value = direction;
        return props;
    },
    caption: "WPD",
    unit: "°",
    formatter: avnav.api.formatter.formatDirection,
    className: "widget COG"
};
var wpdParameter={
    value: false,
    formatter: false,
    formatterParameters: false
};
avnav.api.registerWidget(wpdWidget,wpdParameter);

/*
* WaypointDirection Widget with radial gauge
*/
var wpdrgWidget = {
    name: "userWPDgauge",
        storeKeys: {
        courseValue: 'nav.wp.course',
        gpsValue: 'nav.gps.course',
    wpDistance: 'nav.wp.distance'
    },
    translateFunction: function (props) {
        var direction = props.courseValue - props.gpsValue;
        if (props.wpDistance == 0)  props.value = "---";
        else if (direction > 180)   props.value = direction - 360;
        else if (direction < -180)  props.value = direction + 360;
        else                        props.value = direction;
        return props;
    },
    caption: "WPD", 
    unit: "°",
    type: "radialGauge",
    width: 400,
    height: 300,
    minValue: -120,
    maxValue: 120,
    valueBox: false,
    ticksAngle: 240,
    startAngle: 60,
//  units: "°",
    majorTicks: [
        "-120","-90","-60","-30", 
        "0","30","60","90","120"
    ],
    minorTicks: 3,
    strokeTicks: true,
    highlights: [
        {"from": -120, "to":-105, "color": "rgba(200, 50, 50, .75)"}, //red
        {"from": 105, "to": 120, "color": "rgba(46, 184, 64, .75)"}   //green
    ],
    colorPlate: "#fff",
    borderShadowWidth: 0,
    borders: false,
    needleType: "arrow",
    needleWidth: 2,
    needleCircleSize: 7,
    needleCircleOuter: true,
    needleCircleInner: false
};
var wpdrgParameter={
    value: false,
    formatter: false,
    formatterParameters: false
};
avnav.api.registerWidget(wpdrgWidget,wpdrgParameter);

/*
* VMG Widget with radial gauge
*/
var vmgrgWidget = {
    name: "userVMGgauge",
    storeKeys: {vmgMsec: 'nav.wp.vmg'},
    translateFunction: function (props) {
        props.value = props.vmgMsec * 1.852;
        return props;
    },
    caption: "VMG", 
    unit: "Knts",
    type: "radialGauge",
    width: 400,
    height: 300,
    minValue: 0,
    maxValue: 8,
    valueBox: false,
    ticksAngle: 240,
    startAngle: 60,
    majorTicks: [
        "0","1","2","3", 
        "4","5","6","7","8"
    ],
    minorTicks: 2,
    strokeTicks: true,
    highlights: [ ],
    colorPlate: "#fff",
    borderShadowWidth: 0,
    borders: false,
    needleType: "arrow",
    needleWidth: 2,
    needleCircleSize: 7,
    needleCircleOuter: true,
    needleCircleInner: false
};
avnav.api.registerWidget(vmgrgWidget);

teesix commented 1 year ago

Ok, thanks! Issue solved.

wellenvogel commented 8 months ago

No further activity - so closing this.