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
}
]