|
| 1 | +# Usage |
| 2 | + |
| 3 | +`controller` takes `path` stream from `imaging` service as input and produces a `decision` output stream. |
| 4 | + |
| 5 | +## Input |
| 6 | + |
| 7 | +`path` stream has the following format: |
| 8 | +``` |
| 9 | +pb_output.SensorOutput{ |
| 10 | + SensorId: 25, |
| 11 | + Timestamp: uint64(time.Now().UnixMilli()), |
| 12 | + SensorOutput: &pb_output.SensorOutput_CameraOutput{ |
| 13 | + CameraOutput: &pb_output.CameraSensorOutput{ |
| 14 | + DebugFrame: &pb_output.CameraSensorOutput_DebugFrame{ |
| 15 | + Jpeg: imgBytes.GetBytes(), |
| 16 | + Canvas: &canvas, |
| 17 | + }, |
| 18 | + Trajectory: &pb_output.CameraSensorOutput_Trajectory{ |
| 19 | + Points: trajectory_points, |
| 20 | + Width: uint32(imgWidth), |
| 21 | + Height: uint32(imgHeight), |
| 22 | + }, |
| 23 | + }, |
| 24 | + }, |
| 25 | +} |
| 26 | +``` |
| 27 | + |
| 28 | +`SensorOutput_CameraOutput` object contains a `CameraSensorOutput` object with 2 main fields: |
| 29 | +1. `CameraSensorOutput_DebugFrame` containing: |
| 30 | + - `Jpeg`, a (prerpocessed) acquired frame transmitted as a raw byte array of a JPEG image and the |
| 31 | + - `canvas`, contains a `width` and `height` fields, as well as an array of `CanvasObject`s, which are either a `Line`, `Rectangle` or `Circle`. It can be used for example to overlay these shapes on top of the JPEG image. |
| 32 | + |
| 33 | +2. `CameraSensorOutput_Trajecotry` is composed of: |
| 34 | + - `trajectory_points` array of points supplied by the imaging (default implementation only passes 1 point to the array). |
| 35 | + - `Width` of the acquired image. |
| 36 | + - `Height` of the acquired image |
| 37 | + |
| 38 | +### Processing input |
| 39 | + |
| 40 | +Taken from `src/main.go`: |
| 41 | +``` |
| 42 | +imagingData := data.GetCameraOutput() |
| 43 | +``` |
| 44 | +This unmarshals the `SensorOutput` object and returns a `CameraSensorOutput` object |
| 45 | + |
| 46 | + |
| 47 | +``` |
| 48 | +trajectory := imagingData.GetTrajectory() |
| 49 | +``` |
| 50 | +Next, we further process the input to extract a `CameraSensorOutput_Trajectory` object to further work with. |
| 51 | + |
| 52 | +### how to use first point |
| 53 | + |
| 54 | +The first point in the array of trajectory points is the identified middle of the visible part of the track. (see image below). You can, for example, compare value of its `x` coordinate to the middle of the frame to see if the car is offset towards the left or right side of the track. |
| 55 | + |
| 56 | + |
| 57 | + |
| 58 | +## Controller |
| 59 | + |
| 60 | +The default implementation of the `controller` service uses a PID algorithm to make a decision on where to go ([What is a PID controller?](https://en.wikipedia.org/wiki/Proportional–integral–derivative_controller)). It is very much the core of this service and is the primary part you would want to replace, should you decide to implement your own algorithm. |
| 61 | + |
| 62 | +## Output |
| 63 | + |
| 64 | +`controller` outputs the `decision` stream (see example below), which is later read and interpreted by the `actuator`. |
| 65 | + |
| 66 | +``` |
| 67 | +actuatorOutput.Write( |
| 68 | + &pb_outputs.SensorOutput{ |
| 69 | + SensorId: 2, |
| 70 | + Timestamp: uint64(time.Now().UnixMilli()), |
| 71 | + SensorOutput: &pb_outputs.SensorOutput_ControllerOutput{ |
| 72 | + ControllerOutput: &pb_outputs.ControllerOutput{ |
| 73 | + SteeringAngle: float32(steerValue), |
| 74 | + LeftThrottle: float32(speed), |
| 75 | + RightThrottle: float32(speed), |
| 76 | + FrontLights: false, |
| 77 | + }, |
| 78 | + }, |
| 79 | + }, |
| 80 | +) |
| 81 | +``` |
| 82 | + |
| 83 | +`SensorOutput_ControllerOutput` contains a `ControllerOutput` object, composed of the following fields: |
| 84 | + |
| 85 | +1. `SteeringAngle`, a `float32` value between -1 (left) and 1 (right) |
| 86 | +2. `LeftThrottle`, a `float32` value between -1 (full reverse) and 1 (full forward) |
| 87 | +3. `RightThrottle`, a `float32` value between -1 (full reverse) and 1 (full forward) |
| 88 | +4. `FrontLights`, a `boolean` value previously used to turn on the front lights in the dark, currently not used |
| 89 | + |
| 90 | +For seeing an example of using `decision` stream, please look at `actuator documentation` |
0 commit comments