From b0f576731f5a2fe9a6584df1f72a0cc2eb3a9865 Mon Sep 17 00:00:00 2001 From: Aden Chan <40689649+21chanas3@users.noreply.github.com> Date: Sat, 9 Mar 2024 05:50:10 -0800 Subject: [PATCH 1/6] added documentation --- controllers/drone_controller.go | 67 ++++ docs/docs.go | 624 +++++++++++++++++++++++++++++++- docs/swagger.json | 624 +++++++++++++++++++++++++++++++- docs/swagger.yaml | 423 +++++++++++++++++++++- 4 files changed, 1732 insertions(+), 6 deletions(-) diff --git a/controllers/drone_controller.go b/controllers/drone_controller.go index ca36232..4232e8f 100644 --- a/controllers/drone_controller.go +++ b/controllers/drone_controller.go @@ -36,6 +36,15 @@ func GetStatusHistory(c echo.Context) error { return c.JSON(http.StatusOK, c.Get("drone")) } +// Takeoff tells the drone to take off to a specific altitude +// +// @Summary Take off Drone +// @Description Tells Drone to takeoff +// @Tags Drone +// @Accept json +// @Param altitude body number true "Takeoff Altitude" +// @Success 200 +// @Router /drone/takeoff [post] func Takeoff(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) @@ -52,6 +61,14 @@ func Takeoff(c echo.Context) error { return c.HTML(http.StatusAccepted, "") } +// Land tells the drone to land +// +// @Summary Take off Drone +// @Description Tells Drone to land +// @Tags Drone +// @Success 200 body string "Command issued successfully" +// @Failure 500 body string "Command failed to be issued" +// @Router /drone/land [get] func Land(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) if mp.Land() { @@ -61,6 +78,14 @@ func Land(c echo.Context) error { } } +// RTL return to home waypoint and land +// +// @Summary Returns to Home and Lands +// @Description Tells Drone to return home and land +// @Tags Drone +// @Success 200 body string "RTL command issued successfully" +// @Failure 500 body string "RTL command encountered an error" +// @Router /drone/rtl [get] func RTL(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) if mp.ReturnHome() { @@ -70,6 +95,14 @@ func RTL(c echo.Context) error { } } +// Lock locks the drone +// +// @Summary Halts drone in place while preserving queue +// @Description Stops drone movement while preserving existing queue +// @Tags Drone +// @Success 200 body string "Drone locked successfully" +// @Failure 500 body string "Drone unable to lock (already locked?)" +// @Router /drone/lock [get] func Lock(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) if mp.Lock() { @@ -79,6 +112,14 @@ func Lock(c echo.Context) error { } } +// Unlock unlocks the drone +// +// @Summary Halts drone in place while preserving queue +// @Description Stops drone movement while preserving existing queue +// @Tags Drone +// @Success 200 body string "Drone unlocked successfully" +// @Failure 500 body string "Drone unable to unlock (already unlocked?)" +// @Router /drone/lock [get] func Unlock(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) if mp.Unlock() { @@ -88,12 +129,29 @@ func Unlock(c echo.Context) error { } } +// GetQueue obtains the current queue in MissionPlanner +// +// @Summary Returns queue in Mission Planner +// @Description Returns queue in Mission Planner +// @Tags Drone +// @Produce json +// @Success 200 {object} []models.Waypoint +// @Router /drone/queue [get] func GetQueue(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) var queue = mp.GetQueue() return c.JSON(http.StatusOK, queue) } +// PostQueue sends a queue to MissionPlanner +// +// @Summary Sends a queue in Mission Planner +// @Description Sends a queue in Mission Planner +// @Tags Drone +// @Accept json +// @Param waypoints body []models.Waypoint true "Array of Waypoint Data" +// @Success 200 +// @Router /drone/queue [post] func PostQueue(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) var queue []models.Waypoint @@ -118,6 +176,15 @@ func PostQueue(c echo.Context) error { } } +// PostHome updates the home waypoint +// +// @Summary Updates the home waypoint +// @Description Updates the home waypoint +// @Tags Drone +// @Accept json +// @Param waypoints body models.Waypoint true "Home Waypoint" +// @Success 200 +// @Router /drone/home [post] func PostHome(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) var wp models.Waypoint diff --git a/docs/docs.go b/docs/docs.go index c66f7f4..7cf8680 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -128,6 +128,521 @@ const docTemplate = `{ } } }, + "/drone/home": { + "post": { + "description": "Updates the home waypoint", + "consumes": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Updates the home waypoint", + "parameters": [ + { + "description": "Home Waypoint", + "name": "waypoints", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Waypoint" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/drone/land": { + "get": { + "description": "Tells Drone to land", + "tags": [ + "Drone" + ], + "summary": "Take off Drone", + "responses": { + "200": { + "description": "Command issued successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "Command failed to be issued", + "schema": { + "type": "body" + } + } + } + } + }, + "/drone/lock": { + "get": { + "description": "Stops drone movement while preserving existing queue", + "tags": [ + "Drone" + ], + "summary": "Halts drone in place while preserving queue", + "responses": { + "200": { + "description": "Drone unlocked successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "Drone unable to unlock (already unlocked?)", + "schema": { + "type": "body" + } + } + } + } + }, + "/drone/queue": { + "get": { + "description": "Returns queue in Mission Planner", + "produces": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Returns queue in Mission Planner", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Waypoint" + } + } + } + } + }, + "post": { + "description": "Sends a queue in Mission Planner", + "consumes": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Sends a queue in Mission Planner", + "parameters": [ + { + "description": "Array of Waypoint Data", + "name": "waypoints", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Waypoint" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/drone/rtl": { + "get": { + "description": "Tells Drone to return home and land", + "tags": [ + "Drone" + ], + "summary": "Returns to Home and Lands", + "responses": { + "200": { + "description": "RTL command issued successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "RTL command encountered an error", + "schema": { + "type": "body" + } + } + } + } + }, + "/drone/takeoff": { + "post": { + "description": "Tells Drone to takeoff", + "consumes": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Take off Drone", + "parameters": [ + { + "description": "Takeoff Altitude", + "name": "altitude", + "in": "body", + "required": true, + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/ground_object": { + "post": { + "description": "Create a singular ground object based on JSON, must have sentinel ID of \"-1\"", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "GroundObject" + ], + "summary": "Create a ground object", + "parameters": [ + { + "description": "Ground Object Data", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.GroundObject" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.GroundObjectResponse" + } + }, + "400": { + "description": "Invalid JSON or Ground Object Data", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Creating Ground Object", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, + "/ground_object/{id}": { + "get": { + "description": "Get a singular ground object based on the provided ID", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "GroundObject" + ], + "summary": "Get a ground object by ID", + "parameters": [ + { + "type": "integer", + "description": "Ground Object ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.GroundObjectResponse" + } + }, + "404": { + "description": "Ground Object Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Querying Ground Object", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + }, + "delete": { + "description": "Delete a singular payload based on path param", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Delete a payload", + "parameters": [ + { + "type": "integer", + "description": "Payload ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success (returns a blank Payload)", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "404": { + "description": "Payload Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Deleting Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + }, + "patch": { + "description": "Edit a singular ground object based on path param and JSON", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "GroundObject" + ], + "summary": "Edit a ground object.", + "parameters": [ + { + "type": "integer", + "description": "GroundObject ID", + "name": "id", + "in": "path", + "required": true + }, + { + "example": "{\"name\": \"Whiskey\"}", + "description": "JSON fields", + "name": "fields", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.GroundObjectResponse" + } + }, + "400": { + "description": "Invalid JSON or GroundObject ID", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "404": { + "description": "GroundObject Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Editing GroundObject", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, + "/payload": { + "post": { + "description": "Create a singular payload based on JSON, must have sentinel ID of \"-1\"", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Create a payload", + "parameters": [ + { + "description": "Payload Data", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Payload" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "400": { + "description": "Invalid JSON or Payload Data", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, + "/payload/{id}": { + "get": { + "description": "Get a singular payload based on the provided ID", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Get a payload by ID", + "parameters": [ + { + "type": "integer", + "description": "Payload ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "404": { + "description": "Payload Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Querying Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + }, + "patch": { + "description": "Edit a singular payload based on path param and JSON", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Edit a payload.", + "parameters": [ + { + "type": "integer", + "description": "Payload ID", + "name": "id", + "in": "path", + "required": true + }, + { + "example": "{\"name\": \"Whiskey\"}", + "description": "JSON fields", + "name": "fields", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "400": { + "description": "Invalid JSON or Payload ID", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "404": { + "description": "Payload Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Editing Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, "/status": { "get": { "description": "Get the current status of the drone", @@ -323,7 +838,7 @@ const docTemplate = `{ "required": true }, { - "example": "{\"name\": \"Whiskey}", + "example": "{\"name\": \"Whiskey\"}", "description": "JSON fields", "name": "fields", "in": "body", @@ -553,7 +1068,7 @@ const docTemplate = `{ "Launch", "Land", "Obstacle", - "Payload" + "PayloadDesignation" ] }, "models.Drone": { @@ -613,6 +1128,85 @@ const docTemplate = `{ } } }, + "models.GroundObject": { + "type": "object", + "required": [ + "color", + "id", + "lat", + "long", + "obj_type", + "shape", + "text", + "text_color" + ], + "properties": { + "id": { + "description": "To create a ground object, ID of \"-1\" must be passed", + "type": "string", + "x-order": "1", + "example": "-1" + }, + "obj_type": { + "type": "string", + "x-order": "2", + "example": "standard" + }, + "shape": { + "type": "string", + "x-order": "3", + "example": "triangle" + }, + "color": { + "type": "string", + "x-order": "4", + "example": "blue" + }, + "text": { + "type": "string", + "x-order": "5", + "example": "A" + }, + "text_color": { + "type": "string", + "x-order": "6", + "example": "green" + }, + "long": { + "type": "number", + "x-order": "7", + "example": -123.45 + }, + "lat": { + "type": "number", + "x-order": "8", + "example": 123.45 + } + } + }, + "models.Payload": { + "type": "object", + "required": [ + "ground_object", + "id" + ], + "properties": { + "id": { + "description": "To create a payload, ID of \"-1\" must be passed", + "type": "string", + "x-order": "1", + "example": "1" + }, + "ground_object": { + "allOf": [ + { + "$ref": "#/definitions/models.GroundObject" + } + ], + "x-order": "2" + } + } + }, "models.Waypoint": { "description": "describes a location in GCOM", "type": "object", @@ -702,6 +1296,32 @@ const docTemplate = `{ } } }, + "responses.GroundObjectResponse": { + "description": "Describes a response a single ground object", + "type": "object", + "properties": { + "ground_object": { + "$ref": "#/definitions/models.GroundObject" + }, + "message": { + "type": "string", + "example": "Sample success message" + } + } + }, + "responses.PayloadResponse": { + "description": "Describes a response a single payload", + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Sample success message" + }, + "payload": { + "$ref": "#/definitions/models.Payload" + } + } + }, "responses.WaypointResponse": { "description": "Describes a response a single waypoint", "type": "object", diff --git a/docs/swagger.json b/docs/swagger.json index 1ce3dcd..ad1db17 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -121,6 +121,521 @@ } } }, + "/drone/home": { + "post": { + "description": "Updates the home waypoint", + "consumes": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Updates the home waypoint", + "parameters": [ + { + "description": "Home Waypoint", + "name": "waypoints", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Waypoint" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/drone/land": { + "get": { + "description": "Tells Drone to land", + "tags": [ + "Drone" + ], + "summary": "Take off Drone", + "responses": { + "200": { + "description": "Command issued successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "Command failed to be issued", + "schema": { + "type": "body" + } + } + } + } + }, + "/drone/lock": { + "get": { + "description": "Stops drone movement while preserving existing queue", + "tags": [ + "Drone" + ], + "summary": "Halts drone in place while preserving queue", + "responses": { + "200": { + "description": "Drone unlocked successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "Drone unable to unlock (already unlocked?)", + "schema": { + "type": "body" + } + } + } + } + }, + "/drone/queue": { + "get": { + "description": "Returns queue in Mission Planner", + "produces": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Returns queue in Mission Planner", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Waypoint" + } + } + } + } + }, + "post": { + "description": "Sends a queue in Mission Planner", + "consumes": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Sends a queue in Mission Planner", + "parameters": [ + { + "description": "Array of Waypoint Data", + "name": "waypoints", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Waypoint" + } + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/drone/rtl": { + "get": { + "description": "Tells Drone to return home and land", + "tags": [ + "Drone" + ], + "summary": "Returns to Home and Lands", + "responses": { + "200": { + "description": "RTL command issued successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "RTL command encountered an error", + "schema": { + "type": "body" + } + } + } + } + }, + "/drone/takeoff": { + "post": { + "description": "Tells Drone to takeoff", + "consumes": [ + "application/json" + ], + "tags": [ + "Drone" + ], + "summary": "Take off Drone", + "parameters": [ + { + "description": "Takeoff Altitude", + "name": "altitude", + "in": "body", + "required": true, + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/ground_object": { + "post": { + "description": "Create a singular ground object based on JSON, must have sentinel ID of \"-1\"", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "GroundObject" + ], + "summary": "Create a ground object", + "parameters": [ + { + "description": "Ground Object Data", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.GroundObject" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.GroundObjectResponse" + } + }, + "400": { + "description": "Invalid JSON or Ground Object Data", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Creating Ground Object", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, + "/ground_object/{id}": { + "get": { + "description": "Get a singular ground object based on the provided ID", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "GroundObject" + ], + "summary": "Get a ground object by ID", + "parameters": [ + { + "type": "integer", + "description": "Ground Object ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.GroundObjectResponse" + } + }, + "404": { + "description": "Ground Object Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Querying Ground Object", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + }, + "delete": { + "description": "Delete a singular payload based on path param", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Delete a payload", + "parameters": [ + { + "type": "integer", + "description": "Payload ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success (returns a blank Payload)", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "404": { + "description": "Payload Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Deleting Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + }, + "patch": { + "description": "Edit a singular ground object based on path param and JSON", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "GroundObject" + ], + "summary": "Edit a ground object.", + "parameters": [ + { + "type": "integer", + "description": "GroundObject ID", + "name": "id", + "in": "path", + "required": true + }, + { + "example": "{\"name\": \"Whiskey\"}", + "description": "JSON fields", + "name": "fields", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.GroundObjectResponse" + } + }, + "400": { + "description": "Invalid JSON or GroundObject ID", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "404": { + "description": "GroundObject Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Editing GroundObject", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, + "/payload": { + "post": { + "description": "Create a singular payload based on JSON, must have sentinel ID of \"-1\"", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Create a payload", + "parameters": [ + { + "description": "Payload Data", + "name": "object", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.Payload" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "400": { + "description": "Invalid JSON or Payload Data", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, + "/payload/{id}": { + "get": { + "description": "Get a singular payload based on the provided ID", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Get a payload by ID", + "parameters": [ + { + "type": "integer", + "description": "Payload ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "404": { + "description": "Payload Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Querying Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + }, + "patch": { + "description": "Edit a singular payload based on path param and JSON", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Payload" + ], + "summary": "Edit a payload.", + "parameters": [ + { + "type": "integer", + "description": "Payload ID", + "name": "id", + "in": "path", + "required": true + }, + { + "example": "{\"name\": \"Whiskey\"}", + "description": "JSON fields", + "name": "fields", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/responses.PayloadResponse" + } + }, + "400": { + "description": "Invalid JSON or Payload ID", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "404": { + "description": "Payload Not Found", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + }, + "500": { + "description": "Internal Error Editing Payload", + "schema": { + "$ref": "#/definitions/responses.ErrorResponse" + } + } + } + } + }, "/status": { "get": { "description": "Get the current status of the drone", @@ -316,7 +831,7 @@ "required": true }, { - "example": "{\"name\": \"Whiskey}", + "example": "{\"name\": \"Whiskey\"}", "description": "JSON fields", "name": "fields", "in": "body", @@ -546,7 +1061,7 @@ "Launch", "Land", "Obstacle", - "Payload" + "PayloadDesignation" ] }, "models.Drone": { @@ -606,6 +1121,85 @@ } } }, + "models.GroundObject": { + "type": "object", + "required": [ + "color", + "id", + "lat", + "long", + "obj_type", + "shape", + "text", + "text_color" + ], + "properties": { + "id": { + "description": "To create a ground object, ID of \"-1\" must be passed", + "type": "string", + "x-order": "1", + "example": "-1" + }, + "obj_type": { + "type": "string", + "x-order": "2", + "example": "standard" + }, + "shape": { + "type": "string", + "x-order": "3", + "example": "triangle" + }, + "color": { + "type": "string", + "x-order": "4", + "example": "blue" + }, + "text": { + "type": "string", + "x-order": "5", + "example": "A" + }, + "text_color": { + "type": "string", + "x-order": "6", + "example": "green" + }, + "long": { + "type": "number", + "x-order": "7", + "example": -123.45 + }, + "lat": { + "type": "number", + "x-order": "8", + "example": 123.45 + } + } + }, + "models.Payload": { + "type": "object", + "required": [ + "ground_object", + "id" + ], + "properties": { + "id": { + "description": "To create a payload, ID of \"-1\" must be passed", + "type": "string", + "x-order": "1", + "example": "1" + }, + "ground_object": { + "allOf": [ + { + "$ref": "#/definitions/models.GroundObject" + } + ], + "x-order": "2" + } + } + }, "models.Waypoint": { "description": "describes a location in GCOM", "type": "object", @@ -695,6 +1289,32 @@ } } }, + "responses.GroundObjectResponse": { + "description": "Describes a response a single ground object", + "type": "object", + "properties": { + "ground_object": { + "$ref": "#/definitions/models.GroundObject" + }, + "message": { + "type": "string", + "example": "Sample success message" + } + } + }, + "responses.PayloadResponse": { + "description": "Describes a response a single payload", + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Sample success message" + }, + "payload": { + "$ref": "#/definitions/models.Payload" + } + } + }, "responses.WaypointResponse": { "description": "Describes a response a single waypoint", "type": "object", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 662bc5d..b23a0d5 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -50,7 +50,7 @@ definitions: - Launch - Land - Obstacle - - Payload + - PayloadDesignation models.Drone: description: describes the drone being flown properties: @@ -97,6 +97,66 @@ definitions: - timestamp - v_speed type: object + models.GroundObject: + properties: + color: + example: blue + type: string + x-order: "4" + id: + description: To create a ground object, ID of "-1" must be passed + example: "-1" + type: string + x-order: "1" + lat: + example: 123.45 + type: number + x-order: "8" + long: + example: -123.45 + type: number + x-order: "7" + obj_type: + example: standard + type: string + x-order: "2" + shape: + example: triangle + type: string + x-order: "3" + text: + example: A + type: string + x-order: "5" + text_color: + example: green + type: string + x-order: "6" + required: + - color + - id + - lat + - long + - obj_type + - shape + - text + - text_color + type: object + models.Payload: + properties: + ground_object: + allOf: + - $ref: '#/definitions/models.GroundObject' + x-order: "2" + id: + description: To create a payload, ID of "-1" must be passed + example: "1" + type: string + x-order: "1" + required: + - ground_object + - id + type: object models.Waypoint: description: describes a location in GCOM properties: @@ -163,6 +223,24 @@ definitions: example: Sample error message type: string type: object + responses.GroundObjectResponse: + description: Describes a response a single ground object + properties: + ground_object: + $ref: '#/definitions/models.GroundObject' + message: + example: Sample success message + type: string + type: object + responses.PayloadResponse: + description: Describes a response a single payload + properties: + message: + example: Sample success message + type: string + payload: + $ref: '#/definitions/models.Payload' + type: object responses.WaypointResponse: description: Describes a response a single waypoint properties: @@ -261,6 +339,347 @@ paths: summary: Create multiple AirObjects tags: - AirObject + /drone/home: + post: + consumes: + - application/json + description: Updates the home waypoint + parameters: + - description: Home Waypoint + in: body + name: waypoints + required: true + schema: + $ref: '#/definitions/models.Waypoint' + responses: + "200": + description: OK + summary: Updates the home waypoint + tags: + - Drone + /drone/land: + get: + description: Tells Drone to land + responses: + "200": + description: Command issued successfully + schema: + type: body + "500": + description: Command failed to be issued + schema: + type: body + summary: Take off Drone + tags: + - Drone + /drone/lock: + get: + description: Stops drone movement while preserving existing queue + responses: + "200": + description: Drone unlocked successfully + schema: + type: body + "500": + description: Drone unable to unlock (already unlocked?) + schema: + type: body + summary: Halts drone in place while preserving queue + tags: + - Drone + /drone/queue: + get: + description: Returns queue in Mission Planner + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.Waypoint' + type: array + summary: Returns queue in Mission Planner + tags: + - Drone + post: + consumes: + - application/json + description: Sends a queue in Mission Planner + parameters: + - description: Array of Waypoint Data + in: body + name: waypoints + required: true + schema: + items: + $ref: '#/definitions/models.Waypoint' + type: array + responses: + "200": + description: OK + summary: Sends a queue in Mission Planner + tags: + - Drone + /drone/rtl: + get: + description: Tells Drone to return home and land + responses: + "200": + description: RTL command issued successfully + schema: + type: body + "500": + description: RTL command encountered an error + schema: + type: body + summary: Returns to Home and Lands + tags: + - Drone + /drone/takeoff: + post: + consumes: + - application/json + description: Tells Drone to takeoff + parameters: + - description: Takeoff Altitude + in: body + name: altitude + required: true + schema: + type: number + responses: + "200": + description: OK + summary: Take off Drone + tags: + - Drone + /ground_object: + post: + consumes: + - application/json + description: Create a singular ground object based on JSON, must have sentinel + ID of "-1" + parameters: + - description: Ground Object Data + in: body + name: object + required: true + schema: + $ref: '#/definitions/models.GroundObject' + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/responses.GroundObjectResponse' + "400": + description: Invalid JSON or Ground Object Data + schema: + $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Error Creating Ground Object + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Create a ground object + tags: + - GroundObject + /ground_object/{id}: + delete: + consumes: + - application/json + description: Delete a singular payload based on path param + parameters: + - description: Payload ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: Success (returns a blank Payload) + schema: + $ref: '#/definitions/responses.PayloadResponse' + "404": + description: Payload Not Found + schema: + $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Error Deleting Payload + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Delete a payload + tags: + - Payload + get: + consumes: + - application/json + description: Get a singular ground object based on the provided ID + parameters: + - description: Ground Object ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/responses.GroundObjectResponse' + "404": + description: Ground Object Not Found + schema: + $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Error Querying Ground Object + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Get a ground object by ID + tags: + - GroundObject + patch: + consumes: + - application/json + description: Edit a singular ground object based on path param and JSON + parameters: + - description: GroundObject ID + in: path + name: id + required: true + type: integer + - description: JSON fields + example: '{"name": "Whiskey"}' + in: body + name: fields + required: true + schema: + type: string + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/responses.GroundObjectResponse' + "400": + description: Invalid JSON or GroundObject ID + schema: + $ref: '#/definitions/responses.ErrorResponse' + "404": + description: GroundObject Not Found + schema: + $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Error Editing GroundObject + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Edit a ground object. + tags: + - GroundObject + /payload: + post: + consumes: + - application/json + description: Create a singular payload based on JSON, must have sentinel ID + of "-1" + parameters: + - description: Payload Data + in: body + name: object + required: true + schema: + $ref: '#/definitions/models.Payload' + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/responses.PayloadResponse' + "400": + description: Invalid JSON or Payload Data + schema: + $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Error Payload + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Create a payload + tags: + - Payload + /payload/{id}: + get: + consumes: + - application/json + description: Get a singular payload based on the provided ID + parameters: + - description: Payload ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/responses.PayloadResponse' + "404": + description: Payload Not Found + schema: + $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Error Querying Payload + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Get a payload by ID + tags: + - Payload + patch: + consumes: + - application/json + description: Edit a singular payload based on path param and JSON + parameters: + - description: Payload ID + in: path + name: id + required: true + type: integer + - description: JSON fields + example: '{"name": "Whiskey"}' + in: body + name: fields + required: true + schema: + type: string + produces: + - application/json + responses: + "200": + description: Success + schema: + $ref: '#/definitions/responses.PayloadResponse' + "400": + description: Invalid JSON or Payload ID + schema: + $ref: '#/definitions/responses.ErrorResponse' + "404": + description: Payload Not Found + schema: + $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Error Editing Payload + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Edit a payload. + tags: + - Payload /status: get: description: Get the current status of the drone @@ -388,7 +807,7 @@ paths: required: true type: integer - description: JSON fields - example: '{"name": "Whiskey}' + example: '{"name": "Whiskey"}' in: body name: fields required: true From d74b4ace4ef858ae5c1b690be6ab133bc597e2b2 Mon Sep 17 00:00:00 2001 From: Aden Chan <40689649+21chanas3@users.noreply.github.com> Date: Sat, 9 Mar 2024 06:26:45 -0800 Subject: [PATCH 2/6] added documentation --- controllers/drone_controller.go | 2 +- docs/docs.go | 27 +++++++++++++++++++++++++-- docs/swagger.json | 27 +++++++++++++++++++++++++-- docs/swagger.yaml | 19 +++++++++++++++++-- go.mod | 2 +- go.sum | 31 +++++++++++++++++++++++++++++-- main.go | 4 +--- 7 files changed, 99 insertions(+), 13 deletions(-) diff --git a/controllers/drone_controller.go b/controllers/drone_controller.go index 4232e8f..f70988e 100644 --- a/controllers/drone_controller.go +++ b/controllers/drone_controller.go @@ -119,7 +119,7 @@ func Lock(c echo.Context) error { // @Tags Drone // @Success 200 body string "Drone unlocked successfully" // @Failure 500 body string "Drone unable to unlock (already unlocked?)" -// @Router /drone/lock [get] +// @Router /drone/unlock [get] func Unlock(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) if mp.Unlock() { diff --git a/docs/docs.go b/docs/docs.go index 7cf8680..2d4a2ed 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -188,13 +188,13 @@ const docTemplate = `{ "summary": "Halts drone in place while preserving queue", "responses": { "200": { - "description": "Drone unlocked successfully", + "description": "Drone locked successfully", "schema": { "type": "body" } }, "500": { - "description": "Drone unable to unlock (already unlocked?)", + "description": "Drone unable to lock (already locked?)", "schema": { "type": "body" } @@ -305,6 +305,29 @@ const docTemplate = `{ } } }, + "/drone/unlock": { + "get": { + "description": "Stops drone movement while preserving existing queue", + "tags": [ + "Drone" + ], + "summary": "Halts drone in place while preserving queue", + "responses": { + "200": { + "description": "Drone unlocked successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "Drone unable to unlock (already unlocked?)", + "schema": { + "type": "body" + } + } + } + } + }, "/ground_object": { "post": { "description": "Create a singular ground object based on JSON, must have sentinel ID of \"-1\"", diff --git a/docs/swagger.json b/docs/swagger.json index ad1db17..ef998ae 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -181,13 +181,13 @@ "summary": "Halts drone in place while preserving queue", "responses": { "200": { - "description": "Drone unlocked successfully", + "description": "Drone locked successfully", "schema": { "type": "body" } }, "500": { - "description": "Drone unable to unlock (already unlocked?)", + "description": "Drone unable to lock (already locked?)", "schema": { "type": "body" } @@ -298,6 +298,29 @@ } } }, + "/drone/unlock": { + "get": { + "description": "Stops drone movement while preserving existing queue", + "tags": [ + "Drone" + ], + "summary": "Halts drone in place while preserving queue", + "responses": { + "200": { + "description": "Drone unlocked successfully", + "schema": { + "type": "body" + } + }, + "500": { + "description": "Drone unable to unlock (already unlocked?)", + "schema": { + "type": "body" + } + } + } + } + }, "/ground_object": { "post": { "description": "Create a singular ground object based on JSON, must have sentinel ID of \"-1\"", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b23a0d5..275bb8a 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -377,11 +377,11 @@ paths: description: Stops drone movement while preserving existing queue responses: "200": - description: Drone unlocked successfully + description: Drone locked successfully schema: type: body "500": - description: Drone unable to unlock (already unlocked?) + description: Drone unable to lock (already locked?) schema: type: body summary: Halts drone in place while preserving queue @@ -454,6 +454,21 @@ paths: summary: Take off Drone tags: - Drone + /drone/unlock: + get: + description: Stops drone movement while preserving existing queue + responses: + "200": + description: Drone unlocked successfully + schema: + type: body + "500": + description: Drone unable to unlock (already unlocked?) + schema: + type: body + summary: Halts drone in place while preserving queue + tags: + - Drone /ground_object: post: consumes: diff --git a/go.mod b/go.mod index 065b957..482622c 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.19 require ( github.com/go-playground/validator v9.31.0+incompatible github.com/googollee/go-socket.io v1.7.0 - github.com/joho/godotenv v1.5.1 github.com/labstack/echo/v4 v4.11.2 github.com/swaggo/echo-swagger v1.4.1 + github.com/swaggo/files v1.0.1 github.com/swaggo/swag v1.16.2 ) diff --git a/go.sum b/go.sum index c736749..85a9f30 100644 --- a/go.sum +++ b/go.sum @@ -44,8 +44,6 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -95,6 +93,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/swaggo/echo-swagger v1.4.1 h1:Yf0uPaJWp1uRtDloZALyLnvdBeoEL5Kc7DtnjzO/TUk= github.com/swaggo/echo-swagger v1.4.1/go.mod h1:C8bSi+9yH2FLZsnhqMZLIZddpUxZdBYuNHbtaS1Hljc= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw= github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM= github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= @@ -104,24 +104,51 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/main.go b/main.go index 9ad9701..b8f14fc 100644 --- a/main.go +++ b/main.go @@ -3,13 +3,11 @@ package main import ( "gcom-backend/configs" "gcom-backend/controllers" - "gcom-backend/docs" + _ "gcom-backend/docs" "gcom-backend/util" "log" "os" - "github.com/joho/godotenv" - "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" echoSwagger "github.com/swaggo/echo-swagger" From 1a72c8c9e6ab185eca214984722eed79d74923e1 Mon Sep 17 00:00:00 2001 From: Aden Chan <40689649+21chanas3@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:36:36 -0800 Subject: [PATCH 3/6] debugged changes --- configs/mp.go | 24 ++++++++++++++++-------- controllers/drone_controller.go | 18 ++++++++++++++---- main.go | 8 +++----- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/configs/mp.go b/configs/mp.go index a16e77d..1a54a0b 100644 --- a/configs/mp.go +++ b/configs/mp.go @@ -2,6 +2,7 @@ package configs import ( "net/http" + "strconv" "bytes" "encoding/json" @@ -34,7 +35,7 @@ func ConnectMissionPlanner(url string) (*MissionPlanner, error) { } type mpWaypoint struct { - ID int `json:"id"` + ID string `json:"id"` Name string `json:"name"` Longitude float64 `json:"longitude"` Latitude float64 `json:"latitude"` @@ -51,7 +52,6 @@ type mpDrone struct { } func genericGet(url string) *http.Response { - println(url) resp, err := http.Get(url) if err != nil { println(url) @@ -92,7 +92,7 @@ func (mp MissionPlanner) GetQueue() []models.Waypoint { for _, mpwp := range respArr { wp := models.Waypoint{ - ID: mpwp.ID, + ID: -1, Name: mpwp.Name, Latitude: mpwp.Latitude, Longitude: mpwp.Longitude, @@ -133,9 +133,17 @@ func (mp MissionPlanner) GetStatus() models.Drone { return ans } -func (mp MissionPlanner) ReturnHome() bool { - resp := genericGet(mp.url + "/rtl") - println(resp.StatusCode) +func (mp MissionPlanner) ReturnHome(alt float64) bool { + json, err := json.Marshal(map[string]float64{ + "altitude": alt, + }) + + if err != nil { + log.Fatal("[MP Functions] Error marshalling altitude for rtl") + } + + resp := genericPost(mp.url+"/rtl", json) + return resp.StatusCode == http.StatusOK } @@ -160,7 +168,7 @@ func (mp MissionPlanner) SetQueue(waypoints []models.Waypoint) bool { var mpArr []mpWaypoint for _, wp := range waypoints { mpwp := mpWaypoint{ - ID: wp.ID, + ID: strconv.Itoa(wp.ID), Name: wp.Name, Longitude: wp.Longitude, Latitude: wp.Latitude, @@ -196,7 +204,7 @@ func (mp MissionPlanner) Takeoff(alt float64) bool { func (mp MissionPlanner) SetHome(waypoint models.Waypoint) bool { mpwp := mpWaypoint{ - ID: waypoint.ID, + ID: strconv.Itoa(waypoint.ID), Name: waypoint.Name, Longitude: waypoint.Longitude, Latitude: waypoint.Latitude, diff --git a/controllers/drone_controller.go b/controllers/drone_controller.go index f70988e..2f33090 100644 --- a/controllers/drone_controller.go +++ b/controllers/drone_controller.go @@ -85,10 +85,20 @@ func Land(c echo.Context) error { // @Tags Drone // @Success 200 body string "RTL command issued successfully" // @Failure 500 body string "RTL command encountered an error" -// @Router /drone/rtl [get] +// @Router /drone/rtl [post] func RTL(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) - if mp.ReturnHome() { + + var altitude float64 + json_map := make(map[string]interface{}) + err := json.NewDecoder(c.Request().Body).Decode(&json_map) + if err != nil { + return err + } else { + altitude = json_map["altitude"].(float64) + } + + if mp.ReturnHome(altitude) { return c.HTML(http.StatusAccepted, "") } else { return c.HTML(http.StatusInternalServerError, "") @@ -106,9 +116,9 @@ func RTL(c echo.Context) error { func Lock(c echo.Context) error { mp := c.Get("mp").(*configs.MissionPlanner) if mp.Lock() { - return c.HTML(http.StatusAccepted, "") + return c.HTML(http.StatusAccepted, "a") } else { - return c.HTML(http.StatusInternalServerError, "") + return c.HTML(http.StatusInternalServerError, "a") } } diff --git a/main.go b/main.go index b8f14fc..c64ea63 100644 --- a/main.go +++ b/main.go @@ -5,12 +5,10 @@ import ( "gcom-backend/controllers" _ "gcom-backend/docs" "gcom-backend/util" - "log" - "os" - "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" echoSwagger "github.com/swaggo/echo-swagger" + "log" ) // @title GCOM Backend @@ -31,7 +29,7 @@ func main() { db := configs.Connect(false) - mp, err := configs.ConnectMissionPlanner(os.Getenv("MP_URL")) + mp, err := configs.ConnectMissionPlanner("http://host.docker.internal:9000") if err != nil { log.Fatal("Error connecting to MPS") } @@ -75,7 +73,7 @@ func main() { e.GET("/status/history", controllers.GetStatusHistory) e.POST("/drone/takeoff", controllers.Takeoff) e.GET("/drone/land", controllers.Land) - e.GET("/drone/rtl", controllers.RTL) + e.POST("/drone/rtl", controllers.RTL) e.GET("/drone/lock", controllers.Lock) e.GET("/drone/unlock", controllers.Unlock) e.GET("/drone/queue", controllers.GetQueue) From 531bba81ee009d7ceb3586ea8e40b859807402de Mon Sep 17 00:00:00 2001 From: Jim Geng Date: Sat, 16 Mar 2024 12:00:11 -0700 Subject: [PATCH 4/6] add CORS to allow for front end communication --- main.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index c64ea63..7e16ec6 100644 --- a/main.go +++ b/main.go @@ -5,10 +5,11 @@ import ( "gcom-backend/controllers" _ "gcom-backend/docs" "gcom-backend/util" + "log" + "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" echoSwagger "github.com/swaggo/echo-swagger" - "log" ) // @title GCOM Backend @@ -38,6 +39,7 @@ func main() { e.Use(util.DBMiddleware(db)) e.Use(util.MPMiddleware(mp)) + e.Use(middleware.CORS()) e.Use(middleware.Logger()) e.GET("/", func(c echo.Context) error { From e0ee87508f72b1e583742a41c401d1e4868feb5c Mon Sep 17 00:00:00 2001 From: 21chanas3 Date: Tue, 19 Mar 2024 09:53:16 -0700 Subject: [PATCH 5/6] mps integration final --- docs/docs.go | 2 +- docs/swagger.json | 2 +- docs/swagger.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 2d4a2ed..1a4afe1 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -255,7 +255,7 @@ const docTemplate = `{ } }, "/drone/rtl": { - "get": { + "post": { "description": "Tells Drone to return home and land", "tags": [ "Drone" diff --git a/docs/swagger.json b/docs/swagger.json index ef998ae..0779b2a 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -248,7 +248,7 @@ } }, "/drone/rtl": { - "get": { + "post": { "description": "Tells Drone to return home and land", "tags": [ "Drone" diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 275bb8a..6ef2de7 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -422,7 +422,7 @@ paths: tags: - Drone /drone/rtl: - get: + post: description: Tells Drone to return home and land responses: "200": From b045717615e217be775f9d47015ce0372813126c Mon Sep 17 00:00:00 2001 From: 21chanas3 Date: Tue, 19 Mar 2024 10:07:37 -0700 Subject: [PATCH 6/6] fixes --- controllers/drone_controller.go | 4 ++++ main.go | 5 ----- models/drone_model.go | 2 +- util/mp_middleware.go | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 util/mp_middleware.go diff --git a/controllers/drone_controller.go b/controllers/drone_controller.go index b1d52b7..929bf3f 100644 --- a/controllers/drone_controller.go +++ b/controllers/drone_controller.go @@ -1,8 +1,12 @@ package controllers import ( + "gcom-backend/configs" + "gcom-backend/responses" + "gcom-backend/models" "github.com/labstack/echo/v4" "net/http" + "encoding/json" ) // GetCurrentStatus gets the current status of the drone diff --git a/main.go b/main.go index 16ac4eb..ba4846f 100644 --- a/main.go +++ b/main.go @@ -69,11 +69,6 @@ func main() { e.POST("/drone/queue", controllers.PostQueue) e.POST("/drone/home", controllers.PostHome) - //AirObjects - e.GET("/air_object", controllers.GetAirObjects) - e.DELETE("/air_object", controllers.DeleteAirObjects) - e.POST("/air_object", controllers.CreateAirObjects) - //Websockets e.Any("/socket.io/", controllers.WebsocketHandler()) diff --git a/models/drone_model.go b/models/drone_model.go index a77a118..0c02acf 100644 --- a/models/drone_model.go +++ b/models/drone_model.go @@ -4,7 +4,7 @@ package models // // @Description describes the drone being flown type Drone struct { - Timestamp int `json:"timestamp" gorm:"primaryKey" validate:"required" example:"1698544781" extensions:"x-order=1"` + Timestamp int64 `json:"timestamp" gorm:"primaryKey" validate:"required" example:"1698544781" extensions:"x-order=1"` Latitude float64 `json:"lat" validate:"required" example:"49.267941" extensions:"x-order=2"` Longitude float64 `json:"long" validate:"required" example:"-123.247360" extensions:"x-order=3"` Altitude float64 `json:"alt" validate:"required" example:"100.00" extensions:"x-order=4"` diff --git a/util/mp_middleware.go b/util/mp_middleware.go new file mode 100644 index 0000000..94ac06c --- /dev/null +++ b/util/mp_middleware.go @@ -0,0 +1,16 @@ +package util + +import ( + "gcom-backend/configs" + + "github.com/labstack/echo/v4" +) + +func MPMiddleware(mp *configs.MissionPlanner) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + c.Set("mp", mp) + return next(c) + } + } +} \ No newline at end of file