A Flight Control System to move icon in World Map

Hello all,
I am trying to make a flight control system in node red. The description of the project/simulation is as follows:

  • Inject nodes to show or update the position of UAV in the Map
  • A Speed Slider which when the speed is increased will make the UAV move in the map in any direction (for e.g. N,S,E,W)
  • Buttons to turn the UAV in any direction as above
  • When pressing the button it would also rotate the UAV marker/icon in that direction
    I am confused as to how I can start this project/simulation. Any help or ideas would be appreciated by the forum. My current flow is below:
[
    {
        "id": "594f4d4bfd9f7699",
        "type": "tab",
        "label": "Flight_Control_SIMULU",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "319ff3a15befbaa7",
        "type": "ui_worldmap",
        "z": "594f4d4bfd9f7699",
        "group": "b4ebae93d455bbc5",
        "order": 1,
        "width": 9,
        "height": 10,
        "name": "",
        "lat": "48.80",
        "lon": "13.50",
        "zoom": "",
        "layer": "OSMC",
        "cluster": "0",
        "maxage": "",
        "usermenu": "hide",
        "layers": "hide",
        "panit": "true",
        "panlock": "false",
        "zoomlock": "false",
        "hiderightclick": "true",
        "coords": "deg",
        "showgrid": "false",
        "showruler": "false",
        "allowFileDrop": "false",
        "path": "/worldmap",
        "overlist": "DR,CO,RA,DN,AC,HM",
        "maplist": "OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS",
        "mapname": "",
        "mapurl": "",
        "mapopt": "",
        "mapwms": false,
        "x": 1100,
        "y": 40,
        "wires": []
    },
    {
        "id": "01732bfeeaa6afce",
        "type": "ui_text_input",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Initial Lat Position",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 2,
        "width": 6,
        "height": 1,
        "passthru": true,
        "mode": "number",
        "delay": "100",
        "topic": "lat",
        "sendOnBlur": true,
        "className": "",
        "topicType": "str",
        "x": 210,
        "y": 120,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "2aeed1b10c6c1515",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 3,
        "width": 2,
        "height": 1,
        "passthru": false,
        "label": "Set",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "set",
        "topicType": "str",
        "x": 90,
        "y": 200,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "bb2883299b8bc021",
        "type": "function",
        "z": "594f4d4bfd9f7699",
        "name": "function 1",
        "func": "var data1 = flow.get(\"data1\") || 0;\nvar data2 = flow.get(\"data2\") || 0;\nvar data3 = flow.get(\"data3\") || 0;\n//var data4 = flow.get(\"data4\") || {value:0,max:50,min:0};\n\nif(msg.topic == \"lat\"){\n    data1 = msg.payload;\n    flow.set(\"data1\", data1);\n    return msg;\n}\n\nif(msg.topic == \"lon\"){\n    data2 = msg.payload;\n    flow.set(\"data2\", data2);\n    return msg;\n}\n// Set Altitude\nif(msg.topic == \"alt\"){\n    data3 = msg.payload;\n    flow.set(\"data3\", data3);\n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"alt\": data3 + \"m\",\n        \"layer\": \"gps\"\n    }\n    return msg;\n}\n\n// Speed Calculation\nvar data_lat1 = data1 * Math.PI / 180;\nvar data_lon1 = data2 * Math.PI / 180;\nvar data_lat2 = 0;\nvar data_lon2 = 0;\nlet dlat = data_lat1 - data_lat2  ;\nlet dlon = data_lon1 - data_lon2;\nlet z = Math.pow(Math.sin(dlat / 2),2)\n        + Math.cos(data_lat1) * Math.cos(data_lat2)\n        * Math.pow(Math.sin(dlon / 2),2);\nlet c = 2 * Math.asin(Math.sqrt(z));\nlet r = 6371;\nlet distance = c * r;\nvar time = 3600;\nvar speed = distance / time;\n\n//Set Speed\nif(msg.topic == \"speed\"){\n    \n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"speed\": speed + \"kn\",\n        \"layer\": \"gps\"\n    }\n    return msg;\n}\n\n// Up Button Config\nif (msg.topic == \"up\") {\n    data1 = data1 + 1;\n    var speed_up = speed + 0.1;\n    var alt_up = data3 + 0.1\n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"lat\": data1,\n        \"layer\": \"gps\",\n        \"speed\": speed_up.toFixed(2) + \"kn\",\n        \"alt\": alt_up + \"m\"\n    }\n    node.warn(data1);\n}\n\n//Down Button Config\nif(msg.topic == \"down\"){\n    data1 = data1 - 1;\n    var speed_down = speed - 0.1;\n    var alt_down = data3 - 0.1;\n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"lat\": data1,\n        \"layer\": \"gps\",\n        \"speed\": speed_down.toFixed(2) + \"kn\",\n        \"alt\": alt_down + \"m\"\n    }\n}\n\n//Left Button Config\nif(msg.topic == \"left\"){\n    data2 = data2 - 1;\n    var speed_left = speed - 0.01;\n    var alt_left = data3 - 0.01;\n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"lon\": data2,\n        \"layer\": \"gps\",\n        \"speed\": speed_left.toFixed(2) + \"kn\",\n        \"alt\": alt_left + \"m\"\n    }\n}\n\n//Right Button Config\nif(msg.topic == \"right\"){\n    data2 = data2 + 1;\n    var speed_right = speed + 0.01;\n    var alt_right = data3 + 0.01;\n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"lon\": data2,\n        \"layer\": \"gps\",\n        \"speed\": speed_right.toFixed(2) + \"kn\",\n        \"alt\": alt_right + \"m\"\n    }\n}\n\n//Set Button Config\nif(msg.topic == \"set\"){\n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"lat\": data1,\n        \"lon\": data2,\n        \"alt\": data3 + \"m\",\n        \"speed\": speed.toFixed(2) + \"kn\",\n        \"icon\": \"plane\",\n        \"iconColor\": \"black\",\n        \"layer\": \"gps\",\n        \"popped\": true\n    }\n    \n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 580,
        "y": 140,
        "wires": [
            [
                "2cb3acd121995f56",
                "14927396080798d3",
                "0b8c558142c13b6e"
            ]
        ]
    },
    {
        "id": "0b8c558142c13b6e",
        "type": "debug",
        "z": "594f4d4bfd9f7699",
        "name": "debug 3",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 740,
        "y": 200,
        "wires": []
    },
    {
        "id": "2cb3acd121995f56",
        "type": "worldmap-tracks",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "depth": 20,
        "layer": "single",
        "smooth": false,
        "x": 870,
        "y": 40,
        "wires": [
            [
                "14927396080798d3"
            ]
        ]
    },
    {
        "id": "14927396080798d3",
        "type": "worldmap",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "lat": "48.80",
        "lon": "13.50",
        "zoom": "",
        "layer": "OSMC",
        "cluster": "",
        "maxage": "20",
        "usermenu": "show",
        "layers": "show",
        "panit": "true",
        "panlock": "false",
        "zoomlock": "false",
        "hiderightclick": "false",
        "coords": "deg",
        "showgrid": "false",
        "showruler": "false",
        "allowFileDrop": "false",
        "path": "/worldmap",
        "overlist": "DR,CO,RA,DN,AC,HM",
        "maplist": "OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS",
        "mapname": "",
        "mapurl": "",
        "mapopt": "",
        "mapwms": false,
        "x": 1100,
        "y": 200,
        "wires": []
    },
    {
        "id": "3f1eed7c26c68aa2",
        "type": "ui_text_input",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Initial Lon Position",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 4,
        "width": 6,
        "height": 1,
        "passthru": true,
        "mode": "number",
        "delay": "100",
        "topic": "lon",
        "sendOnBlur": true,
        "className": "",
        "topicType": "str",
        "x": 210,
        "y": 160,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "6c78defaf08106ad",
        "type": "ui_slider",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Altitude",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 6,
        "width": 6,
        "height": 1,
        "passthru": true,
        "outs": "end",
        "topic": "alt",
        "topicType": "str",
        "min": 0,
        "max": "100",
        "step": "0.1",
        "className": "",
        "x": 100,
        "y": 240,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "bf273c3b70b21055",
        "type": "function",
        "z": "594f4d4bfd9f7699",
        "name": "function 2",
        "func": "var data = flow.get(\"data\") || 0;\ndata = msg.payload;\nmsg.payload = msg.payload + global.data3;\nflow.set(\"data\", data);\n\nif(msg.topic == \"alt\"){\n    msg.payload = {\n        \"name\": \"SIMULU\",\n        \"alt\": data,\n        \"layer\": \"gps\"\n    }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 900,
        "y": 320,
        "wires": [
            [
                "14927396080798d3"
            ]
        ]
    },
    {
        "id": "bd958146f73af5c1",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 11,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "up",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "up",
        "topicType": "str",
        "x": 370,
        "y": 40,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "83cee2bda843d0d2",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 13,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "down",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "down",
        "topicType": "str",
        "x": 370,
        "y": 100,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "03aa2f6ba41795a5",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 15,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "left",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "left",
        "topicType": "str",
        "x": 370,
        "y": 220,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "7347a00f5de4aab0",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 17,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "right",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "right",
        "topicType": "str",
        "x": 370,
        "y": 260,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "d3bc3eb546aebf85",
        "type": "ui_slider",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Speed",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 8,
        "width": 6,
        "height": 1,
        "passthru": true,
        "outs": "all",
        "topic": "speed",
        "topicType": "str",
        "min": 0,
        "max": "50",
        "step": "0.5",
        "className": "",
        "x": 410,
        "y": 340,
        "wires": [
            [
                "bb2883299b8bc021"
            ]
        ]
    },
    {
        "id": "a333b7c63e423341",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 5,
        "width": 2,
        "height": 1
    },
    {
        "id": "b799d5f4abc85aea",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 7,
        "width": 2,
        "height": 1
    },
    {
        "id": "a8256bf1a70cbc10",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 9,
        "width": 2,
        "height": 1
    },
    {
        "id": "3efcf3a26cf4acb5",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 10,
        "width": 8,
        "height": 1
    },
    {
        "id": "7755f33ef2e05f46",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 12,
        "width": 2,
        "height": 1
    },
    {
        "id": "0ed7f978998ffa18",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 14,
        "width": 2,
        "height": 1
    },
    {
        "id": "db7de98bd68799e3",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 16,
        "width": 2,
        "height": 1
    },
    {
        "id": "39d7ca7a70f187c4",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 18,
        "width": 2,
        "height": 1
    },
    {
        "id": "87fe331c3fba3f22",
        "type": "ui_spacer",
        "z": "594f4d4bfd9f7699",
        "name": "spacer",
        "group": "b4ebae93d455bbc5",
        "order": 19,
        "width": 8,
        "height": 1
    },
    {
        "id": "b4ebae93d455bbc5",
        "type": "ui_group",
        "name": "UAV Flight Control",
        "tab": "37a720198b072daf",
        "order": 1,
        "disp": true,
        "width": 17,
        "collapse": false,
        "className": ""
    },
    {
        "id": "37a720198b072daf",
        "type": "ui_tab",
        "name": "Flight_Control",
        "icon": "dashboard",
        "order": 2,
        "disabled": false,
        "hidden": false
    }
]
1 Like

As a start, you need to do some research on converting speed and distance into Latitude/Longitude updates from the existing position.

I found out how to calculate next lat/lon points from distance, bearing and speed. Now the question is, is it possible to show a dynamic movement/slow movement of marker towards the next lat/lon point? If yes, then can I use the inject node for this purpose to show that the marker/icon is moving towards that point?
Also, if I want to change the direction of the icon while moving to that point using button, how would the flow look like?

sure, write a flow that continually sends the new Lat/Lon values to the world map. You can point the marker by filling in the direction (read the Help tab for the node-red-contrib-web-worldmap node)

1 Like

Hello @zenofmud,
I can't make up the flow as to how I can send the next Lat/Lon to worldmap via function node and also I would want to use the inject node to send constant values to the worldmap for the market, is there any idea to that?

I was just playing around with a simple map and this flow should give you some ideas

[{"id":"a6f8a950.69aba","type":"worldmap","z":"a54015d0.bd34b8","name":"","lat":"","lon":"","zoom":"","layer":"OSMG","cluster":"","maxage":"","hiderightclick":"false","coords":"none","path":"worldmap2","overlist":"DR,CO,RA,DN,HM","maplist":"OSMG,OSMC,EsriC,EsriS,EsriT,EsriO,EsriDG,NatGeo,UKOS,OpTop","mapname":"","mapurl":"","mapopt":"","mapwms":false,"x":550,"y":120,"wires":[]},{"id":"14547e0d.18c07a","type":"inject","z":"a54015d0.bd34b8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"str","x":100,"y":120,"wires":[["14a1ce4b.c590fa"]]},{"id":"14a1ce4b.c590fa","type":"function","z":"a54015d0.bd34b8","name":"Add plane to map","func":"var thing = {\n    name:\"UAV\", \n    lat:51, \n    lon:-1.45,\n    heading: 0,\n    icon: \"plane\",\n    iconColor:\"darkred\",\n    extrainfo:\"lets fly\"\n};\nmsg.payload = thing;\nflow.set(\"location\", thing)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":120,"wires":[["a6f8a950.69aba","c97d7e0e1cb1bb42"]]},{"id":"cb7979a1.3dec98","type":"comment","z":"a54015d0.bd34b8","name":"Simple map - click inject to send point to map.","info":"Adds a map at http://(your-server-ip):1880/worldmap. \n\nThe `function` node creates an object with some basic properties required to add to a map.","x":230,"y":60,"wires":[]},{"id":"c97d7e0e1cb1bb42","type":"debug","z":"a54015d0.bd34b8","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":560,"y":180,"wires":[]},{"id":"35ae9e0591fd4ef1","type":"inject","z":"a54015d0.bd34b8","name":"","repeat":"","crontab":"","once":false,"topic":"","payload":"","payloadType":"str","x":110,"y":200,"wires":[["dfd3cb8f541df181"]]},{"id":"dfd3cb8f541df181","type":"function","z":"a54015d0.bd34b8","name":"move plane on map","func":"let empty_thing = {\n    name: \"\",\n    lat: 0,\n    lon: 0,\n    icon: \"\",\n    heading: 0,\n    speed: 0,\n    iconColor: \"\",\n    extrainfo: \"\"\n};\n\nlet thing = flow.get(\"location\") || empty_thing\n\nif (thing.heading == 0 ) {\n    thing.lat = thing.lat + .01\n//    thing.lon = thing.lon + .01\n}\n\nif (thing.heading > 0 && thing.heading < 90) {\n    thing.lat = thing.lat + .01\n    thing.lon = thing.lon + .01\n\n}\n\nif (thing.heading == 90) {\n    //thing.lat = thing.lat + .01\n    thing.lon = thing.lon + .01\n}\n\nif (thing.heading > 90 && thing.heading < 180) {\n    thing.lat = thing.lat - .01\n    thing.lon = thing.lon + .01\n}\n\nif (thing.heading == 180) {\n    thing.lat = thing.lat - .01\n//    thing.lon = thing.lon - .01\n}\n\nif (thing.heading > 180 && thing.heading < 270) {\n    thing.lat = thing.lat - .01\n    thing.lon = thing.lon - .01\n}\n\nif (thing.heading == 270) {\n    thing.lat = thing.lat + .01\n//    thing.lon = thing.lon - .01\n}\n\nif (thing.heading > 270 && thing.heading < 360) {\n    thing.lat = thing.lat + .01\n    thing.lon = thing.lon - .01\n}\n\nmsg.payload = thing;\nflow.set(\"location\", thing)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":200,"wires":[["a6f8a950.69aba","20a868c1617e37cb"]]},{"id":"a3fdd2a4bfb8671f","type":"inject","z":"a54015d0.bd34b8","name":"turn right","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"right","payloadType":"str","x":120,"y":260,"wires":[["a769cdb9fe89167c","a002b3e8e8efe1aa"]]},{"id":"a769cdb9fe89167c","type":"function","z":"a54015d0.bd34b8","name":"change direction of plane on map","func":"let empty_thing = {\n    name: \"\",\n    lat: 0,\n    lon: 0,\n    icon: \"\",\n    heading: 0,\n    speed: 0,\n    iconColor: \"\",\n    extrainfo: \"\"\n};\n\nlet thing = flow.get(\"location\") || empty_thing\nlet heading = thing.heading\n\nif (msg.payload == \"right\") {\n    if (heading > 359) { heading = 0}\n    heading = heading+5\n} \n\n if (msg.payload == \"left\") {\n    if (heading < 1) { heading = 360 }\n    heading = heading - 5\n}\nthing.heading = heading\n\nmsg.payload = thing;\nflow.set(\"location\", thing)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":280,"wires":[["a6f8a950.69aba","dce5e5b68ae42c2e"]]},{"id":"20a868c1617e37cb","type":"debug","z":"a54015d0.bd34b8","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":240,"wires":[]},{"id":"dce5e5b68ae42c2e","type":"debug","z":"a54015d0.bd34b8","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":340,"wires":[]},{"id":"59883c41e3fb3e8d","type":"inject","z":"a54015d0.bd34b8","name":"turn left","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"left","payloadType":"str","x":110,"y":300,"wires":[["a769cdb9fe89167c","a002b3e8e8efe1aa"]]},{"id":"a002b3e8e8efe1aa","type":"debug","z":"a54015d0.bd34b8","name":"debug 4","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":320,"y":360,"wires":[]}]

Try simplifying your work

Hello @zenofmud ,
I played around with your flow and it gave me some ideas. I have created a joystick type buttons that make the UAV/plane turn in the direction listed up,down,right, or left. But I want to add a functionality where if I press any of the button it should also move in that direction not just turn, any idea how to go about that?
My current flow is as below:

[
    {
        "id": "01732bfeeaa6afce",
        "type": "ui_text_input",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Initial Lat Position",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 2,
        "width": 6,
        "height": 1,
        "passthru": true,
        "mode": "number",
        "delay": "100",
        "topic": "lat",
        "sendOnBlur": true,
        "className": "",
        "topicType": "str",
        "x": 230,
        "y": 420,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "2aeed1b10c6c1515",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 3,
        "width": 2,
        "height": 1,
        "passthru": false,
        "label": "Set",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "set",
        "topicType": "str",
        "x": 390,
        "y": 580,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "2cb3acd121995f56",
        "type": "worldmap-tracks",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "depth": 20,
        "layer": "single",
        "smooth": false,
        "x": 790,
        "y": 400,
        "wires": [
            [
                "14927396080798d3"
            ]
        ]
    },
    {
        "id": "14927396080798d3",
        "type": "worldmap",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "lat": "48.80",
        "lon": "13.50",
        "zoom": "",
        "layer": "OSMC",
        "cluster": "",
        "maxage": "20",
        "usermenu": "show",
        "layers": "show",
        "panit": "true",
        "panlock": "false",
        "zoomlock": "false",
        "hiderightclick": "false",
        "coords": "deg",
        "showgrid": "false",
        "showruler": "false",
        "allowFileDrop": "false",
        "path": "/worldmap",
        "overlist": "DR,CO,RA,DN,AC,HM",
        "maplist": "OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS",
        "mapname": "",
        "mapurl": "",
        "mapopt": "",
        "mapwms": false,
        "x": 1020,
        "y": 460,
        "wires": []
    },
    {
        "id": "3f1eed7c26c68aa2",
        "type": "ui_text_input",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Initial Lon Position",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 4,
        "width": 6,
        "height": 1,
        "passthru": true,
        "mode": "number",
        "delay": "100",
        "topic": "lon",
        "sendOnBlur": true,
        "className": "",
        "topicType": "str",
        "x": 230,
        "y": 460,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "bd958146f73af5c1",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 11,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "up",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "up",
        "topicType": "str",
        "x": 210,
        "y": 340,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "83cee2bda843d0d2",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 13,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "down",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "down",
        "topicType": "str",
        "x": 190,
        "y": 520,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "03aa2f6ba41795a5",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 15,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "left",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "left",
        "topicType": "str",
        "x": 190,
        "y": 560,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "7347a00f5de4aab0",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 17,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "right",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "right",
        "topicType": "str",
        "x": 210,
        "y": 380,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "fa8d16f8a3e226de",
        "type": "function",
        "z": "594f4d4bfd9f7699",
        "name": "function 3",
        "func": "var R = 6378.1; // Radius of Earth\nvar dist = 100; // Distance in meters\nvar theta = (dist / R) * 2 * Math.PI; // Angular distance in radians\nvar speed = 0;\n\nvar lat1 = 0.0;\nvar lon1 = 0.0;\n\nvar lat2 = flow.get(\"lat2\") || 0;\nvar lon2 = flow.get(\"lon2\") || 0;\n\nif(msg.topic == \"lat\"){\n    lat2 = msg.payload; \n    flow.set(\"lat2\", lat2);\n    return msg;\n}\n\nif(msg.topic == \"lon\"){\n    lon2 = msg.payload ;\n    flow.set(\"lon2\", lon2);\n    return msg;\n}\n\nvar y = Math.sin(lon2 - lon1) * Math.cos(lat2);\nvar x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(lon2-lon1);\nvar angle = Math.atan2(y, x);\nvar brng = (angle*180/Math.PI + 360) % 360; // in degrees\n\nif(msg.topic == \"set\"){\n    var set_it = {\n        name:\"SIMULU\",\n        lat: lat2,\n        lon: lon2,\n        icon: \"plane\",\n        iconColor: \"black\",\n        layer: \"gps\",\n        bearing: brng,\n        speed: speed + \"kn\",\n        popped: true\n    }\n    msg.payload = set_it;\n    return msg;\n}\n\nvar lat3 = Math.asin(Math.sin(lat1) * Math.cos(theta) +\n            Math.cos(lat1) * Math.sin(theta) * Math.cos(brng));\n\nvar lon3 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(theta)* Math.cos(lat1),\n            Math.cos(theta) - Math.sin(lat1) * Math.sin(lat3))\n\nvar lat3_deg = lat3 * 180 / Math.PI;\nvar lon3_deg = lon3 * 180 / Math.PI;\n\nlet thing = flow.get(\"location\") || set_it;\nlet heading = thing.heading;\n\nif(msg.topic == \"up\"){\n    if(heading = 0){\n        heading = 0;\n    }\n    var up = {\n        name:\"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = up;\n    return msg;\n}\n\nif(msg.topic==\"right\"){\n    if(heading >= 0 || heading < 90){\n        heading = 90;\n    }\n    var right = {\n        name:\"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = right;\n    return msg;\n}\n\nif(msg.topic == \"down\"){\n    if(heading > 90 || heading < 270){\n        heading = 180;\n    }\n    var down = {\n        name: \"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = down;\n    return msg;\n}\n\nif(msg.topic==\"left\"){\n    if(heading > 180 || heading < 360 ){\n        heading = 270;\n    }\n    var left = {\n        name:\"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = left;\n    return msg;\n}\n\nthing.heading = heading;\nflow.set(\"location\", thing);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 560,
        "y": 420,
        "wires": [
            [
                "9336120dc02d8212",
                "2cb3acd121995f56",
                "14927396080798d3"
            ]
        ]
    },
    {
        "id": "9336120dc02d8212",
        "type": "debug",
        "z": "594f4d4bfd9f7699",
        "name": "debug 4",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 880,
        "y": 580,
        "wires": []
    },
    {
        "id": "b4ebae93d455bbc5",
        "type": "ui_group",
        "name": "UAV Flight Control",
        "tab": "37a720198b072daf",
        "order": 1,
        "disp": true,
        "width": "17",
        "collapse": false,
        "className": ""
    },
    {
        "id": "37a720198b072daf",
        "type": "ui_tab",
        "name": "Flight_Control",
        "icon": "dashboard",
        "order": 2,
        "disabled": false,
        "hidden": false
    }
]

Well the first thing you have to do is fix your flow because when I use it I get an error
Screen Shot 2022-12-20 at 5.43.06 AM

Hi @zenofmud, I have tried everything to remove/fix the error but I cannot seem to fix it. Any suggestions?

Can you explain why you didn't tell me yesterday that the flow had an error?
Let me see what changes you made to try and fix the error - show me your current flow.
Is this a project for school by any chance?

Try adding node-warn() statements to the function node to examine data as it runs. You can read about node-warn() in th documentation. Writing Functions : Node-RED

It was working when I sent you the flow but I don't know why it did not worked at your side. Early this morning I also tried the flow and it give me the same error as you stated in the above replies. This is not a project for school by any chance, it is a research project. My current flow is as follows:

[
    {
        "id": "01732bfeeaa6afce",
        "type": "ui_text_input",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Initial Lat Position",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 2,
        "width": 6,
        "height": 1,
        "passthru": true,
        "mode": "number",
        "delay": "100",
        "topic": "lat",
        "sendOnBlur": true,
        "className": "",
        "topicType": "str",
        "x": 230,
        "y": 420,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "2aeed1b10c6c1515",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 3,
        "width": 2,
        "height": 1,
        "passthru": false,
        "label": "Set",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "set",
        "topicType": "str",
        "x": 390,
        "y": 580,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "2cb3acd121995f56",
        "type": "worldmap-tracks",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "depth": 20,
        "layer": "single",
        "smooth": false,
        "x": 790,
        "y": 400,
        "wires": [
            [
                "14927396080798d3"
            ]
        ]
    },
    {
        "id": "14927396080798d3",
        "type": "worldmap",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "lat": "48.80",
        "lon": "13.50",
        "zoom": "",
        "layer": "OSMC",
        "cluster": "",
        "maxage": "20",
        "usermenu": "show",
        "layers": "show",
        "panit": "true",
        "panlock": "false",
        "zoomlock": "false",
        "hiderightclick": "false",
        "coords": "deg",
        "showgrid": "false",
        "showruler": "false",
        "allowFileDrop": "false",
        "path": "/worldmap",
        "overlist": "DR,CO,RA,DN,AC,HM",
        "maplist": "OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS",
        "mapname": "",
        "mapurl": "",
        "mapopt": "",
        "mapwms": false,
        "x": 1020,
        "y": 460,
        "wires": []
    },
    {
        "id": "3f1eed7c26c68aa2",
        "type": "ui_text_input",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "label": "Initial Lon Position",
        "tooltip": "",
        "group": "b4ebae93d455bbc5",
        "order": 4,
        "width": 6,
        "height": 1,
        "passthru": true,
        "mode": "number",
        "delay": "100",
        "topic": "lon",
        "sendOnBlur": true,
        "className": "",
        "topicType": "str",
        "x": 230,
        "y": 460,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "bd958146f73af5c1",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 11,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "up",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "up",
        "topicType": "str",
        "x": 210,
        "y": 340,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "83cee2bda843d0d2",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 13,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "down",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "down",
        "topicType": "str",
        "x": 190,
        "y": 520,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "03aa2f6ba41795a5",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 15,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "left",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "left",
        "topicType": "str",
        "x": 190,
        "y": 560,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "7347a00f5de4aab0",
        "type": "ui_button",
        "z": "594f4d4bfd9f7699",
        "name": "",
        "group": "b4ebae93d455bbc5",
        "order": 17,
        "width": 6,
        "height": 1,
        "passthru": false,
        "label": "right",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "right",
        "topicType": "str",
        "x": 210,
        "y": 380,
        "wires": [
            [
                "fa8d16f8a3e226de"
            ]
        ]
    },
    {
        "id": "fa8d16f8a3e226de",
        "type": "function",
        "z": "594f4d4bfd9f7699",
        "name": "function 3",
        "func": "var R = 6378.1; // Radius of Earth\nvar dist = 100; // Distance in meters\nvar theta = (dist / R) * 2 * Math.PI; // Angular distance in radians\nvar speed = 0;\n\nvar lat1 = 0.0;\nvar lon1 = 0.0;\n\nvar lat2 = flow.get(\"lat2\") || 0;\nvar lon2 = flow.get(\"lon2\") || 0;\n\nif(msg.topic == \"lat\"){\n    lat2 = msg.payload; \n    flow.set(\"lat2\", lat2);\n    return msg;\n}\n\nif(msg.topic == \"lon\"){\n    lon2 = msg.payload ;\n    flow.set(\"lon2\", lon2);\n    return msg;\n}\n\nvar y = Math.sin(lon2 - lon1) * Math.cos(lat2);\nvar x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(lon2-lon1);\nvar angle = Math.atan2(y, x);\nvar brng = (angle*180/Math.PI + 360) % 360; // in degrees\n\nif(msg.topic == \"set\"){\n    var set_it = {\n        name:\"SIMULU\",\n        lat: lat2,\n        lon: lon2,\n        icon: \"plane\",\n        iconColor: \"black\",\n        layer: \"gps\",\n        bearing: brng,\n        speed: speed + \"kn\",\n        popped: true\n    }\n    msg.payload = set_it;\n    return msg;\n}\n\nvar lat3 = Math.asin(Math.sin(lat1) * Math.cos(theta) +\n            Math.cos(lat1) * Math.sin(theta) * Math.cos(brng));\n\nvar lon3 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(theta)* Math.cos(lat1),\n            Math.cos(theta) - Math.sin(lat1) * Math.sin(lat3))\n\nvar lat3_deg = lat3 * 180 / Math.PI;\nvar lon3_deg = lon3 * 180 / Math.PI;\n\nvar move = flow.get(\"location\") || brng;\nvar heading = move.heading; \nnode.warn(move);\n\nif(msg.topic == \"up\"){\n    if(heading = 0){\n        heading = 0;\n    }\n    var up = {\n        name:\"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = up;\n    return msg;\n}\n\nif(msg.topic==\"right\"){\n    if(heading >= 0 || heading < 90){\n        heading = 90;\n    }\n    var right = {\n        name:\"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = right;\n    return msg;\n}\n\nif(msg.topic == \"down\"){\n    if(heading > 90 || heading < 270){\n        heading = 180;\n    }\n    var down = {\n        name: \"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = down;\n    return msg;\n}\n\nif(msg.topic==\"left\"){\n    if(heading > 180 || heading < 360 ){\n        heading = 270;\n    }\n    var left = {\n        name:\"SIMULU\",\n        bearing:heading,\n        layer:\"gps\",\n        popped:true\n    }\n    msg.payload = left;\n    return msg;\n}\n\nmove.heading = heading;\nflow.set(\"location\", move);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 560,
        "y": 420,
        "wires": [
            [
                "9336120dc02d8212",
                "2cb3acd121995f56",
                "14927396080798d3"
            ]
        ]
    },
    {
        "id": "9336120dc02d8212",
        "type": "debug",
        "z": "594f4d4bfd9f7699",
        "name": "debug 4",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 880,
        "y": 580,
        "wires": []
    },
    {
        "id": "b4ebae93d455bbc5",
        "type": "ui_group",
        "name": "UAV Flight Control",
        "tab": "37a720198b072daf",
        "order": 1,
        "disp": true,
        "width": "17",
        "collapse": false,
        "className": ""
    },
    {
        "id": "37a720198b072daf",
        "type": "ui_tab",
        "name": "Flight_Control",
        "icon": "dashboard",
        "order": 2,
        "disabled": false,
        "hidden": false
    }
]

The error is removed but the other button like down,left and right give me an undefined value.

I have added the node.warn() statement in my flow.

When I run your latest flow the debug sidebar shows a message from debug 4

12/21/2022, 5:49:28 AM node: debug 4
down : msg.payload : Object
object
    name: "SIMULU"
    bearing: undefined
    layer: "gps"
    popped: true

in the function you set bearing to heading so where do you define heading?

Previously I defined heading like:

let heading = move.heading

and then:

bearing:heading

but it does not work.

I know the error is somewhere along these parts of the code:

if(msg.topic == "set"){
    var set_it = {
        name:"SIMULU",
        lat: lat2,
        lon: lon2,
        icon: "plane",
        iconColor: "black",
        layer: "gps",
        bearing: brng,
        speed: speed + "kn",
        popped: true
    }
    msg.payload = set_it;
    return msg;
}

and

var move = flow.get("location") || set_it;
var bearing = move.bearing; 
node.warn(move);

if(msg.topic == "up"){
    if(bearing = 0){
        bearing = 0;
    }
    var up = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    msg.payload = up;
    return msg;
}

if(msg.topic=="right"){
    if(bearing >= 0 || bearing < 90){
        bearing = 90;
    }
    var right = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    msg.payload = right;
    return msg;
}

if(msg.topic == "down"){
    if(bearing > 90 || bearing < 270){
        bearing = 180;
    }
    var down = {
        name: "SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    msg.payload = down;
    return msg;
}

if(msg.topic=="left"){
    if(bearing > 180 || bearing < 360 ){
        bearing = 270;
    }
    var left = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    msg.payload = left;
    return msg;
}

move.bearing = bearing;
flow.set("location", move);
return msg;

I would add a bunch of node.warn("debug ??") where ?? is a different number in each one, then run your flow so you can see what is happening in the code.

You could even add one to each if statement like node.warn("debug ?? - in UP test")

You can even display variables using something like node.warn("bearing=" + bearing)

I did this:

let move = flow.get("location") || 0 ;
let bearing = move.bearing; 

if(msg.topic == "up"){
    if(bearing = 0){
        bearing = 0;
    }
    var up = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing);
    msg.payload = up;
    return msg;
}

if(msg.topic=="right"){
    if(bearing >= 0 || bearing < 90){
        bearing = 90;
    }
    var right = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing)
    msg.payload = right;
    return msg;
}

if(msg.topic == "down"){
    if(bearing > 90 || bearing < 270){
        bearing = 180;
    }
    var down = {
        name: "SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing)
    msg.payload = down;
    return msg;
}

if(msg.topic=="left"){
    if(bearing > 180 || bearing < 360 ){
        bearing = 270;
    }
    var left = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing)
    msg.payload = left;
    return msg;
}

move.bearing = bearing;
flow.set("location", move);
return msg;

Screenshot from 2022-12-21 13-42-29

But still I do not understand why it is getting an undefined value? It was perfectly working yesterday without any errors and I even used your previous function code but today it just keeps giving errors.

Please provide the entire function node.

var R = 6378.1; // Radius of Earth
var dist = 100; // Distance in meters
var theta = (dist / R) * 2 * Math.PI; // Angular distance in radians
var speed = 0;

var lat1 = 0.0;
var lon1 = 0.0;

var lat2 = flow.get("lat2") || 0;
var lon2 = flow.get("lon2") || 0;

if(msg.topic == "lat"){
    lat2 = msg.payload; 
    flow.set("lat2", lat2);
    return msg;
}

if(msg.topic == "lon"){
    lon2 = msg.payload ;
    flow.set("lon2", lon2);
    return msg;
}

var y = Math.sin(lon2 - lon1) * Math.cos(lat2);
var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(lon2-lon1);
var angle = Math.atan2(y, x);
var brng = (angle*180/Math.PI + 360) % 360; // in degrees

if(msg.topic == "set"){
    var set_it = {
        name:"SIMULU",
        lat: lat2,
        lon: lon2,
        icon: "plane",
        iconColor: "black",
        layer: "gps",
        bearing: brng,
        speed: speed + "kn",
        popped: true
    }
    msg.payload = set_it;
    return msg;
}

var lat3 = Math.asin(Math.sin(lat1) * Math.cos(theta) +
            Math.cos(lat1) * Math.sin(theta) * Math.cos(brng));

var lon3 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(theta)* Math.cos(lat1),
            Math.cos(theta) - Math.sin(lat1) * Math.sin(lat3))

var lat3_deg = lat3 * 180 / Math.PI;
var lon3_deg = lon3 * 180 / Math.PI;

let move = flow.get("location") || 0 ;
let bearing = move.bearing; 

if(msg.topic == "up"){
    if(bearing = 0){
        bearing = 0;
    }
    var up = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing);
    msg.payload = up;
    return msg;
}

if(msg.topic=="right"){
    if(bearing >= 0 || bearing < 90){
        bearing = 90;
    }
    var right = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing)
    msg.payload = right;
    return msg;
}

if(msg.topic == "down"){
    if(bearing > 90 || bearing < 270){
        bearing = 180;
    }
    var down = {
        name: "SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing)
    msg.payload = down;
    return msg;
}

if(msg.topic=="left"){
    if(bearing > 180 || bearing < 360 ){
        bearing = 270;
    }
    var left = {
        name:"SIMULU",
        bearing:bearing,
        layer:"gps",
        popped:true
    }
    node.warn("bearing=" +bearing)
    msg.payload = left;
    return msg;
}

move.bearing = bearing;
flow.set("location", move);
return msg;

Here: if "location is not stored in the flow yet, the move will be 0

let move = flow.get("location") || 0;

Then if move is 0, you cant ask any property from it because 0 has no properties

let bearing = move.bearing;

Here you need to have double ==

if(bearing = 0){
    bearing = 0;
}

Like this

if(bearing == 0){
    bearing = 0;
}

But I cant find any reason to make such statement at all
if something is already what you want, why to declare it over??