├── templates ├── enum.j2 ├── struct.j2 ├── func_desc_macro.j2 ├── file.j2 ├── type_conversions ├── call.j2 ├── request.j2 ├── func_param_macro.j2 ├── object_init_macro.j2 └── stream.j2 ├── .gitignore ├── .gitmodules ├── tools ├── run_docker.bash ├── Dockerfile ├── generate_only_plugins.bash └── generate_from_protos.bash ├── docker ├── mavsdk_server │ └── Dockerfile └── docker-compose.yml ├── go.mod ├── Sources ├── rtk │ ├── rtk.go │ └── rtk_grpc.pb.go ├── tune │ ├── tune.go │ └── tune_grpc.pb.go ├── server_utility │ ├── server_utility.go │ └── server_utility_grpc.pb.go ├── component_metadata_server │ ├── component_metadata_server.go │ └── component_metadata_server_grpc.pb.go ├── failure │ ├── failure.go │ └── failure_grpc.pb.go ├── ftp_server │ ├── ftp_server.go │ └── ftp_server_grpc.pb.go ├── gripper │ ├── gripper.go │ └── gripper_grpc.pb.go ├── geofence │ ├── geofence.go │ └── geofence_grpc.pb.go ├── shell │ ├── shell.go │ └── shell_grpc.pb.go ├── transponder │ ├── transponder.go │ └── transponder_grpc.pb.go ├── core │ ├── core.go │ └── core_grpc.pb.go ├── manual_control │ └── manual_control.go ├── log_streaming │ └── log_streaming.go ├── log_files │ ├── log_files.go │ └── log_files_grpc.pb.go ├── mocap │ └── mocap.go ├── arm_authorizer_server │ └── arm_authorizer_server.go ├── follow_me │ └── follow_me.go ├── component_metadata │ └── component_metadata.go ├── info │ └── info.go ├── mission_raw_server │ └── mission_raw_server.go ├── param │ └── param.go ├── calibration │ └── calibration.go ├── ftp │ └── ftp.go ├── winch │ └── winch.go ├── offboard │ └── offboard.go ├── param_server │ └── param_server.go ├── gimbal │ └── gimbal.go ├── telemetry_server │ └── telemetry_server.go ├── mission │ └── mission.go ├── action_server │ └── action_server.go └── mission_raw │ └── mission_raw.go ├── README.md ├── go.sum ├── LICENSE.md ├── Contributing.md └── example └── example.go /templates/enum.j2: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/struct.j2: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | bin/ 3 | 4 | .build 5 | 6 | .idea 7 | docs/ 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "proto"] 2 | path = proto 3 | url = https://github.com/mavlink/MAVSDK-Proto.git 4 | -------------------------------------------------------------------------------- /templates/func_desc_macro.j2: -------------------------------------------------------------------------------- 1 | /* 2 | {{ name.upper_camel_case }} {{ indent(method_description, 0) }} 3 | */ -------------------------------------------------------------------------------- /tools/run_docker.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | docker run -it -v "$(dirname "$(pwd)")":/resources/ mavsdk bash 3 | 4 | # To Build the docker 5 | # docker build . -t mavsdk -------------------------------------------------------------------------------- /templates/file.j2: -------------------------------------------------------------------------------- 1 | package {{plugin_name.lower_snake_case}} 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io" 7 | ) 8 | 9 | type ServiceImpl struct{ 10 | Client {{plugin_name.upper_camel_case}}ServiceClient 11 | } 12 | 13 | {%- for method in methods -%} 14 | 15 | {{ '\n' + indent(method, 1) }} 16 | 17 | {%- endfor %} -------------------------------------------------------------------------------- /docker/mavsdk_server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y curl 5 | 6 | RUN curl -L https://github.com/ykhedar/MAVSDK/releases/download/v0.50.2APM/mavsdk_server_manylinux2010-x64 -o /root/mavsdk_server 7 | 8 | RUN chmod +x /root/mavsdk_server 9 | 10 | ENTRYPOINT /root/mavsdk_server -p 50051 11 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mavsdk_server: 4 | build: ./mavsdk_server 5 | ports: 6 | - "50051:50051" 7 | - "14540:14540/udp" 8 | gazebo_sitl_headless: 9 | image: jonasvautherin/px4-gazebo-headless:1.12.1 10 | environment: 11 | - NO_PXH=1 12 | links: 13 | - mavsdk_server 14 | -------------------------------------------------------------------------------- /templates/type_conversions: -------------------------------------------------------------------------------- 1 | { 2 | "double": "float64", 3 | "float": "float32", 4 | "int64": "int64", 5 | "uint64": "uint64", 6 | "int32": "int32", 7 | "int32_t":"int32", 8 | "bool": "bool", 9 | "bytes": "[]byte", 10 | "uint32_t":"uint32", 11 | "uint64_t":"uint64", 12 | "std::string":"string", 13 | "repeated": { "prefix": "[]*", "suffix": "" } 14 | } -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mavlink/MAVSDK-Go 2 | 3 | go 1.24.4 4 | 5 | require ( 6 | google.golang.org/grpc v1.65.0 7 | google.golang.org/protobuf v1.34.1 8 | ) 9 | 10 | require ( 11 | golang.org/x/net v0.25.0 // indirect 12 | golang.org/x/sys v0.20.0 // indirect 13 | golang.org/x/text v0.15.0 // indirect 14 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /templates/call.j2: -------------------------------------------------------------------------------- 1 | {% include 'func_desc_macro.j2' %} 2 | func (s *ServiceImpl) {{ name.upper_camel_case }}( 3 | ctx context.Context, 4 | {% include 'func_param_macro.j2' %} 5 | ) (*{{ name.upper_camel_case }}Response, error) { 6 | request := &{{ name.upper_camel_case }}Request{ 7 | {% include 'object_init_macro.j2' %} 8 | } 9 | response, err := s.Client.{{ name.upper_camel_case }}(ctx, request) 10 | if err != nil { 11 | return nil, err 12 | } 13 | return response, nil 14 | } -------------------------------------------------------------------------------- /templates/request.j2: -------------------------------------------------------------------------------- 1 | {% include 'func_desc_macro.j2' %} 2 | func(s *ServiceImpl) {{ name.upper_camel_case }}( 3 | ctx context.Context, 4 | {% include 'func_param_macro.j2' %} 5 | ) (*{{ name.upper_camel_case }}Response, error) { 6 | request := &{{ name.upper_camel_case }}Request{ 7 | {% include 'object_init_macro.j2' %} 8 | } 9 | response, err := s.Client.{{ name.upper_camel_case }}(ctx, request) 10 | if err != nil { 11 | return nil, err 12 | } 13 | return response, nil 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sources/rtk/rtk.go: -------------------------------------------------------------------------------- 1 | package rtk 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client RtkServiceClient 9 | } 10 | 11 | /* 12 | SendRtcmData Send RTCM data. 13 | */ 14 | func (s *ServiceImpl) SendRtcmData( 15 | ctx context.Context, 16 | rtcmData *RtcmData, 17 | 18 | ) (*SendRtcmDataResponse, error) { 19 | request := &SendRtcmDataRequest{ 20 | RtcmData: rtcmData, 21 | } 22 | response, err := s.Client.SendRtcmData(ctx, request) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, nil 27 | } 28 | -------------------------------------------------------------------------------- /Sources/tune/tune.go: -------------------------------------------------------------------------------- 1 | package tune 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client TuneServiceClient 9 | } 10 | 11 | /* 12 | PlayTune Send a tune to be played by the system. 13 | */ 14 | func (s *ServiceImpl) PlayTune( 15 | ctx context.Context, 16 | tuneDescription *TuneDescription, 17 | 18 | ) (*PlayTuneResponse, error) { 19 | request := &PlayTuneRequest{ 20 | TuneDescription: tuneDescription, 21 | } 22 | response, err := s.Client.PlayTune(ctx, request) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, nil 27 | } 28 | -------------------------------------------------------------------------------- /templates/func_param_macro.j2: -------------------------------------------------------------------------------- 1 | {% for param in params %} 2 | {%- if param.name.lower_camel_case == 'range' %} 3 | rangeVar {{ param.type_info.name }}, 4 | {%- elif param.name.lower_camel_case == 'type' %} 5 | typeVar {{ param.type_info.name }}, 6 | {%- elif param.type_info.is_primitive -%} 7 | {{ param.name.lower_camel_case }} {{ param.type_info.name }}, 8 | {%- elif param.type_info.is_repeated -%} 9 | {{ param.name.lower_camel_case }} {{ param.type_info.name }}, 10 | {%- else -%} 11 | {{ param.name.lower_camel_case }} *{{ param.type_info.name }}, 12 | {% endif %} 13 | {% endfor %} -------------------------------------------------------------------------------- /Sources/server_utility/server_utility.go: -------------------------------------------------------------------------------- 1 | package server_utility 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client ServerUtilityServiceClient 9 | } 10 | 11 | /* 12 | SendStatusText Sends a statustext. 13 | */ 14 | func (s *ServiceImpl) SendStatusText( 15 | ctx context.Context, 16 | 17 | typeVar StatusTextType, 18 | text string, 19 | 20 | ) (*SendStatusTextResponse, error) { 21 | request := &SendStatusTextRequest{ 22 | 23 | Type: typeVar, 24 | Text: text, 25 | } 26 | response, err := s.Client.SendStatusText(ctx, request) 27 | if err != nil { 28 | return nil, err 29 | } 30 | return response, nil 31 | } 32 | -------------------------------------------------------------------------------- /Sources/component_metadata_server/component_metadata_server.go: -------------------------------------------------------------------------------- 1 | package component_metadata_server 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client ComponentMetadataServerServiceClient 9 | } 10 | 11 | /* 12 | SetMetadata Provide metadata (can only be called once) 13 | */ 14 | func (s *ServiceImpl) SetMetadata( 15 | ctx context.Context, 16 | metadata []*Metadata, 17 | 18 | ) (*SetMetadataResponse, error) { 19 | request := &SetMetadataRequest{ 20 | Metadata: metadata, 21 | } 22 | response, err := s.Client.SetMetadata(ctx, request) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, nil 27 | } 28 | -------------------------------------------------------------------------------- /templates/object_init_macro.j2: -------------------------------------------------------------------------------- 1 | {% for param in params %} 2 | {%- if param.name.lower_camel_case == 'range' %} 3 | {{ param.name.upper_camel_case }}: rangeVar, 4 | {%- elif param.name.lower_camel_case == 'type' %} 5 | {{ param.name.upper_camel_case }}: typeVar, 6 | {%- elif param.type_info.is_primitive -%} 7 | {{ param.name.upper_camel_case }}: {{ param.name.lower_camel_case }}, 8 | {%- elif param.type_info.is_enum -%} 9 | {{ param.name.upper_camel_case }}: *{{ param.name.lower_camel_case }}, 10 | {%- else -%} 11 | {{ param.name.upper_camel_case }}: {{ param.name.lower_camel_case }}, 12 | {% endif %} 13 | {% endfor %} -------------------------------------------------------------------------------- /Sources/failure/failure.go: -------------------------------------------------------------------------------- 1 | package failure 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client FailureServiceClient 9 | } 10 | 11 | /* 12 | Inject Injects a failure. 13 | */ 14 | func (s *ServiceImpl) Inject( 15 | ctx context.Context, 16 | failureUnit *FailureUnit, 17 | 18 | failureType *FailureType, 19 | 20 | instance int32, 21 | 22 | ) (*InjectResponse, error) { 23 | request := &InjectRequest{ 24 | FailureUnit: *failureUnit, 25 | FailureType: *failureType, 26 | Instance: instance, 27 | } 28 | response, err := s.Client.Inject(ctx, request) 29 | if err != nil { 30 | return nil, err 31 | } 32 | return response, nil 33 | } 34 | -------------------------------------------------------------------------------- /Sources/ftp_server/ftp_server.go: -------------------------------------------------------------------------------- 1 | package ftp_server 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client FtpServerServiceClient 9 | } 10 | 11 | /* 12 | SetRootDir Set root directory. 13 | 14 | This is the directory that can then be accessed by a client. 15 | The directory needs to exist when this is called. 16 | The permissions are the same as the file permission for the user running the server. 17 | The root directory can't be changed while an FTP process is in progress. 18 | */ 19 | func (s *ServiceImpl) SetRootDir( 20 | ctx context.Context, 21 | path string, 22 | 23 | ) (*SetRootDirResponse, error) { 24 | request := &SetRootDirRequest{ 25 | Path: path, 26 | } 27 | response, err := s.Client.SetRootDir(ctx, request) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return response, nil 32 | } 33 | -------------------------------------------------------------------------------- /Sources/gripper/gripper.go: -------------------------------------------------------------------------------- 1 | package gripper 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client GripperServiceClient 9 | } 10 | 11 | /* 12 | Grab Gripper grab cargo. 13 | */ 14 | func (s *ServiceImpl) Grab( 15 | ctx context.Context, 16 | instance uint32, 17 | 18 | ) (*GrabResponse, error) { 19 | request := &GrabRequest{ 20 | Instance: instance, 21 | } 22 | response, err := s.Client.Grab(ctx, request) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, nil 27 | } 28 | 29 | /* 30 | Release Gripper release cargo. 31 | */ 32 | func (s *ServiceImpl) Release( 33 | ctx context.Context, 34 | instance uint32, 35 | 36 | ) (*ReleaseResponse, error) { 37 | request := &ReleaseRequest{ 38 | Instance: instance, 39 | } 40 | response, err := s.Client.Release(ctx, request) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return response, nil 45 | } 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MAVSDK-Go 2 | This package contains the Go wrapper based on gRPC for the MAVSDK. This is still work in progress so use at your own descretion. 3 | MAVSDK server (also called backend) needs to be running on the same system as this plugin. The Go Wrapper communicates using gRPC to the server. 4 | 5 | MAVSDK uses Google Protobuf based message definitions in the protobuf files. [MAVSDK-ProtoBuf](https://github.com/mavlink/MAVSDK-Proto) 6 | 7 | A example is also provided which contains example usage of the mavsdk-go package. 8 | 9 | 10 | ## Contributing 11 | For general users, it is enough to use the generated files as such. But in order to keep the sources updated based on the latest proto definitions it is required to generate the source file again. 12 | This can be done using the instructions from ```Contributing.md``` 13 | 14 | If you have any issues or questions, please feel free to open an issue in the repository. We will try to address them as soon as possible. 15 | 16 | Happy flying :) -------------------------------------------------------------------------------- /Sources/geofence/geofence.go: -------------------------------------------------------------------------------- 1 | package geofence 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client GeofenceServiceClient 9 | } 10 | 11 | /* 12 | UploadGeofence Upload geofences. 13 | 14 | Polygon and Circular geofences are uploaded to a drone. Once uploaded, the geofence will remain 15 | on the drone even if a connection is lost. 16 | */ 17 | func (s *ServiceImpl) UploadGeofence( 18 | ctx context.Context, 19 | geofenceData *GeofenceData, 20 | 21 | ) (*UploadGeofenceResponse, error) { 22 | request := &UploadGeofenceRequest{ 23 | GeofenceData: geofenceData, 24 | } 25 | response, err := s.Client.UploadGeofence(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | return response, nil 30 | } 31 | 32 | /* 33 | ClearGeofence Clear all geofences saved on the vehicle. 34 | */ 35 | func (s *ServiceImpl) ClearGeofence( 36 | ctx context.Context, 37 | 38 | ) (*ClearGeofenceResponse, error) { 39 | request := &ClearGeofenceRequest{} 40 | response, err := s.Client.ClearGeofence(ctx, request) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return response, nil 45 | } 46 | -------------------------------------------------------------------------------- /tools/Dockerfile: -------------------------------------------------------------------------------- 1 | # This is the docker file which is used to generate the code from proto buf files. 2 | FROM --platform=linux/amd64 ubuntu:22.04 3 | 4 | RUN apt-get update 5 | RUN apt-get install -y wget python3 python3-distutils python3-dev python3-pip 6 | RUN wget https://go.dev/dl/go1.24.4.linux-amd64.tar.gz 7 | RUN rm -rf /usr/local/go && tar -C /usr/local -xzf go1.24.4.linux-amd64.tar.gz 8 | ENV PATH $PATH:/usr/local/go/bin:/root/go/bin 9 | ENV PATH="$PATH:$(go env GOPATH)/bin" 10 | RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest 11 | RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest 12 | RUN go install golang.org/x/tools/cmd/goimports@latest 13 | 14 | # Step 4: Install the python protoc-gendcsdk plugin to generate the class 15 | RUN apt-get install -y -q python3-pip git 16 | RUN cd / && git clone https://github.com/mavlink/MAVSDK-Proto.git 17 | RUN cd /MAVSDK-Proto/pb_plugins && pip3 install -r requirements.txt && pip3 install -e . 18 | RUN pip3 install grpcio-tools==1.47.0 19 | RUN apt install protobuf-compiler -y 20 | ENV PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python 21 | 22 | ENTRYPOINT ["/bin/bash", "-l", "-c"] -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= 4 | golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 5 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 6 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 7 | golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= 8 | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 9 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= 10 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= 11 | google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= 12 | google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= 13 | google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= 14 | google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020, MAVSDK Development Team All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /templates/stream.j2: -------------------------------------------------------------------------------- 1 | {% include 'func_desc_macro.j2' %} 2 | func (a *ServiceImpl) {{ name.upper_camel_case }}( 3 | ctx context.Context, 4 | {% include 'func_param_macro.j2' %} 5 | ) (<-chan {% if return_type.is_repeated or return_type.is_primitive or return_type.is_enum %} {{ return_type.name }}, {% else %} *{{ return_type.name }}, {% endif %} error) { 6 | ch := make(chan {% if return_type.is_repeated or return_type.is_primitive or return_type.is_enum %} {{ return_type.name }} {% else %} *{{ return_type.name }} {% endif %}) 7 | request := &Subscribe{{ name.upper_camel_case }}Request{ 8 | {% include 'object_init_macro.j2' %} 9 | } 10 | stream, err := a.Client.Subscribe{{ name.upper_camel_case }}(ctx, request) 11 | if err != nil { 12 | return nil, err 13 | } 14 | go func() { 15 | defer close(ch) 16 | for { 17 | m := &{{ name.upper_camel_case }}Response{} 18 | err := stream.RecvMsg(m) 19 | if err == io.EOF { 20 | return 21 | } 22 | if err != nil { 23 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 24 | return 25 | } 26 | log.Fatalf("Unable to receive {{ name.upper_camel_case }} messages, err: %v", err) 27 | } 28 | ch <- m.Get{{ return_name.upper_camel_case }}() 29 | } 30 | }() 31 | return ch, nil 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Sources/shell/shell.go: -------------------------------------------------------------------------------- 1 | package shell 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client ShellServiceClient 14 | } 15 | 16 | /* 17 | Send Send a command line. 18 | */ 19 | func (s *ServiceImpl) Send( 20 | ctx context.Context, 21 | command string, 22 | 23 | ) (*SendResponse, error) { 24 | request := &SendRequest{ 25 | Command: command, 26 | } 27 | response, err := s.Client.Send(ctx, request) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return response, nil 32 | } 33 | 34 | /* 35 | Receive Receive feedback from a sent command line. 36 | 37 | This subscription needs to be made before a command line is sent, otherwise, no response will be sent. 38 | */ 39 | func (a *ServiceImpl) Receive( 40 | ctx context.Context, 41 | 42 | ) (<-chan string, error) { 43 | ch := make(chan string) 44 | request := &SubscribeReceiveRequest{} 45 | stream, err := a.Client.SubscribeReceive(ctx, request) 46 | if err != nil { 47 | return nil, err 48 | } 49 | go func() { 50 | defer close(ch) 51 | for { 52 | m := &ReceiveResponse{} 53 | err := stream.RecvMsg(m) 54 | if err == io.EOF { 55 | return 56 | } 57 | if err != nil { 58 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 59 | return 60 | } 61 | log.Fatalf("Unable to receive Receive messages, err: %v", err) 62 | } 63 | ch <- m.GetData() 64 | } 65 | }() 66 | return ch, nil 67 | } 68 | -------------------------------------------------------------------------------- /Sources/transponder/transponder.go: -------------------------------------------------------------------------------- 1 | package transponder 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client TransponderServiceClient 14 | } 15 | 16 | /* 17 | Transponder Subscribe to 'transponder' updates. 18 | */ 19 | func (a *ServiceImpl) Transponder( 20 | ctx context.Context, 21 | 22 | ) (<-chan *AdsbVehicle, error) { 23 | ch := make(chan *AdsbVehicle) 24 | request := &SubscribeTransponderRequest{} 25 | stream, err := a.Client.SubscribeTransponder(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | go func() { 30 | defer close(ch) 31 | for { 32 | m := &TransponderResponse{} 33 | err := stream.RecvMsg(m) 34 | if err == io.EOF { 35 | return 36 | } 37 | if err != nil { 38 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 39 | return 40 | } 41 | log.Fatalf("Unable to receive Transponder messages, err: %v", err) 42 | } 43 | ch <- m.GetTransponder() 44 | } 45 | }() 46 | return ch, nil 47 | } 48 | 49 | /* 50 | SetRateTransponder Set rate to 'transponder' updates. 51 | */ 52 | func (s *ServiceImpl) SetRateTransponder( 53 | ctx context.Context, 54 | rateHz float64, 55 | 56 | ) (*SetRateTransponderResponse, error) { 57 | request := &SetRateTransponderRequest{ 58 | RateHz: rateHz, 59 | } 60 | response, err := s.Client.SetRateTransponder(ctx, request) 61 | if err != nil { 62 | return nil, err 63 | } 64 | return response, nil 65 | } 66 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | More advanced user can also generate the files from the protobuf definition. In order to do this the go packages proto-gen-go and proto-gen-gorpc are required. 2 | This is already installed in the docker file available in tools/Dockerfile. 3 | 4 | Build this dockerfile using 5 | ```bash 6 | docker build . -t mavsdk 7 | ``` 8 | 9 | Run the image using the following command with the volume with MAVSDK-GO mounted in the docker. 10 | 11 | ```bash 12 | bash run_docker.bash 13 | ``` 14 | 15 | Then run the script ```generate_from_protos.bash``` to generate the plugins. The script is more or less self explanatory. 16 | 17 | 18 | Now the proto-gen-mavsdk can be used to generate the MAVSDK language related files using the jinja2 templates. 19 | In order to generate the plugin classes run the following command from the root of the MAVSDK-Go 20 | 21 | ```bash 22 | export TEMPLATE_PATH="$(pwd)/templates/" 23 | protoc --plugin=protoc-gen-custom=$(which protoc-gen-mavsdk) -I./proto/protos/action --custom_out=. --custom_opt=file-ext=go ./proto/protos/action/action.proto 24 | 25 | ``` 26 | ### Troubleshooting 27 | If you are using an ARM 64bit device to build the image you might experience the error listed below: 28 | 29 | ```bash 30 | qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory 31 | 32 | ``` 33 | 34 | If this happens use the below command that specifies the platform to use for the build: 35 | 36 | ```bash 37 | docker build . -t mavsdk --platform linux/x86_64 38 | 39 | ``` 40 | 41 | 42 | ## Note 43 | There was a problem generating the plugins in docker. If you get similar problems, please generate the plugins on a normal machine (ubuntu) -------------------------------------------------------------------------------- /Sources/core/core.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client CoreServiceClient 14 | } 15 | 16 | /* 17 | ConnectionState Subscribe to 'connection state' updates. 18 | */ 19 | func (a *ServiceImpl) ConnectionState( 20 | ctx context.Context, 21 | 22 | ) (<-chan *ConnectionState, error) { 23 | ch := make(chan *ConnectionState) 24 | request := &SubscribeConnectionStateRequest{} 25 | stream, err := a.Client.SubscribeConnectionState(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | go func() { 30 | defer close(ch) 31 | for { 32 | m := &ConnectionStateResponse{} 33 | err := stream.RecvMsg(m) 34 | if err == io.EOF { 35 | return 36 | } 37 | if err != nil { 38 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 39 | return 40 | } 41 | log.Fatalf("Unable to receive ConnectionState messages, err: %v", err) 42 | } 43 | ch <- m.GetConnectionState() 44 | } 45 | }() 46 | return ch, nil 47 | } 48 | 49 | /* 50 | SetMavlinkTimeout Set timeout of MAVLink transfers. 51 | 52 | The default timeout used is generally (0.5 seconds) seconds. 53 | If MAVSDK is used on the same host this timeout can be reduced, while 54 | if MAVSDK has to communicate over links with high latency it might 55 | need to be increased to prevent timeouts. 56 | */ 57 | func (s *ServiceImpl) SetMavlinkTimeout( 58 | ctx context.Context, 59 | timeoutS float64, 60 | 61 | ) (*SetMavlinkTimeoutResponse, error) { 62 | request := &SetMavlinkTimeoutRequest{ 63 | TimeoutS: timeoutS, 64 | } 65 | response, err := s.Client.SetMavlinkTimeout(ctx, request) 66 | if err != nil { 67 | return nil, err 68 | } 69 | return response, nil 70 | } 71 | -------------------------------------------------------------------------------- /Sources/manual_control/manual_control.go: -------------------------------------------------------------------------------- 1 | package manual_control 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client ManualControlServiceClient 9 | } 10 | 11 | /* 12 | StartPositionControl Start position control using e.g. joystick input. 13 | 14 | Requires manual control input to be sent regularly already. 15 | Requires a valid position using e.g. GPS, external vision, or optical flow. 16 | */ 17 | func (s *ServiceImpl) StartPositionControl( 18 | ctx context.Context, 19 | 20 | ) (*StartPositionControlResponse, error) { 21 | request := &StartPositionControlRequest{} 22 | response, err := s.Client.StartPositionControl(ctx, request) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, nil 27 | } 28 | 29 | /* 30 | StartAltitudeControl Start altitude control 31 | 32 | Requires manual control input to be sent regularly already. 33 | Does not require a valid position e.g. GPS. 34 | */ 35 | func (s *ServiceImpl) StartAltitudeControl( 36 | ctx context.Context, 37 | 38 | ) (*StartAltitudeControlResponse, error) { 39 | request := &StartAltitudeControlRequest{} 40 | response, err := s.Client.StartAltitudeControl(ctx, request) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return response, nil 45 | } 46 | 47 | /* 48 | SetManualControlInput Set manual control input 49 | 50 | The manual control input needs to be sent at a rate high enough to prevent 51 | triggering of RC loss, a good minimum rate is 10 Hz. 52 | */ 53 | func (s *ServiceImpl) SetManualControlInput( 54 | ctx context.Context, 55 | x float32, 56 | y float32, 57 | z float32, 58 | r float32, 59 | 60 | ) (*SetManualControlInputResponse, error) { 61 | request := &SetManualControlInputRequest{ 62 | X: x, 63 | Y: y, 64 | Z: z, 65 | R: r, 66 | } 67 | response, err := s.Client.SetManualControlInput(ctx, request) 68 | if err != nil { 69 | return nil, err 70 | } 71 | return response, nil 72 | } 73 | -------------------------------------------------------------------------------- /Sources/log_streaming/log_streaming.go: -------------------------------------------------------------------------------- 1 | package log_streaming 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client LogStreamingServiceClient 14 | } 15 | 16 | /* 17 | StartLogStreaming Start streaming logging data. 18 | */ 19 | func (s *ServiceImpl) StartLogStreaming( 20 | ctx context.Context, 21 | 22 | ) (*StartLogStreamingResponse, error) { 23 | request := &StartLogStreamingRequest{} 24 | response, err := s.Client.StartLogStreaming(ctx, request) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return response, nil 29 | } 30 | 31 | /* 32 | StopLogStreaming Stop streaming logging data. 33 | */ 34 | func (s *ServiceImpl) StopLogStreaming( 35 | ctx context.Context, 36 | 37 | ) (*StopLogStreamingResponse, error) { 38 | request := &StopLogStreamingRequest{} 39 | response, err := s.Client.StopLogStreaming(ctx, request) 40 | if err != nil { 41 | return nil, err 42 | } 43 | return response, nil 44 | } 45 | 46 | /* 47 | LogStreamingRaw Subscribe to logging messages 48 | */ 49 | func (a *ServiceImpl) LogStreamingRaw( 50 | ctx context.Context, 51 | 52 | ) (<-chan *LogStreamingRaw, error) { 53 | ch := make(chan *LogStreamingRaw) 54 | request := &SubscribeLogStreamingRawRequest{} 55 | stream, err := a.Client.SubscribeLogStreamingRaw(ctx, request) 56 | if err != nil { 57 | return nil, err 58 | } 59 | go func() { 60 | defer close(ch) 61 | for { 62 | m := &LogStreamingRawResponse{} 63 | err := stream.RecvMsg(m) 64 | if err == io.EOF { 65 | return 66 | } 67 | if err != nil { 68 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 69 | return 70 | } 71 | log.Fatalf("Unable to receive LogStreamingRaw messages, err: %v", err) 72 | } 73 | ch <- m.GetLoggingRaw() 74 | } 75 | }() 76 | return ch, nil 77 | } 78 | -------------------------------------------------------------------------------- /Sources/log_files/log_files.go: -------------------------------------------------------------------------------- 1 | package log_files 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client LogFilesServiceClient 14 | } 15 | 16 | /* 17 | GetEntries Get List of log files. 18 | */ 19 | func (s *ServiceImpl) GetEntries( 20 | ctx context.Context, 21 | 22 | ) (*GetEntriesResponse, error) { 23 | request := &GetEntriesRequest{} 24 | response, err := s.Client.GetEntries(ctx, request) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return response, nil 29 | } 30 | 31 | /* 32 | DownloadLogFile Download log file. 33 | */ 34 | func (a *ServiceImpl) DownloadLogFile( 35 | ctx context.Context, 36 | entry *Entry, 37 | 38 | path string, 39 | 40 | ) (<-chan *ProgressData, error) { 41 | ch := make(chan *ProgressData) 42 | request := &SubscribeDownloadLogFileRequest{ 43 | Entry: entry, 44 | 45 | Path: path, 46 | } 47 | stream, err := a.Client.SubscribeDownloadLogFile(ctx, request) 48 | if err != nil { 49 | return nil, err 50 | } 51 | go func() { 52 | defer close(ch) 53 | for { 54 | m := &DownloadLogFileResponse{} 55 | err := stream.RecvMsg(m) 56 | if err == io.EOF { 57 | return 58 | } 59 | if err != nil { 60 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 61 | return 62 | } 63 | log.Fatalf("Unable to receive DownloadLogFile messages, err: %v", err) 64 | } 65 | ch <- m.GetProgress() 66 | } 67 | }() 68 | return ch, nil 69 | } 70 | 71 | /* 72 | EraseAllLogFiles Erase all log files. 73 | */ 74 | func (s *ServiceImpl) EraseAllLogFiles( 75 | ctx context.Context, 76 | 77 | ) (*EraseAllLogFilesResponse, error) { 78 | request := &EraseAllLogFilesRequest{} 79 | response, err := s.Client.EraseAllLogFiles(ctx, request) 80 | if err != nil { 81 | return nil, err 82 | } 83 | return response, nil 84 | } 85 | -------------------------------------------------------------------------------- /Sources/mocap/mocap.go: -------------------------------------------------------------------------------- 1 | package mocap 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client MocapServiceClient 9 | } 10 | 11 | /* 12 | SetVisionPositionEstimate Send Global position/attitude estimate from a vision source. 13 | */ 14 | func (s *ServiceImpl) SetVisionPositionEstimate( 15 | ctx context.Context, 16 | visionPositionEstimate *VisionPositionEstimate, 17 | 18 | ) (*SetVisionPositionEstimateResponse, error) { 19 | request := &SetVisionPositionEstimateRequest{ 20 | VisionPositionEstimate: visionPositionEstimate, 21 | } 22 | response, err := s.Client.SetVisionPositionEstimate(ctx, request) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, nil 27 | } 28 | 29 | /* 30 | SetVisionSpeedEstimate Send Global speed estimate from a vision source. 31 | */ 32 | func (s *ServiceImpl) SetVisionSpeedEstimate( 33 | ctx context.Context, 34 | visionSpeedEstimate *VisionSpeedEstimate, 35 | 36 | ) (*SetVisionSpeedEstimateResponse, error) { 37 | request := &SetVisionSpeedEstimateRequest{ 38 | VisionSpeedEstimate: visionSpeedEstimate, 39 | } 40 | response, err := s.Client.SetVisionSpeedEstimate(ctx, request) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return response, nil 45 | } 46 | 47 | /* 48 | SetAttitudePositionMocap Send motion capture attitude and position. 49 | */ 50 | func (s *ServiceImpl) SetAttitudePositionMocap( 51 | ctx context.Context, 52 | attitudePositionMocap *AttitudePositionMocap, 53 | 54 | ) (*SetAttitudePositionMocapResponse, error) { 55 | request := &SetAttitudePositionMocapRequest{ 56 | AttitudePositionMocap: attitudePositionMocap, 57 | } 58 | response, err := s.Client.SetAttitudePositionMocap(ctx, request) 59 | if err != nil { 60 | return nil, err 61 | } 62 | return response, nil 63 | } 64 | 65 | /* 66 | SetOdometry Send odometry information with an external interface. 67 | */ 68 | func (s *ServiceImpl) SetOdometry( 69 | ctx context.Context, 70 | odometry *Odometry, 71 | 72 | ) (*SetOdometryResponse, error) { 73 | request := &SetOdometryRequest{ 74 | Odometry: odometry, 75 | } 76 | response, err := s.Client.SetOdometry(ctx, request) 77 | if err != nil { 78 | return nil, err 79 | } 80 | return response, nil 81 | } 82 | -------------------------------------------------------------------------------- /Sources/arm_authorizer_server/arm_authorizer_server.go: -------------------------------------------------------------------------------- 1 | package arm_authorizer_server 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client ArmAuthorizerServerServiceClient 14 | } 15 | 16 | /* 17 | ArmAuthorization Subscribe to arm authorization request messages. Each request received should respond to using RespondArmAuthorization 18 | */ 19 | func (a *ServiceImpl) ArmAuthorization( 20 | ctx context.Context, 21 | 22 | ) (<-chan uint32, error) { 23 | ch := make(chan uint32) 24 | request := &SubscribeArmAuthorizationRequest{} 25 | stream, err := a.Client.SubscribeArmAuthorization(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | go func() { 30 | defer close(ch) 31 | for { 32 | m := &ArmAuthorizationResponse{} 33 | err := stream.RecvMsg(m) 34 | if err == io.EOF { 35 | return 36 | } 37 | if err != nil { 38 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 39 | return 40 | } 41 | log.Fatalf("Unable to receive ArmAuthorization messages, err: %v", err) 42 | } 43 | ch <- m.GetSystemId() 44 | } 45 | }() 46 | return ch, nil 47 | } 48 | 49 | /* 50 | AcceptArmAuthorization Authorize arm for the specific time 51 | */ 52 | func (s *ServiceImpl) AcceptArmAuthorization( 53 | ctx context.Context, 54 | validTimeS int32, 55 | 56 | ) (*AcceptArmAuthorizationResponse, error) { 57 | request := &AcceptArmAuthorizationRequest{ 58 | ValidTimeS: validTimeS, 59 | } 60 | response, err := s.Client.AcceptArmAuthorization(ctx, request) 61 | if err != nil { 62 | return nil, err 63 | } 64 | return response, nil 65 | } 66 | 67 | /* 68 | RejectArmAuthorization Reject arm authorization request 69 | */ 70 | func (s *ServiceImpl) RejectArmAuthorization( 71 | ctx context.Context, 72 | temporarily bool, 73 | reason *RejectionReason, 74 | 75 | extraInfo int32, 76 | 77 | ) (*RejectArmAuthorizationResponse, error) { 78 | request := &RejectArmAuthorizationRequest{ 79 | Temporarily: temporarily, 80 | Reason: *reason, 81 | ExtraInfo: extraInfo, 82 | } 83 | response, err := s.Client.RejectArmAuthorization(ctx, request) 84 | if err != nil { 85 | return nil, err 86 | } 87 | return response, nil 88 | } 89 | -------------------------------------------------------------------------------- /Sources/follow_me/follow_me.go: -------------------------------------------------------------------------------- 1 | package follow_me 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client FollowMeServiceClient 9 | } 10 | 11 | /* 12 | GetConfig Get current configuration. 13 | */ 14 | func (s *ServiceImpl) GetConfig( 15 | ctx context.Context, 16 | 17 | ) (*GetConfigResponse, error) { 18 | request := &GetConfigRequest{} 19 | response, err := s.Client.GetConfig(ctx, request) 20 | if err != nil { 21 | return nil, err 22 | } 23 | return response, nil 24 | } 25 | 26 | /* 27 | SetConfig Apply configuration by sending it to the system. 28 | */ 29 | func (s *ServiceImpl) SetConfig( 30 | ctx context.Context, 31 | config *Config, 32 | 33 | ) (*SetConfigResponse, error) { 34 | request := &SetConfigRequest{ 35 | Config: config, 36 | } 37 | response, err := s.Client.SetConfig(ctx, request) 38 | if err != nil { 39 | return nil, err 40 | } 41 | return response, nil 42 | } 43 | 44 | /* 45 | IsActive Check if FollowMe is active. 46 | */ 47 | func (s *ServiceImpl) IsActive( 48 | ctx context.Context, 49 | 50 | ) (*IsActiveResponse, error) { 51 | request := &IsActiveRequest{} 52 | response, err := s.Client.IsActive(ctx, request) 53 | if err != nil { 54 | return nil, err 55 | } 56 | return response, nil 57 | } 58 | 59 | /* 60 | SetTargetLocation Set location of the moving target. 61 | */ 62 | func (s *ServiceImpl) SetTargetLocation( 63 | ctx context.Context, 64 | location *TargetLocation, 65 | 66 | ) (*SetTargetLocationResponse, error) { 67 | request := &SetTargetLocationRequest{ 68 | Location: location, 69 | } 70 | response, err := s.Client.SetTargetLocation(ctx, request) 71 | if err != nil { 72 | return nil, err 73 | } 74 | return response, nil 75 | } 76 | 77 | /* 78 | GetLastLocation Get the last location of the target. 79 | */ 80 | func (s *ServiceImpl) GetLastLocation( 81 | ctx context.Context, 82 | 83 | ) (*GetLastLocationResponse, error) { 84 | request := &GetLastLocationRequest{} 85 | response, err := s.Client.GetLastLocation(ctx, request) 86 | if err != nil { 87 | return nil, err 88 | } 89 | return response, nil 90 | } 91 | 92 | /* 93 | Start Start FollowMe mode. 94 | */ 95 | func (s *ServiceImpl) Start( 96 | ctx context.Context, 97 | 98 | ) (*StartResponse, error) { 99 | request := &StartRequest{} 100 | response, err := s.Client.Start(ctx, request) 101 | if err != nil { 102 | return nil, err 103 | } 104 | return response, nil 105 | } 106 | 107 | /* 108 | Stop Stop FollowMe mode. 109 | */ 110 | func (s *ServiceImpl) Stop( 111 | ctx context.Context, 112 | 113 | ) (*StopResponse, error) { 114 | request := &StopRequest{} 115 | response, err := s.Client.Stop(ctx, request) 116 | if err != nil { 117 | return nil, err 118 | } 119 | return response, nil 120 | } 121 | -------------------------------------------------------------------------------- /Sources/component_metadata/component_metadata.go: -------------------------------------------------------------------------------- 1 | package component_metadata 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client ComponentMetadataServiceClient 14 | } 15 | 16 | /* 17 | RequestComponent Request metadata from a specific component. This is used to start requesting metadata from a component. 18 | 19 | The metadata can later be accessed via subscription (see below) or GetMetadata. 20 | */ 21 | func (s *ServiceImpl) RequestComponent( 22 | ctx context.Context, 23 | compid uint32, 24 | 25 | ) (*RequestComponentResponse, error) { 26 | request := &RequestComponentRequest{ 27 | Compid: compid, 28 | } 29 | response, err := s.Client.RequestComponent(ctx, request) 30 | if err != nil { 31 | return nil, err 32 | } 33 | return response, nil 34 | } 35 | 36 | /* 37 | RequestAutopilotComponent Request metadata from the autopilot component. This is used to start requesting metadata from the autopilot. 38 | 39 | The metadata can later be accessed via subscription (see below) or GetMetadata. 40 | */ 41 | func (s *ServiceImpl) RequestAutopilotComponent( 42 | ctx context.Context, 43 | 44 | ) (*RequestAutopilotComponentResponse, error) { 45 | request := &RequestAutopilotComponentRequest{} 46 | response, err := s.Client.RequestAutopilotComponent(ctx, request) 47 | if err != nil { 48 | return nil, err 49 | } 50 | return response, nil 51 | } 52 | 53 | /* 54 | MetadataAvailable Register a callback that gets called when metadata is available 55 | */ 56 | func (a *ServiceImpl) MetadataAvailable( 57 | ctx context.Context, 58 | 59 | ) (<-chan *MetadataUpdate, error) { 60 | ch := make(chan *MetadataUpdate) 61 | request := &SubscribeMetadataAvailableRequest{} 62 | stream, err := a.Client.SubscribeMetadataAvailable(ctx, request) 63 | if err != nil { 64 | return nil, err 65 | } 66 | go func() { 67 | defer close(ch) 68 | for { 69 | m := &MetadataAvailableResponse{} 70 | err := stream.RecvMsg(m) 71 | if err == io.EOF { 72 | return 73 | } 74 | if err != nil { 75 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 76 | return 77 | } 78 | log.Fatalf("Unable to receive MetadataAvailable messages, err: %v", err) 79 | } 80 | ch <- m.GetData() 81 | } 82 | }() 83 | return ch, nil 84 | } 85 | 86 | /* 87 | GetMetadata Access metadata. This can be used if you know the metadata is available already, otherwise use 88 | 89 | the subscription to get notified when it becomes available. 90 | */ 91 | func (s *ServiceImpl) GetMetadata( 92 | ctx context.Context, 93 | compid uint32, 94 | metadataType *MetadataType, 95 | 96 | ) (*GetMetadataResponse, error) { 97 | request := &GetMetadataRequest{ 98 | Compid: compid, 99 | MetadataType: *metadataType, 100 | } 101 | response, err := s.Client.GetMetadata(ctx, request) 102 | if err != nil { 103 | return nil, err 104 | } 105 | return response, nil 106 | } 107 | -------------------------------------------------------------------------------- /tools/generate_only_plugins.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | command -v protoc || { echo >&2 "Protobuf needs to be installed (e.g. '$ apt install protobuf-compiler') for this script to run!"; exit 1; } 6 | 7 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 8 | PROTO_DIR=${PROTO_DIR:-"${SCRIPT_DIR}/../proto/protos"} 9 | OUTPUT_DIR=${OUTPUT_DIR:-"${SCRIPT_DIR}/../Sources/"} 10 | PROTO_DIR_TMP=${PROTO_DIR_TMP:-"${SCRIPT_DIR}/tmp/protos"} 11 | export TEMPLATE_PATH="$(pwd)/../templates/" 12 | 13 | PLUGIN_LIST="action failure manual_control server_utility action_server follow_me shell 14 | arm_authorizer_server ftp mission telemetry calibration ftp_server mission_raw telemetry_server 15 | camera geofence mission_raw_server transponder camera_server gimbal mocap tune component_metadata 16 | gripper offboard winch component_metadata_server info param core log_files param_server log_streaming rtk" 17 | 18 | mkdir -p ${PROTO_DIR_TMP} 19 | cp -r ${PROTO_DIR}/* ${PROTO_DIR_TMP} 20 | 21 | for plugin in ${PLUGIN_LIST}; do 22 | sed -i "/java_package.*/c option go_package = \".;${plugin}\";" ${PROTO_DIR_TMP}/$plugin/$plugin.proto 23 | cp ${PROTO_DIR_TMP}/mavsdk_options.proto ${PROTO_DIR_TMP}/$plugin/mavsdk_options.proto 24 | sed -i "/java_package.*/c option go_package = \".;${plugin}\";" ${PROTO_DIR_TMP}/$plugin/mavsdk_options.proto 25 | done 26 | 27 | PROTO_DIR=${PROTO_DIR_TMP} 28 | 29 | function snake_case_to_camel_case { 30 | echo $1 | awk -v FS="_" -v OFS="" '{for (i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)} 1' 31 | } 32 | 33 | for plugin in ${PLUGIN_LIST}; do 34 | echo "+=> Doing $plugin" 35 | python3 -m grpc_tools.protoc --plugin=protoc-gen-custom=$(which protoc-gen-mavsdk) -I${PROTO_DIR}/$plugin --custom_out=${OUTPUT_DIR}/$plugin --custom_opt=file_ext=go ${plugin}.proto 36 | # if the output file name is CamelCase, we need to rename it to snake_case 37 | # Construct the expected CamelCase filename 38 | camel_case_filename="$(snake_case_to_camel_case "$plugin").go" 39 | actual_file_path="${OUTPUT_DIR}/$plugin/$camel_case_filename" 40 | new_file_path="${OUTPUT_DIR}/$plugin/${plugin}.go" 41 | temp_file_path="${OUTPUT_DIR}/$plugin/temp.go" 42 | 43 | # Check if the plugin is in snake_case and if the corresponding file exists 44 | if [[ -f "$actual_file_path" ]]; then 45 | echo "Renaming $actual_file_path to $new_file_path" 46 | 47 | # Move the original CamelCase file to a temporary name 48 | cat "$actual_file_path" > "$temp_file_path" 49 | # Remove the original CamelCase file 50 | rm "$actual_file_path" 51 | # Rename the temporary file to the new name 52 | mv "$temp_file_path" "$new_file_path" 53 | 54 | fi 55 | done 56 | 57 | # Remove the temp directory. 58 | rm -rf ${PROTO_DIR_TMP} 59 | 60 | # Navigate to OUTPUT_DIR and run the commands 61 | if cd "$OUTPUT_DIR"; then 62 | echo "Running goimports..." 63 | goimports -w . 64 | 65 | echo "Running go fmt..." 66 | go fmt ./... || { echo "go fmt failed"; exit 1; } 67 | else 68 | echo "Error: Could not navigate to OUTPUT_DIR: $OUTPUT_DIR" 69 | exit 1 70 | fi 71 | -------------------------------------------------------------------------------- /Sources/info/info.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client InfoServiceClient 14 | } 15 | 16 | /* 17 | GetFlightInformation Get flight information of the system. 18 | */ 19 | func (s *ServiceImpl) GetFlightInformation( 20 | ctx context.Context, 21 | 22 | ) (*GetFlightInformationResponse, error) { 23 | request := &GetFlightInformationRequest{} 24 | response, err := s.Client.GetFlightInformation(ctx, request) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return response, nil 29 | } 30 | 31 | /* 32 | GetIdentification Get the identification of the system. 33 | */ 34 | func (s *ServiceImpl) GetIdentification( 35 | ctx context.Context, 36 | 37 | ) (*GetIdentificationResponse, error) { 38 | request := &GetIdentificationRequest{} 39 | response, err := s.Client.GetIdentification(ctx, request) 40 | if err != nil { 41 | return nil, err 42 | } 43 | return response, nil 44 | } 45 | 46 | /* 47 | GetProduct Get product information of the system. 48 | */ 49 | func (s *ServiceImpl) GetProduct( 50 | ctx context.Context, 51 | 52 | ) (*GetProductResponse, error) { 53 | request := &GetProductRequest{} 54 | response, err := s.Client.GetProduct(ctx, request) 55 | if err != nil { 56 | return nil, err 57 | } 58 | return response, nil 59 | } 60 | 61 | /* 62 | GetVersion Get the version information of the system. 63 | */ 64 | func (s *ServiceImpl) GetVersion( 65 | ctx context.Context, 66 | 67 | ) (*GetVersionResponse, error) { 68 | request := &GetVersionRequest{} 69 | response, err := s.Client.GetVersion(ctx, request) 70 | if err != nil { 71 | return nil, err 72 | } 73 | return response, nil 74 | } 75 | 76 | /* 77 | GetSpeedFactor Get the speed factor of a simulation (with lockstep a simulation can run faster or slower than realtime). 78 | */ 79 | func (s *ServiceImpl) GetSpeedFactor( 80 | ctx context.Context, 81 | 82 | ) (*GetSpeedFactorResponse, error) { 83 | request := &GetSpeedFactorRequest{} 84 | response, err := s.Client.GetSpeedFactor(ctx, request) 85 | if err != nil { 86 | return nil, err 87 | } 88 | return response, nil 89 | } 90 | 91 | /* 92 | FlightInformation Subscribe to 'flight information' updates. 93 | */ 94 | func (a *ServiceImpl) FlightInformation( 95 | ctx context.Context, 96 | 97 | ) (<-chan *FlightInfo, error) { 98 | ch := make(chan *FlightInfo) 99 | request := &SubscribeFlightInformationRequest{} 100 | stream, err := a.Client.SubscribeFlightInformation(ctx, request) 101 | if err != nil { 102 | return nil, err 103 | } 104 | go func() { 105 | defer close(ch) 106 | for { 107 | m := &FlightInformationResponse{} 108 | err := stream.RecvMsg(m) 109 | if err == io.EOF { 110 | return 111 | } 112 | if err != nil { 113 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 114 | return 115 | } 116 | log.Fatalf("Unable to receive FlightInformation messages, err: %v", err) 117 | } 118 | ch <- m.GetFlightInfo() 119 | } 120 | }() 121 | return ch, nil 122 | } 123 | -------------------------------------------------------------------------------- /Sources/mission_raw_server/mission_raw_server.go: -------------------------------------------------------------------------------- 1 | package mission_raw_server 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client MissionRawServerServiceClient 14 | } 15 | 16 | /* 17 | IncomingMission Subscribe to when a new mission is uploaded (asynchronous). 18 | */ 19 | func (a *ServiceImpl) IncomingMission( 20 | ctx context.Context, 21 | 22 | ) (<-chan *MissionPlan, error) { 23 | ch := make(chan *MissionPlan) 24 | request := &SubscribeIncomingMissionRequest{} 25 | stream, err := a.Client.SubscribeIncomingMission(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | go func() { 30 | defer close(ch) 31 | for { 32 | m := &IncomingMissionResponse{} 33 | err := stream.RecvMsg(m) 34 | if err == io.EOF { 35 | return 36 | } 37 | if err != nil { 38 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 39 | return 40 | } 41 | log.Fatalf("Unable to receive IncomingMission messages, err: %v", err) 42 | } 43 | ch <- m.GetMissionPlan() 44 | } 45 | }() 46 | return ch, nil 47 | } 48 | 49 | /* 50 | CurrentItemChanged Subscribe to when a new current item is set 51 | */ 52 | func (a *ServiceImpl) CurrentItemChanged( 53 | ctx context.Context, 54 | 55 | ) (<-chan *MissionItem, error) { 56 | ch := make(chan *MissionItem) 57 | request := &SubscribeCurrentItemChangedRequest{} 58 | stream, err := a.Client.SubscribeCurrentItemChanged(ctx, request) 59 | if err != nil { 60 | return nil, err 61 | } 62 | go func() { 63 | defer close(ch) 64 | for { 65 | m := &CurrentItemChangedResponse{} 66 | err := stream.RecvMsg(m) 67 | if err == io.EOF { 68 | return 69 | } 70 | if err != nil { 71 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 72 | return 73 | } 74 | log.Fatalf("Unable to receive CurrentItemChanged messages, err: %v", err) 75 | } 76 | ch <- m.GetMissionItem() 77 | } 78 | }() 79 | return ch, nil 80 | } 81 | 82 | /* 83 | SetCurrentItemComplete Set Current item as completed 84 | */ 85 | func (s *ServiceImpl) SetCurrentItemComplete( 86 | ctx context.Context, 87 | 88 | ) (*SetCurrentItemCompleteResponse, error) { 89 | request := &SetCurrentItemCompleteRequest{} 90 | response, err := s.Client.SetCurrentItemComplete(ctx, request) 91 | if err != nil { 92 | return nil, err 93 | } 94 | return response, nil 95 | } 96 | 97 | /* 98 | ClearAll Subscribe when a MISSION_CLEAR_ALL is received 99 | */ 100 | func (a *ServiceImpl) ClearAll( 101 | ctx context.Context, 102 | 103 | ) (<-chan uint32, error) { 104 | ch := make(chan uint32) 105 | request := &SubscribeClearAllRequest{} 106 | stream, err := a.Client.SubscribeClearAll(ctx, request) 107 | if err != nil { 108 | return nil, err 109 | } 110 | go func() { 111 | defer close(ch) 112 | for { 113 | m := &ClearAllResponse{} 114 | err := stream.RecvMsg(m) 115 | if err == io.EOF { 116 | return 117 | } 118 | if err != nil { 119 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 120 | return 121 | } 122 | log.Fatalf("Unable to receive ClearAll messages, err: %v", err) 123 | } 124 | ch <- m.GetClearType() 125 | } 126 | }() 127 | return ch, nil 128 | } 129 | -------------------------------------------------------------------------------- /example/example.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "os" 8 | 9 | "github.com/mavlink/MAVSDK-Go/Sources/action" 10 | "github.com/mavlink/MAVSDK-Go/Sources/core" 11 | "github.com/mavlink/MAVSDK-Go/Sources/geofence" 12 | "github.com/mavlink/MAVSDK-Go/Sources/telemetry" 13 | "google.golang.org/grpc" 14 | "google.golang.org/grpc/credentials/insecure" 15 | ) 16 | 17 | // Drone creates a drone object to interact with drone related plugins 18 | type Drone struct { 19 | port string 20 | mavsdkServer string 21 | action action.ServiceImpl 22 | core core.ServiceImpl 23 | telemetry telemetry.ServiceImpl 24 | geofence geofence.ServiceImpl 25 | } 26 | 27 | // Connect Starts a mavsdk server and create a connection to it 28 | func (s *Drone) Connect() { 29 | grpcConnection := s.connectToMAVSDKServer() 30 | s.InitPlugins(grpcConnection) 31 | 32 | } 33 | 34 | // InitPlugins initializes all the plugins 35 | func (s *Drone) InitPlugins(cc *grpc.ClientConn) { 36 | 37 | s.telemetry = telemetry.ServiceImpl{ 38 | Client: telemetry.NewTelemetryServiceClient(cc), 39 | } 40 | s.core = core.ServiceImpl{ 41 | Client: core.NewCoreServiceClient(cc), 42 | } 43 | s.action = action.ServiceImpl{ 44 | Client: action.NewActionServiceClient(cc), 45 | } 46 | s.action = action.ServiceImpl{ 47 | Client: action.NewActionServiceClient(cc), 48 | } 49 | s.geofence = geofence.ServiceImpl{ 50 | Client: geofence.NewGeofenceServiceClient(cc), 51 | } 52 | } 53 | 54 | func (s *Drone) connectToMAVSDKServer() *grpc.ClientConn { 55 | dialoption := grpc.WithTransportCredentials(insecure.NewCredentials()) 56 | 57 | serverAddr := s.mavsdkServer + ":" + s.port 58 | cc, err := grpc.NewClient(serverAddr, dialoption) 59 | if err != nil { 60 | fmt.Printf("Error while dialing %v", err) 61 | } 62 | grpc.ConnectionTimeout(5) 63 | return cc 64 | } 65 | 66 | func main() { 67 | drone := &Drone{port: "50051", mavsdkServer: "127.0.0.1"} 68 | drone.Connect() 69 | if _, err := drone.action.Arm(context.Background()); err != nil { 70 | log.Fatalf("Error while arming %v", err) 71 | } 72 | if _, err := drone.action.Takeoff(context.Background()); err != nil { 73 | log.Fatalf("Error while taking off %v", err) 74 | } 75 | if _, err := drone.action.Land(context.Background()); err != nil { 76 | log.Fatalf("Error while landing %v", err) 77 | } 78 | if _, err := drone.core.ConnectionState(context.Background()); err != nil { 79 | log.Fatalf("Error while getting connection state %v", err) 80 | } 81 | lat := 47.3977508 82 | lon := 8.5456074 83 | p1 := &geofence.Point{ 84 | LatitudeDeg: lat - 0.0001, 85 | LongitudeDeg: lon - 0.0001, 86 | } 87 | p2 := &geofence.Point{ 88 | LatitudeDeg: lat + 0.0001, 89 | LongitudeDeg: lon - 0.0001, 90 | } 91 | p3 := &geofence.Point{ 92 | LatitudeDeg: lat + 0.0001, 93 | LongitudeDeg: lon + 0.0001, 94 | } 95 | p4 := &geofence.Point{ 96 | LatitudeDeg: lat - 0.0001, 97 | LongitudeDeg: lon + 0.0001, 98 | } 99 | // this is not a test or verification package. this only checks the sanity of geofence api 100 | polygon := &geofence.Polygon{ 101 | Points: []*geofence.Point{p1, p2, p3, p4}, 102 | FenceType: geofence.FenceType_FENCE_TYPE_EXCLUSION} 103 | response, err := drone.geofence.UploadGeofence(context.Background(), &geofence.GeofenceData{ 104 | Polygons: []*geofence.Polygon{polygon}, 105 | }) 106 | if err != nil { 107 | log.Print(err.Error()) 108 | os.Exit(1) 109 | } 110 | log.Printf("response %v", response) 111 | } 112 | -------------------------------------------------------------------------------- /Sources/param/param.go: -------------------------------------------------------------------------------- 1 | package param 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client ParamServiceClient 9 | } 10 | 11 | /* 12 | GetParamInt Get an int parameter. 13 | 14 | If the type is wrong, the result will be `WRONG_TYPE`. 15 | */ 16 | func (s *ServiceImpl) GetParamInt( 17 | ctx context.Context, 18 | name string, 19 | 20 | ) (*GetParamIntResponse, error) { 21 | request := &GetParamIntRequest{ 22 | Name: name, 23 | } 24 | response, err := s.Client.GetParamInt(ctx, request) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return response, nil 29 | } 30 | 31 | /* 32 | SetParamInt Set an int parameter. 33 | 34 | If the type is wrong, the result will be `WRONG_TYPE`. 35 | */ 36 | func (s *ServiceImpl) SetParamInt( 37 | ctx context.Context, 38 | name string, 39 | value int32, 40 | 41 | ) (*SetParamIntResponse, error) { 42 | request := &SetParamIntRequest{ 43 | Name: name, 44 | Value: value, 45 | } 46 | response, err := s.Client.SetParamInt(ctx, request) 47 | if err != nil { 48 | return nil, err 49 | } 50 | return response, nil 51 | } 52 | 53 | /* 54 | GetParamFloat Get a float parameter. 55 | 56 | If the type is wrong, the result will be `WRONG_TYPE`. 57 | */ 58 | func (s *ServiceImpl) GetParamFloat( 59 | ctx context.Context, 60 | name string, 61 | 62 | ) (*GetParamFloatResponse, error) { 63 | request := &GetParamFloatRequest{ 64 | Name: name, 65 | } 66 | response, err := s.Client.GetParamFloat(ctx, request) 67 | if err != nil { 68 | return nil, err 69 | } 70 | return response, nil 71 | } 72 | 73 | /* 74 | SetParamFloat Set a float parameter. 75 | 76 | If the type is wrong, the result will be `WRONG_TYPE`. 77 | */ 78 | func (s *ServiceImpl) SetParamFloat( 79 | ctx context.Context, 80 | name string, 81 | value float32, 82 | 83 | ) (*SetParamFloatResponse, error) { 84 | request := &SetParamFloatRequest{ 85 | Name: name, 86 | Value: value, 87 | } 88 | response, err := s.Client.SetParamFloat(ctx, request) 89 | if err != nil { 90 | return nil, err 91 | } 92 | return response, nil 93 | } 94 | 95 | /* 96 | GetParamCustom Get a custom parameter. 97 | 98 | If the type is wrong, the result will be `WRONG_TYPE`. 99 | */ 100 | func (s *ServiceImpl) GetParamCustom( 101 | ctx context.Context, 102 | name string, 103 | 104 | ) (*GetParamCustomResponse, error) { 105 | request := &GetParamCustomRequest{ 106 | Name: name, 107 | } 108 | response, err := s.Client.GetParamCustom(ctx, request) 109 | if err != nil { 110 | return nil, err 111 | } 112 | return response, nil 113 | } 114 | 115 | /* 116 | SetParamCustom Set a custom parameter. 117 | 118 | If the type is wrong, the result will be `WRONG_TYPE`. 119 | */ 120 | func (s *ServiceImpl) SetParamCustom( 121 | ctx context.Context, 122 | name string, 123 | value string, 124 | 125 | ) (*SetParamCustomResponse, error) { 126 | request := &SetParamCustomRequest{ 127 | Name: name, 128 | Value: value, 129 | } 130 | response, err := s.Client.SetParamCustom(ctx, request) 131 | if err != nil { 132 | return nil, err 133 | } 134 | return response, nil 135 | } 136 | 137 | /* 138 | GetAllParams Get all parameters. 139 | */ 140 | func (s *ServiceImpl) GetAllParams( 141 | ctx context.Context, 142 | 143 | ) (*GetAllParamsResponse, error) { 144 | request := &GetAllParamsRequest{} 145 | response, err := s.Client.GetAllParams(ctx, request) 146 | if err != nil { 147 | return nil, err 148 | } 149 | return response, nil 150 | } 151 | 152 | /* 153 | SelectComponent Select component ID of parameter component to talk to and param protocol version. 154 | 155 | Default is the autopilot component (1), and Version (0). 156 | */ 157 | func (s *ServiceImpl) SelectComponent( 158 | ctx context.Context, 159 | componentId int32, 160 | protocolVersion *ProtocolVersion, 161 | 162 | ) (*SelectComponentResponse, error) { 163 | request := &SelectComponentRequest{ 164 | ComponentId: componentId, 165 | ProtocolVersion: *protocolVersion, 166 | } 167 | response, err := s.Client.SelectComponent(ctx, request) 168 | if err != nil { 169 | return nil, err 170 | } 171 | return response, nil 172 | } 173 | -------------------------------------------------------------------------------- /tools/generate_from_protos.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | function snake_case_to_camel_case { 6 | echo $1 | awk -v FS="_" -v OFS="" '{for (i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)} 1' 7 | } 8 | 9 | command -v protoc || { echo >&2 "Protobuf needs to be installed (e.g. '$ apt install protobuf-compiler') for this script to run!"; exit 1; } 10 | 11 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 12 | PROTO_DIR=${PROTO_DIR:-"${SCRIPT_DIR}/../proto/protos"} 13 | OUTPUT_DIR=${OUTPUT_DIR:-"${SCRIPT_DIR}/../Sources/"} 14 | PROTO_DIR_TMP=${PROTO_DIR_TMP:-"${SCRIPT_DIR}/tmp/protos"} 15 | export TEMPLATE_PATH="$(pwd)/../templates/" 16 | 17 | PLUGIN_LIST="action failure manual_control server_utility action_server follow_me shell 18 | arm_authorizer_server ftp mission telemetry calibration ftp_server mission_raw telemetry_server 19 | camera geofence mission_raw_server transponder camera_server gimbal mocap tune component_metadata 20 | gripper offboard winch component_metadata_server info param core log_files param_server log_streaming rtk" 21 | 22 | echo "Plugin List consist of: " ${PLUGIN_LIST} 23 | rm -rf ${PROTO_DIR_TMP} 24 | mkdir -p ${PROTO_DIR_TMP} 25 | cp -r ${PROTO_DIR}/* ${PROTO_DIR_TMP} 26 | 27 | for plugin in ${PLUGIN_LIST}; do 28 | sed -i "/java_package.*/c option go_package = \".;${plugin}\";" ${PROTO_DIR_TMP}/$plugin/$plugin.proto 29 | cp ${PROTO_DIR_TMP}/mavsdk_options.proto ${PROTO_DIR_TMP}/$plugin/mavsdk_options.proto 30 | sed -i "/java_package.*/c option go_package = \".;${plugin}\";" ${PROTO_DIR_TMP}/$plugin/mavsdk_options.proto 31 | done 32 | 33 | PROTO_DIR=${PROTO_DIR_TMP} 34 | 35 | if [ ! -d ${PROTO_DIR} ]; then 36 | echo "Script is not in the right location! It will look for the proto files in '${PROTO_DIR}', which doesn't exist!" 37 | 38 | exit 1 39 | fi 40 | 41 | if [ ! -d ${OUTPUT_DIR} ]; then 42 | echo "Script is not in the right location! It is made to generate the files in '${OUTPUT_DIR}', which doesn't exist!" 43 | 44 | exit 1 45 | fi 46 | 47 | echo "-------------------------------" 48 | echo "Generating pb and grpc.pb files" 49 | echo "-------------------------------" 50 | 51 | GO_GEN_CMD="/root/go/bin/protoc-gen-go" 52 | GO_GEN_RPC_CMD="/root/go/bin/protoc-gen-go-grpc" 53 | 54 | echo "Generating proto definitions." 55 | # Generate the message and service definitions using grpc plugins. 56 | for plugin in ${PLUGIN_LIST}; do 57 | mkdir -p ${OUTPUT_DIR}/$plugin 58 | protoc ${plugin}.proto -I${PROTO_DIR}/$plugin --go_out=${OUTPUT_DIR}/$plugin --gogrpc_out=${OUTPUT_DIR}/$plugin --plugin=protoc-gen-go=${GO_GEN_CMD} --plugin=protoc-gen-gogrpc=${GO_GEN_RPC_CMD} 59 | ## remove file_mavsdk_options_proto_init() line from generated file 60 | sed -i '/file_mavsdk_options_proto_init/d' ${OUTPUT_DIR}/$plugin/${plugin}.pb.go 61 | done 62 | 63 | echo "Generating final plugins." 64 | # Generate the final plugins 65 | for plugin in ${PLUGIN_LIST}; do 66 | echo "+=> Doing $plugin" 67 | python3 -m grpc_tools.protoc --plugin=protoc-gen-custom=$(which protoc-gen-mavsdk) -I${PROTO_DIR}/$plugin --custom_out=${OUTPUT_DIR}/$plugin --custom_opt=file_ext=go ${plugin}.proto 68 | # Again move generated file to its place. 69 | camel_case_filename="$(snake_case_to_camel_case "$plugin").go" 70 | actual_file_path="${OUTPUT_DIR}/$plugin/$camel_case_filename" 71 | new_file_path="${OUTPUT_DIR}/$plugin/${plugin}.go" 72 | temp_file_path="${OUTPUT_DIR}/$plugin/temp.go" 73 | 74 | # Check if the plugin is in snake_case and if the corresponding file exists 75 | if [[ -f "$actual_file_path" ]]; then 76 | echo "Renaming $actual_file_path to $new_file_path" 77 | 78 | # Move the original CamelCase file to a temporary name 79 | mv "$actual_file_path" "$temp_file_path" 80 | 81 | # Rename the temporary file to the new name 82 | mv "$temp_file_path" "$new_file_path" 83 | 84 | fi 85 | done 86 | 87 | # Remove the temp directory. 88 | rm -rf ${PROTO_DIR_TMP} 89 | 90 | # Navigate to OUTPUT_DIR and run the commands 91 | if cd "$OUTPUT_DIR"; then 92 | echo "Running goimports..." 93 | goimports -w . 94 | 95 | echo "Running go fmt..." 96 | go fmt ./... || { echo "go fmt failed"; exit 1; } 97 | else 98 | echo "Error: Could not navigate to OUTPUT_DIR: $OUTPUT_DIR" 99 | exit 1 100 | fi 101 | -------------------------------------------------------------------------------- /Sources/rtk/rtk_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: rtk.proto 6 | 7 | package rtk 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | RtkService_SendRtcmData_FullMethodName = "/mavsdk.rpc.rtk.RtkService/SendRtcmData" 24 | ) 25 | 26 | // RtkServiceClient is the client API for RtkService service. 27 | // 28 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 29 | // 30 | // Service to send RTK corrections to the vehicle. 31 | type RtkServiceClient interface { 32 | // Send RTCM data. 33 | SendRtcmData(ctx context.Context, in *SendRtcmDataRequest, opts ...grpc.CallOption) (*SendRtcmDataResponse, error) 34 | } 35 | 36 | type rtkServiceClient struct { 37 | cc grpc.ClientConnInterface 38 | } 39 | 40 | func NewRtkServiceClient(cc grpc.ClientConnInterface) RtkServiceClient { 41 | return &rtkServiceClient{cc} 42 | } 43 | 44 | func (c *rtkServiceClient) SendRtcmData(ctx context.Context, in *SendRtcmDataRequest, opts ...grpc.CallOption) (*SendRtcmDataResponse, error) { 45 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 46 | out := new(SendRtcmDataResponse) 47 | err := c.cc.Invoke(ctx, RtkService_SendRtcmData_FullMethodName, in, out, cOpts...) 48 | if err != nil { 49 | return nil, err 50 | } 51 | return out, nil 52 | } 53 | 54 | // RtkServiceServer is the server API for RtkService service. 55 | // All implementations must embed UnimplementedRtkServiceServer 56 | // for forward compatibility. 57 | // 58 | // Service to send RTK corrections to the vehicle. 59 | type RtkServiceServer interface { 60 | // Send RTCM data. 61 | SendRtcmData(context.Context, *SendRtcmDataRequest) (*SendRtcmDataResponse, error) 62 | mustEmbedUnimplementedRtkServiceServer() 63 | } 64 | 65 | // UnimplementedRtkServiceServer must be embedded to have 66 | // forward compatible implementations. 67 | // 68 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 69 | // pointer dereference when methods are called. 70 | type UnimplementedRtkServiceServer struct{} 71 | 72 | func (UnimplementedRtkServiceServer) SendRtcmData(context.Context, *SendRtcmDataRequest) (*SendRtcmDataResponse, error) { 73 | return nil, status.Errorf(codes.Unimplemented, "method SendRtcmData not implemented") 74 | } 75 | func (UnimplementedRtkServiceServer) mustEmbedUnimplementedRtkServiceServer() {} 76 | func (UnimplementedRtkServiceServer) testEmbeddedByValue() {} 77 | 78 | // UnsafeRtkServiceServer may be embedded to opt out of forward compatibility for this service. 79 | // Use of this interface is not recommended, as added methods to RtkServiceServer will 80 | // result in compilation errors. 81 | type UnsafeRtkServiceServer interface { 82 | mustEmbedUnimplementedRtkServiceServer() 83 | } 84 | 85 | func RegisterRtkServiceServer(s grpc.ServiceRegistrar, srv RtkServiceServer) { 86 | // If the following call pancis, it indicates UnimplementedRtkServiceServer was 87 | // embedded by pointer and is nil. This will cause panics if an 88 | // unimplemented method is ever invoked, so we test this at initialization 89 | // time to prevent it from happening at runtime later due to I/O. 90 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 91 | t.testEmbeddedByValue() 92 | } 93 | s.RegisterService(&RtkService_ServiceDesc, srv) 94 | } 95 | 96 | func _RtkService_SendRtcmData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 97 | in := new(SendRtcmDataRequest) 98 | if err := dec(in); err != nil { 99 | return nil, err 100 | } 101 | if interceptor == nil { 102 | return srv.(RtkServiceServer).SendRtcmData(ctx, in) 103 | } 104 | info := &grpc.UnaryServerInfo{ 105 | Server: srv, 106 | FullMethod: RtkService_SendRtcmData_FullMethodName, 107 | } 108 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 109 | return srv.(RtkServiceServer).SendRtcmData(ctx, req.(*SendRtcmDataRequest)) 110 | } 111 | return interceptor(ctx, in, info, handler) 112 | } 113 | 114 | // RtkService_ServiceDesc is the grpc.ServiceDesc for RtkService service. 115 | // It's only intended for direct use with grpc.RegisterService, 116 | // and not to be introspected or modified (even as a copy) 117 | var RtkService_ServiceDesc = grpc.ServiceDesc{ 118 | ServiceName: "mavsdk.rpc.rtk.RtkService", 119 | HandlerType: (*RtkServiceServer)(nil), 120 | Methods: []grpc.MethodDesc{ 121 | { 122 | MethodName: "SendRtcmData", 123 | Handler: _RtkService_SendRtcmData_Handler, 124 | }, 125 | }, 126 | Streams: []grpc.StreamDesc{}, 127 | Metadata: "rtk.proto", 128 | } 129 | -------------------------------------------------------------------------------- /Sources/tune/tune_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: tune.proto 6 | 7 | package tune 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | TuneService_PlayTune_FullMethodName = "/mavsdk.rpc.tune.TuneService/PlayTune" 24 | ) 25 | 26 | // TuneServiceClient is the client API for TuneService service. 27 | // 28 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 29 | // 30 | // Enable creating and sending a tune to be played on the system. 31 | type TuneServiceClient interface { 32 | // Send a tune to be played by the system. 33 | PlayTune(ctx context.Context, in *PlayTuneRequest, opts ...grpc.CallOption) (*PlayTuneResponse, error) 34 | } 35 | 36 | type tuneServiceClient struct { 37 | cc grpc.ClientConnInterface 38 | } 39 | 40 | func NewTuneServiceClient(cc grpc.ClientConnInterface) TuneServiceClient { 41 | return &tuneServiceClient{cc} 42 | } 43 | 44 | func (c *tuneServiceClient) PlayTune(ctx context.Context, in *PlayTuneRequest, opts ...grpc.CallOption) (*PlayTuneResponse, error) { 45 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 46 | out := new(PlayTuneResponse) 47 | err := c.cc.Invoke(ctx, TuneService_PlayTune_FullMethodName, in, out, cOpts...) 48 | if err != nil { 49 | return nil, err 50 | } 51 | return out, nil 52 | } 53 | 54 | // TuneServiceServer is the server API for TuneService service. 55 | // All implementations must embed UnimplementedTuneServiceServer 56 | // for forward compatibility. 57 | // 58 | // Enable creating and sending a tune to be played on the system. 59 | type TuneServiceServer interface { 60 | // Send a tune to be played by the system. 61 | PlayTune(context.Context, *PlayTuneRequest) (*PlayTuneResponse, error) 62 | mustEmbedUnimplementedTuneServiceServer() 63 | } 64 | 65 | // UnimplementedTuneServiceServer must be embedded to have 66 | // forward compatible implementations. 67 | // 68 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 69 | // pointer dereference when methods are called. 70 | type UnimplementedTuneServiceServer struct{} 71 | 72 | func (UnimplementedTuneServiceServer) PlayTune(context.Context, *PlayTuneRequest) (*PlayTuneResponse, error) { 73 | return nil, status.Errorf(codes.Unimplemented, "method PlayTune not implemented") 74 | } 75 | func (UnimplementedTuneServiceServer) mustEmbedUnimplementedTuneServiceServer() {} 76 | func (UnimplementedTuneServiceServer) testEmbeddedByValue() {} 77 | 78 | // UnsafeTuneServiceServer may be embedded to opt out of forward compatibility for this service. 79 | // Use of this interface is not recommended, as added methods to TuneServiceServer will 80 | // result in compilation errors. 81 | type UnsafeTuneServiceServer interface { 82 | mustEmbedUnimplementedTuneServiceServer() 83 | } 84 | 85 | func RegisterTuneServiceServer(s grpc.ServiceRegistrar, srv TuneServiceServer) { 86 | // If the following call pancis, it indicates UnimplementedTuneServiceServer was 87 | // embedded by pointer and is nil. This will cause panics if an 88 | // unimplemented method is ever invoked, so we test this at initialization 89 | // time to prevent it from happening at runtime later due to I/O. 90 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 91 | t.testEmbeddedByValue() 92 | } 93 | s.RegisterService(&TuneService_ServiceDesc, srv) 94 | } 95 | 96 | func _TuneService_PlayTune_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 97 | in := new(PlayTuneRequest) 98 | if err := dec(in); err != nil { 99 | return nil, err 100 | } 101 | if interceptor == nil { 102 | return srv.(TuneServiceServer).PlayTune(ctx, in) 103 | } 104 | info := &grpc.UnaryServerInfo{ 105 | Server: srv, 106 | FullMethod: TuneService_PlayTune_FullMethodName, 107 | } 108 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 109 | return srv.(TuneServiceServer).PlayTune(ctx, req.(*PlayTuneRequest)) 110 | } 111 | return interceptor(ctx, in, info, handler) 112 | } 113 | 114 | // TuneService_ServiceDesc is the grpc.ServiceDesc for TuneService service. 115 | // It's only intended for direct use with grpc.RegisterService, 116 | // and not to be introspected or modified (even as a copy) 117 | var TuneService_ServiceDesc = grpc.ServiceDesc{ 118 | ServiceName: "mavsdk.rpc.tune.TuneService", 119 | HandlerType: (*TuneServiceServer)(nil), 120 | Methods: []grpc.MethodDesc{ 121 | { 122 | MethodName: "PlayTune", 123 | Handler: _TuneService_PlayTune_Handler, 124 | }, 125 | }, 126 | Streams: []grpc.StreamDesc{}, 127 | Metadata: "tune.proto", 128 | } 129 | -------------------------------------------------------------------------------- /Sources/failure/failure_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: failure.proto 6 | 7 | package failure 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | FailureService_Inject_FullMethodName = "/mavsdk.rpc.failure.FailureService/Inject" 24 | ) 25 | 26 | // FailureServiceClient is the client API for FailureService service. 27 | // 28 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 29 | // 30 | // Inject failures into system to test failsafes. 31 | type FailureServiceClient interface { 32 | // Injects a failure. 33 | Inject(ctx context.Context, in *InjectRequest, opts ...grpc.CallOption) (*InjectResponse, error) 34 | } 35 | 36 | type failureServiceClient struct { 37 | cc grpc.ClientConnInterface 38 | } 39 | 40 | func NewFailureServiceClient(cc grpc.ClientConnInterface) FailureServiceClient { 41 | return &failureServiceClient{cc} 42 | } 43 | 44 | func (c *failureServiceClient) Inject(ctx context.Context, in *InjectRequest, opts ...grpc.CallOption) (*InjectResponse, error) { 45 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 46 | out := new(InjectResponse) 47 | err := c.cc.Invoke(ctx, FailureService_Inject_FullMethodName, in, out, cOpts...) 48 | if err != nil { 49 | return nil, err 50 | } 51 | return out, nil 52 | } 53 | 54 | // FailureServiceServer is the server API for FailureService service. 55 | // All implementations must embed UnimplementedFailureServiceServer 56 | // for forward compatibility. 57 | // 58 | // Inject failures into system to test failsafes. 59 | type FailureServiceServer interface { 60 | // Injects a failure. 61 | Inject(context.Context, *InjectRequest) (*InjectResponse, error) 62 | mustEmbedUnimplementedFailureServiceServer() 63 | } 64 | 65 | // UnimplementedFailureServiceServer must be embedded to have 66 | // forward compatible implementations. 67 | // 68 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 69 | // pointer dereference when methods are called. 70 | type UnimplementedFailureServiceServer struct{} 71 | 72 | func (UnimplementedFailureServiceServer) Inject(context.Context, *InjectRequest) (*InjectResponse, error) { 73 | return nil, status.Errorf(codes.Unimplemented, "method Inject not implemented") 74 | } 75 | func (UnimplementedFailureServiceServer) mustEmbedUnimplementedFailureServiceServer() {} 76 | func (UnimplementedFailureServiceServer) testEmbeddedByValue() {} 77 | 78 | // UnsafeFailureServiceServer may be embedded to opt out of forward compatibility for this service. 79 | // Use of this interface is not recommended, as added methods to FailureServiceServer will 80 | // result in compilation errors. 81 | type UnsafeFailureServiceServer interface { 82 | mustEmbedUnimplementedFailureServiceServer() 83 | } 84 | 85 | func RegisterFailureServiceServer(s grpc.ServiceRegistrar, srv FailureServiceServer) { 86 | // If the following call pancis, it indicates UnimplementedFailureServiceServer was 87 | // embedded by pointer and is nil. This will cause panics if an 88 | // unimplemented method is ever invoked, so we test this at initialization 89 | // time to prevent it from happening at runtime later due to I/O. 90 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 91 | t.testEmbeddedByValue() 92 | } 93 | s.RegisterService(&FailureService_ServiceDesc, srv) 94 | } 95 | 96 | func _FailureService_Inject_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 97 | in := new(InjectRequest) 98 | if err := dec(in); err != nil { 99 | return nil, err 100 | } 101 | if interceptor == nil { 102 | return srv.(FailureServiceServer).Inject(ctx, in) 103 | } 104 | info := &grpc.UnaryServerInfo{ 105 | Server: srv, 106 | FullMethod: FailureService_Inject_FullMethodName, 107 | } 108 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 109 | return srv.(FailureServiceServer).Inject(ctx, req.(*InjectRequest)) 110 | } 111 | return interceptor(ctx, in, info, handler) 112 | } 113 | 114 | // FailureService_ServiceDesc is the grpc.ServiceDesc for FailureService service. 115 | // It's only intended for direct use with grpc.RegisterService, 116 | // and not to be introspected or modified (even as a copy) 117 | var FailureService_ServiceDesc = grpc.ServiceDesc{ 118 | ServiceName: "mavsdk.rpc.failure.FailureService", 119 | HandlerType: (*FailureServiceServer)(nil), 120 | Methods: []grpc.MethodDesc{ 121 | { 122 | MethodName: "Inject", 123 | Handler: _FailureService_Inject_Handler, 124 | }, 125 | }, 126 | Streams: []grpc.StreamDesc{}, 127 | Metadata: "failure.proto", 128 | } 129 | -------------------------------------------------------------------------------- /Sources/calibration/calibration.go: -------------------------------------------------------------------------------- 1 | package calibration 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client CalibrationServiceClient 14 | } 15 | 16 | /* 17 | CalibrateGyro Perform gyro calibration. 18 | */ 19 | func (a *ServiceImpl) CalibrateGyro( 20 | ctx context.Context, 21 | 22 | ) (<-chan *ProgressData, error) { 23 | ch := make(chan *ProgressData) 24 | request := &SubscribeCalibrateGyroRequest{} 25 | stream, err := a.Client.SubscribeCalibrateGyro(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | go func() { 30 | defer close(ch) 31 | for { 32 | m := &CalibrateGyroResponse{} 33 | err := stream.RecvMsg(m) 34 | if err == io.EOF { 35 | return 36 | } 37 | if err != nil { 38 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 39 | return 40 | } 41 | log.Fatalf("Unable to receive CalibrateGyro messages, err: %v", err) 42 | } 43 | ch <- m.GetProgressData() 44 | } 45 | }() 46 | return ch, nil 47 | } 48 | 49 | /* 50 | CalibrateAccelerometer Perform accelerometer calibration. 51 | */ 52 | func (a *ServiceImpl) CalibrateAccelerometer( 53 | ctx context.Context, 54 | 55 | ) (<-chan *ProgressData, error) { 56 | ch := make(chan *ProgressData) 57 | request := &SubscribeCalibrateAccelerometerRequest{} 58 | stream, err := a.Client.SubscribeCalibrateAccelerometer(ctx, request) 59 | if err != nil { 60 | return nil, err 61 | } 62 | go func() { 63 | defer close(ch) 64 | for { 65 | m := &CalibrateAccelerometerResponse{} 66 | err := stream.RecvMsg(m) 67 | if err == io.EOF { 68 | return 69 | } 70 | if err != nil { 71 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 72 | return 73 | } 74 | log.Fatalf("Unable to receive CalibrateAccelerometer messages, err: %v", err) 75 | } 76 | ch <- m.GetProgressData() 77 | } 78 | }() 79 | return ch, nil 80 | } 81 | 82 | /* 83 | CalibrateMagnetometer Perform magnetometer calibration. 84 | */ 85 | func (a *ServiceImpl) CalibrateMagnetometer( 86 | ctx context.Context, 87 | 88 | ) (<-chan *ProgressData, error) { 89 | ch := make(chan *ProgressData) 90 | request := &SubscribeCalibrateMagnetometerRequest{} 91 | stream, err := a.Client.SubscribeCalibrateMagnetometer(ctx, request) 92 | if err != nil { 93 | return nil, err 94 | } 95 | go func() { 96 | defer close(ch) 97 | for { 98 | m := &CalibrateMagnetometerResponse{} 99 | err := stream.RecvMsg(m) 100 | if err == io.EOF { 101 | return 102 | } 103 | if err != nil { 104 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 105 | return 106 | } 107 | log.Fatalf("Unable to receive CalibrateMagnetometer messages, err: %v", err) 108 | } 109 | ch <- m.GetProgressData() 110 | } 111 | }() 112 | return ch, nil 113 | } 114 | 115 | /* 116 | CalibrateLevelHorizon Perform board level horizon calibration. 117 | */ 118 | func (a *ServiceImpl) CalibrateLevelHorizon( 119 | ctx context.Context, 120 | 121 | ) (<-chan *ProgressData, error) { 122 | ch := make(chan *ProgressData) 123 | request := &SubscribeCalibrateLevelHorizonRequest{} 124 | stream, err := a.Client.SubscribeCalibrateLevelHorizon(ctx, request) 125 | if err != nil { 126 | return nil, err 127 | } 128 | go func() { 129 | defer close(ch) 130 | for { 131 | m := &CalibrateLevelHorizonResponse{} 132 | err := stream.RecvMsg(m) 133 | if err == io.EOF { 134 | return 135 | } 136 | if err != nil { 137 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 138 | return 139 | } 140 | log.Fatalf("Unable to receive CalibrateLevelHorizon messages, err: %v", err) 141 | } 142 | ch <- m.GetProgressData() 143 | } 144 | }() 145 | return ch, nil 146 | } 147 | 148 | /* 149 | CalibrateGimbalAccelerometer Perform gimbal accelerometer calibration. 150 | */ 151 | func (a *ServiceImpl) CalibrateGimbalAccelerometer( 152 | ctx context.Context, 153 | 154 | ) (<-chan *ProgressData, error) { 155 | ch := make(chan *ProgressData) 156 | request := &SubscribeCalibrateGimbalAccelerometerRequest{} 157 | stream, err := a.Client.SubscribeCalibrateGimbalAccelerometer(ctx, request) 158 | if err != nil { 159 | return nil, err 160 | } 161 | go func() { 162 | defer close(ch) 163 | for { 164 | m := &CalibrateGimbalAccelerometerResponse{} 165 | err := stream.RecvMsg(m) 166 | if err == io.EOF { 167 | return 168 | } 169 | if err != nil { 170 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 171 | return 172 | } 173 | log.Fatalf("Unable to receive CalibrateGimbalAccelerometer messages, err: %v", err) 174 | } 175 | ch <- m.GetProgressData() 176 | } 177 | }() 178 | return ch, nil 179 | } 180 | 181 | /* 182 | Cancel Cancel ongoing calibration process. 183 | */ 184 | func (s *ServiceImpl) Cancel( 185 | ctx context.Context, 186 | 187 | ) (*CancelResponse, error) { 188 | request := &CancelRequest{} 189 | response, err := s.Client.Cancel(ctx, request) 190 | if err != nil { 191 | return nil, err 192 | } 193 | return response, nil 194 | } 195 | -------------------------------------------------------------------------------- /Sources/ftp/ftp.go: -------------------------------------------------------------------------------- 1 | package ftp 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client FtpServiceClient 14 | } 15 | 16 | /* 17 | Download Downloads a file to local directory. 18 | */ 19 | func (a *ServiceImpl) Download( 20 | ctx context.Context, 21 | remoteFilePath string, 22 | localDir string, 23 | useBurst bool, 24 | 25 | ) (<-chan *ProgressData, error) { 26 | ch := make(chan *ProgressData) 27 | request := &SubscribeDownloadRequest{ 28 | RemoteFilePath: remoteFilePath, 29 | LocalDir: localDir, 30 | UseBurst: useBurst, 31 | } 32 | stream, err := a.Client.SubscribeDownload(ctx, request) 33 | if err != nil { 34 | return nil, err 35 | } 36 | go func() { 37 | defer close(ch) 38 | for { 39 | m := &DownloadResponse{} 40 | err := stream.RecvMsg(m) 41 | if err == io.EOF { 42 | return 43 | } 44 | if err != nil { 45 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 46 | return 47 | } 48 | log.Fatalf("Unable to receive Download messages, err: %v", err) 49 | } 50 | ch <- m.GetProgressData() 51 | } 52 | }() 53 | return ch, nil 54 | } 55 | 56 | /* 57 | Upload Uploads local file to remote directory. 58 | */ 59 | func (a *ServiceImpl) Upload( 60 | ctx context.Context, 61 | localFilePath string, 62 | remoteDir string, 63 | 64 | ) (<-chan *ProgressData, error) { 65 | ch := make(chan *ProgressData) 66 | request := &SubscribeUploadRequest{ 67 | LocalFilePath: localFilePath, 68 | RemoteDir: remoteDir, 69 | } 70 | stream, err := a.Client.SubscribeUpload(ctx, request) 71 | if err != nil { 72 | return nil, err 73 | } 74 | go func() { 75 | defer close(ch) 76 | for { 77 | m := &UploadResponse{} 78 | err := stream.RecvMsg(m) 79 | if err == io.EOF { 80 | return 81 | } 82 | if err != nil { 83 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 84 | return 85 | } 86 | log.Fatalf("Unable to receive Upload messages, err: %v", err) 87 | } 88 | ch <- m.GetProgressData() 89 | } 90 | }() 91 | return ch, nil 92 | } 93 | 94 | /* 95 | ListDirectory Lists items from a remote directory. 96 | */ 97 | func (s *ServiceImpl) ListDirectory( 98 | ctx context.Context, 99 | remoteDir string, 100 | 101 | ) (*ListDirectoryResponse, error) { 102 | request := &ListDirectoryRequest{ 103 | RemoteDir: remoteDir, 104 | } 105 | response, err := s.Client.ListDirectory(ctx, request) 106 | if err != nil { 107 | return nil, err 108 | } 109 | return response, nil 110 | } 111 | 112 | /* 113 | CreateDirectory Creates a remote directory. 114 | */ 115 | func (s *ServiceImpl) CreateDirectory( 116 | ctx context.Context, 117 | remoteDir string, 118 | 119 | ) (*CreateDirectoryResponse, error) { 120 | request := &CreateDirectoryRequest{ 121 | RemoteDir: remoteDir, 122 | } 123 | response, err := s.Client.CreateDirectory(ctx, request) 124 | if err != nil { 125 | return nil, err 126 | } 127 | return response, nil 128 | } 129 | 130 | /* 131 | RemoveDirectory Removes a remote directory. 132 | */ 133 | func (s *ServiceImpl) RemoveDirectory( 134 | ctx context.Context, 135 | remoteDir string, 136 | 137 | ) (*RemoveDirectoryResponse, error) { 138 | request := &RemoveDirectoryRequest{ 139 | RemoteDir: remoteDir, 140 | } 141 | response, err := s.Client.RemoveDirectory(ctx, request) 142 | if err != nil { 143 | return nil, err 144 | } 145 | return response, nil 146 | } 147 | 148 | /* 149 | RemoveFile Removes a remote file. 150 | */ 151 | func (s *ServiceImpl) RemoveFile( 152 | ctx context.Context, 153 | remoteFilePath string, 154 | 155 | ) (*RemoveFileResponse, error) { 156 | request := &RemoveFileRequest{ 157 | RemoteFilePath: remoteFilePath, 158 | } 159 | response, err := s.Client.RemoveFile(ctx, request) 160 | if err != nil { 161 | return nil, err 162 | } 163 | return response, nil 164 | } 165 | 166 | /* 167 | Rename Renames a remote file or remote directory. 168 | */ 169 | func (s *ServiceImpl) Rename( 170 | ctx context.Context, 171 | remoteFromPath string, 172 | remoteToPath string, 173 | 174 | ) (*RenameResponse, error) { 175 | request := &RenameRequest{ 176 | RemoteFromPath: remoteFromPath, 177 | RemoteToPath: remoteToPath, 178 | } 179 | response, err := s.Client.Rename(ctx, request) 180 | if err != nil { 181 | return nil, err 182 | } 183 | return response, nil 184 | } 185 | 186 | /* 187 | AreFilesIdentical Compares a local file to a remote file using a CRC32 checksum. 188 | */ 189 | func (s *ServiceImpl) AreFilesIdentical( 190 | ctx context.Context, 191 | localFilePath string, 192 | remoteFilePath string, 193 | 194 | ) (*AreFilesIdenticalResponse, error) { 195 | request := &AreFilesIdenticalRequest{ 196 | LocalFilePath: localFilePath, 197 | RemoteFilePath: remoteFilePath, 198 | } 199 | response, err := s.Client.AreFilesIdentical(ctx, request) 200 | if err != nil { 201 | return nil, err 202 | } 203 | return response, nil 204 | } 205 | 206 | /* 207 | SetTargetCompid Set target component ID. By default it is the autopilot. 208 | */ 209 | func (s *ServiceImpl) SetTargetCompid( 210 | ctx context.Context, 211 | compid uint32, 212 | 213 | ) (*SetTargetCompidResponse, error) { 214 | request := &SetTargetCompidRequest{ 215 | Compid: compid, 216 | } 217 | response, err := s.Client.SetTargetCompid(ctx, request) 218 | if err != nil { 219 | return nil, err 220 | } 221 | return response, nil 222 | } 223 | -------------------------------------------------------------------------------- /Sources/winch/winch.go: -------------------------------------------------------------------------------- 1 | package winch 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client WinchServiceClient 14 | } 15 | 16 | /* 17 | Status Subscribe to 'winch status' updates. 18 | */ 19 | func (a *ServiceImpl) Status( 20 | ctx context.Context, 21 | 22 | ) (<-chan *Status, error) { 23 | ch := make(chan *Status) 24 | request := &SubscribeStatusRequest{} 25 | stream, err := a.Client.SubscribeStatus(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | go func() { 30 | defer close(ch) 31 | for { 32 | m := &StatusResponse{} 33 | err := stream.RecvMsg(m) 34 | if err == io.EOF { 35 | return 36 | } 37 | if err != nil { 38 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 39 | return 40 | } 41 | log.Fatalf("Unable to receive Status messages, err: %v", err) 42 | } 43 | ch <- m.GetStatus() 44 | } 45 | }() 46 | return ch, nil 47 | } 48 | 49 | /* 50 | Relax Allow motor to freewheel. 51 | */ 52 | func (s *ServiceImpl) Relax( 53 | ctx context.Context, 54 | instance uint32, 55 | 56 | ) (*RelaxResponse, error) { 57 | request := &RelaxRequest{ 58 | Instance: instance, 59 | } 60 | response, err := s.Client.Relax(ctx, request) 61 | if err != nil { 62 | return nil, err 63 | } 64 | return response, nil 65 | } 66 | 67 | /* 68 | RelativeLengthControl Wind or unwind specified length of line, optionally using specified rate. 69 | */ 70 | func (s *ServiceImpl) RelativeLengthControl( 71 | ctx context.Context, 72 | instance uint32, 73 | lengthM float32, 74 | rateMS float32, 75 | 76 | ) (*RelativeLengthControlResponse, error) { 77 | request := &RelativeLengthControlRequest{ 78 | Instance: instance, 79 | LengthM: lengthM, 80 | RateMS: rateMS, 81 | } 82 | response, err := s.Client.RelativeLengthControl(ctx, request) 83 | if err != nil { 84 | return nil, err 85 | } 86 | return response, nil 87 | } 88 | 89 | /* 90 | RateControl Wind or unwind line at specified rate. 91 | */ 92 | func (s *ServiceImpl) RateControl( 93 | ctx context.Context, 94 | instance uint32, 95 | rateMS float32, 96 | 97 | ) (*RateControlResponse, error) { 98 | request := &RateControlRequest{ 99 | Instance: instance, 100 | RateMS: rateMS, 101 | } 102 | response, err := s.Client.RateControl(ctx, request) 103 | if err != nil { 104 | return nil, err 105 | } 106 | return response, nil 107 | } 108 | 109 | /* 110 | Lock Perform the locking sequence to relieve motor while in the fully retracted position. 111 | */ 112 | func (s *ServiceImpl) Lock( 113 | ctx context.Context, 114 | instance uint32, 115 | 116 | ) (*LockResponse, error) { 117 | request := &LockRequest{ 118 | Instance: instance, 119 | } 120 | response, err := s.Client.Lock(ctx, request) 121 | if err != nil { 122 | return nil, err 123 | } 124 | return response, nil 125 | } 126 | 127 | /* 128 | Deliver Sequence of drop, slow down, touch down, reel up, lock. 129 | */ 130 | func (s *ServiceImpl) Deliver( 131 | ctx context.Context, 132 | instance uint32, 133 | 134 | ) (*DeliverResponse, error) { 135 | request := &DeliverRequest{ 136 | Instance: instance, 137 | } 138 | response, err := s.Client.Deliver(ctx, request) 139 | if err != nil { 140 | return nil, err 141 | } 142 | return response, nil 143 | } 144 | 145 | /* 146 | Hold Engage motor and hold current position. 147 | */ 148 | func (s *ServiceImpl) Hold( 149 | ctx context.Context, 150 | instance uint32, 151 | 152 | ) (*HoldResponse, error) { 153 | request := &HoldRequest{ 154 | Instance: instance, 155 | } 156 | response, err := s.Client.Hold(ctx, request) 157 | if err != nil { 158 | return nil, err 159 | } 160 | return response, nil 161 | } 162 | 163 | /* 164 | Retract Return the reel to the fully retracted position. 165 | */ 166 | func (s *ServiceImpl) Retract( 167 | ctx context.Context, 168 | instance uint32, 169 | 170 | ) (*RetractResponse, error) { 171 | request := &RetractRequest{ 172 | Instance: instance, 173 | } 174 | response, err := s.Client.Retract(ctx, request) 175 | if err != nil { 176 | return nil, err 177 | } 178 | return response, nil 179 | } 180 | 181 | /* 182 | LoadLine Load the reel with line. 183 | 184 | The winch will calculate the total loaded length and stop when the tension exceeds a threshold. 185 | */ 186 | func (s *ServiceImpl) LoadLine( 187 | ctx context.Context, 188 | instance uint32, 189 | 190 | ) (*LoadLineResponse, error) { 191 | request := &LoadLineRequest{ 192 | Instance: instance, 193 | } 194 | response, err := s.Client.LoadLine(ctx, request) 195 | if err != nil { 196 | return nil, err 197 | } 198 | return response, nil 199 | } 200 | 201 | /* 202 | AbandonLine Spool out the entire length of the line. 203 | */ 204 | func (s *ServiceImpl) AbandonLine( 205 | ctx context.Context, 206 | instance uint32, 207 | 208 | ) (*AbandonLineResponse, error) { 209 | request := &AbandonLineRequest{ 210 | Instance: instance, 211 | } 212 | response, err := s.Client.AbandonLine(ctx, request) 213 | if err != nil { 214 | return nil, err 215 | } 216 | return response, nil 217 | } 218 | 219 | /* 220 | LoadPayload Spools out just enough to present the hook to the user to load the payload. 221 | */ 222 | func (s *ServiceImpl) LoadPayload( 223 | ctx context.Context, 224 | instance uint32, 225 | 226 | ) (*LoadPayloadResponse, error) { 227 | request := &LoadPayloadRequest{ 228 | Instance: instance, 229 | } 230 | response, err := s.Client.LoadPayload(ctx, request) 231 | if err != nil { 232 | return nil, err 233 | } 234 | return response, nil 235 | } 236 | -------------------------------------------------------------------------------- /Sources/server_utility/server_utility_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: server_utility.proto 6 | 7 | package server_utility 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | ServerUtilityService_SendStatusText_FullMethodName = "/mavsdk.rpc.server_utility.ServerUtilityService/SendStatusText" 24 | ) 25 | 26 | // ServerUtilityServiceClient is the client API for ServerUtilityService service. 27 | // 28 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 29 | // 30 | // Utility for onboard MAVSDK instances for common "server" tasks. 31 | type ServerUtilityServiceClient interface { 32 | // Sends a statustext. 33 | SendStatusText(ctx context.Context, in *SendStatusTextRequest, opts ...grpc.CallOption) (*SendStatusTextResponse, error) 34 | } 35 | 36 | type serverUtilityServiceClient struct { 37 | cc grpc.ClientConnInterface 38 | } 39 | 40 | func NewServerUtilityServiceClient(cc grpc.ClientConnInterface) ServerUtilityServiceClient { 41 | return &serverUtilityServiceClient{cc} 42 | } 43 | 44 | func (c *serverUtilityServiceClient) SendStatusText(ctx context.Context, in *SendStatusTextRequest, opts ...grpc.CallOption) (*SendStatusTextResponse, error) { 45 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 46 | out := new(SendStatusTextResponse) 47 | err := c.cc.Invoke(ctx, ServerUtilityService_SendStatusText_FullMethodName, in, out, cOpts...) 48 | if err != nil { 49 | return nil, err 50 | } 51 | return out, nil 52 | } 53 | 54 | // ServerUtilityServiceServer is the server API for ServerUtilityService service. 55 | // All implementations must embed UnimplementedServerUtilityServiceServer 56 | // for forward compatibility. 57 | // 58 | // Utility for onboard MAVSDK instances for common "server" tasks. 59 | type ServerUtilityServiceServer interface { 60 | // Sends a statustext. 61 | SendStatusText(context.Context, *SendStatusTextRequest) (*SendStatusTextResponse, error) 62 | mustEmbedUnimplementedServerUtilityServiceServer() 63 | } 64 | 65 | // UnimplementedServerUtilityServiceServer must be embedded to have 66 | // forward compatible implementations. 67 | // 68 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 69 | // pointer dereference when methods are called. 70 | type UnimplementedServerUtilityServiceServer struct{} 71 | 72 | func (UnimplementedServerUtilityServiceServer) SendStatusText(context.Context, *SendStatusTextRequest) (*SendStatusTextResponse, error) { 73 | return nil, status.Errorf(codes.Unimplemented, "method SendStatusText not implemented") 74 | } 75 | func (UnimplementedServerUtilityServiceServer) mustEmbedUnimplementedServerUtilityServiceServer() {} 76 | func (UnimplementedServerUtilityServiceServer) testEmbeddedByValue() {} 77 | 78 | // UnsafeServerUtilityServiceServer may be embedded to opt out of forward compatibility for this service. 79 | // Use of this interface is not recommended, as added methods to ServerUtilityServiceServer will 80 | // result in compilation errors. 81 | type UnsafeServerUtilityServiceServer interface { 82 | mustEmbedUnimplementedServerUtilityServiceServer() 83 | } 84 | 85 | func RegisterServerUtilityServiceServer(s grpc.ServiceRegistrar, srv ServerUtilityServiceServer) { 86 | // If the following call pancis, it indicates UnimplementedServerUtilityServiceServer was 87 | // embedded by pointer and is nil. This will cause panics if an 88 | // unimplemented method is ever invoked, so we test this at initialization 89 | // time to prevent it from happening at runtime later due to I/O. 90 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 91 | t.testEmbeddedByValue() 92 | } 93 | s.RegisterService(&ServerUtilityService_ServiceDesc, srv) 94 | } 95 | 96 | func _ServerUtilityService_SendStatusText_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 97 | in := new(SendStatusTextRequest) 98 | if err := dec(in); err != nil { 99 | return nil, err 100 | } 101 | if interceptor == nil { 102 | return srv.(ServerUtilityServiceServer).SendStatusText(ctx, in) 103 | } 104 | info := &grpc.UnaryServerInfo{ 105 | Server: srv, 106 | FullMethod: ServerUtilityService_SendStatusText_FullMethodName, 107 | } 108 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 109 | return srv.(ServerUtilityServiceServer).SendStatusText(ctx, req.(*SendStatusTextRequest)) 110 | } 111 | return interceptor(ctx, in, info, handler) 112 | } 113 | 114 | // ServerUtilityService_ServiceDesc is the grpc.ServiceDesc for ServerUtilityService service. 115 | // It's only intended for direct use with grpc.RegisterService, 116 | // and not to be introspected or modified (even as a copy) 117 | var ServerUtilityService_ServiceDesc = grpc.ServiceDesc{ 118 | ServiceName: "mavsdk.rpc.server_utility.ServerUtilityService", 119 | HandlerType: (*ServerUtilityServiceServer)(nil), 120 | Methods: []grpc.MethodDesc{ 121 | { 122 | MethodName: "SendStatusText", 123 | Handler: _ServerUtilityService_SendStatusText_Handler, 124 | }, 125 | }, 126 | Streams: []grpc.StreamDesc{}, 127 | Metadata: "server_utility.proto", 128 | } 129 | -------------------------------------------------------------------------------- /Sources/ftp_server/ftp_server_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: ftp_server.proto 6 | 7 | package ftp_server 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | FtpServerService_SetRootDir_FullMethodName = "/mavsdk.rpc.ftp_server.FtpServerService/SetRootDir" 24 | ) 25 | 26 | // FtpServerServiceClient is the client API for FtpServerService service. 27 | // 28 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 29 | // 30 | // Provide files or directories to transfer. 31 | type FtpServerServiceClient interface { 32 | // Set root directory. 33 | // 34 | // This is the directory that can then be accessed by a client. 35 | // The directory needs to exist when this is called. 36 | // The permissions are the same as the file permission for the user running the server. 37 | // The root directory can't be changed while an FTP process is in progress. 38 | SetRootDir(ctx context.Context, in *SetRootDirRequest, opts ...grpc.CallOption) (*SetRootDirResponse, error) 39 | } 40 | 41 | type ftpServerServiceClient struct { 42 | cc grpc.ClientConnInterface 43 | } 44 | 45 | func NewFtpServerServiceClient(cc grpc.ClientConnInterface) FtpServerServiceClient { 46 | return &ftpServerServiceClient{cc} 47 | } 48 | 49 | func (c *ftpServerServiceClient) SetRootDir(ctx context.Context, in *SetRootDirRequest, opts ...grpc.CallOption) (*SetRootDirResponse, error) { 50 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 51 | out := new(SetRootDirResponse) 52 | err := c.cc.Invoke(ctx, FtpServerService_SetRootDir_FullMethodName, in, out, cOpts...) 53 | if err != nil { 54 | return nil, err 55 | } 56 | return out, nil 57 | } 58 | 59 | // FtpServerServiceServer is the server API for FtpServerService service. 60 | // All implementations must embed UnimplementedFtpServerServiceServer 61 | // for forward compatibility. 62 | // 63 | // Provide files or directories to transfer. 64 | type FtpServerServiceServer interface { 65 | // Set root directory. 66 | // 67 | // This is the directory that can then be accessed by a client. 68 | // The directory needs to exist when this is called. 69 | // The permissions are the same as the file permission for the user running the server. 70 | // The root directory can't be changed while an FTP process is in progress. 71 | SetRootDir(context.Context, *SetRootDirRequest) (*SetRootDirResponse, error) 72 | mustEmbedUnimplementedFtpServerServiceServer() 73 | } 74 | 75 | // UnimplementedFtpServerServiceServer must be embedded to have 76 | // forward compatible implementations. 77 | // 78 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 79 | // pointer dereference when methods are called. 80 | type UnimplementedFtpServerServiceServer struct{} 81 | 82 | func (UnimplementedFtpServerServiceServer) SetRootDir(context.Context, *SetRootDirRequest) (*SetRootDirResponse, error) { 83 | return nil, status.Errorf(codes.Unimplemented, "method SetRootDir not implemented") 84 | } 85 | func (UnimplementedFtpServerServiceServer) mustEmbedUnimplementedFtpServerServiceServer() {} 86 | func (UnimplementedFtpServerServiceServer) testEmbeddedByValue() {} 87 | 88 | // UnsafeFtpServerServiceServer may be embedded to opt out of forward compatibility for this service. 89 | // Use of this interface is not recommended, as added methods to FtpServerServiceServer will 90 | // result in compilation errors. 91 | type UnsafeFtpServerServiceServer interface { 92 | mustEmbedUnimplementedFtpServerServiceServer() 93 | } 94 | 95 | func RegisterFtpServerServiceServer(s grpc.ServiceRegistrar, srv FtpServerServiceServer) { 96 | // If the following call pancis, it indicates UnimplementedFtpServerServiceServer was 97 | // embedded by pointer and is nil. This will cause panics if an 98 | // unimplemented method is ever invoked, so we test this at initialization 99 | // time to prevent it from happening at runtime later due to I/O. 100 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 101 | t.testEmbeddedByValue() 102 | } 103 | s.RegisterService(&FtpServerService_ServiceDesc, srv) 104 | } 105 | 106 | func _FtpServerService_SetRootDir_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 107 | in := new(SetRootDirRequest) 108 | if err := dec(in); err != nil { 109 | return nil, err 110 | } 111 | if interceptor == nil { 112 | return srv.(FtpServerServiceServer).SetRootDir(ctx, in) 113 | } 114 | info := &grpc.UnaryServerInfo{ 115 | Server: srv, 116 | FullMethod: FtpServerService_SetRootDir_FullMethodName, 117 | } 118 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 119 | return srv.(FtpServerServiceServer).SetRootDir(ctx, req.(*SetRootDirRequest)) 120 | } 121 | return interceptor(ctx, in, info, handler) 122 | } 123 | 124 | // FtpServerService_ServiceDesc is the grpc.ServiceDesc for FtpServerService service. 125 | // It's only intended for direct use with grpc.RegisterService, 126 | // and not to be introspected or modified (even as a copy) 127 | var FtpServerService_ServiceDesc = grpc.ServiceDesc{ 128 | ServiceName: "mavsdk.rpc.ftp_server.FtpServerService", 129 | HandlerType: (*FtpServerServiceServer)(nil), 130 | Methods: []grpc.MethodDesc{ 131 | { 132 | MethodName: "SetRootDir", 133 | Handler: _FtpServerService_SetRootDir_Handler, 134 | }, 135 | }, 136 | Streams: []grpc.StreamDesc{}, 137 | Metadata: "ftp_server.proto", 138 | } 139 | -------------------------------------------------------------------------------- /Sources/component_metadata_server/component_metadata_server_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: component_metadata_server.proto 6 | 7 | package component_metadata_server 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | ComponentMetadataServerService_SetMetadata_FullMethodName = "/mavsdk.rpc.component_metadata_server.ComponentMetadataServerService/SetMetadata" 24 | ) 25 | 26 | // ComponentMetadataServerServiceClient is the client API for ComponentMetadataServerService service. 27 | // 28 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 29 | // 30 | // Provide component metadata json definitions, such as parameters. 31 | type ComponentMetadataServerServiceClient interface { 32 | // Provide metadata (can only be called once) 33 | SetMetadata(ctx context.Context, in *SetMetadataRequest, opts ...grpc.CallOption) (*SetMetadataResponse, error) 34 | } 35 | 36 | type componentMetadataServerServiceClient struct { 37 | cc grpc.ClientConnInterface 38 | } 39 | 40 | func NewComponentMetadataServerServiceClient(cc grpc.ClientConnInterface) ComponentMetadataServerServiceClient { 41 | return &componentMetadataServerServiceClient{cc} 42 | } 43 | 44 | func (c *componentMetadataServerServiceClient) SetMetadata(ctx context.Context, in *SetMetadataRequest, opts ...grpc.CallOption) (*SetMetadataResponse, error) { 45 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 46 | out := new(SetMetadataResponse) 47 | err := c.cc.Invoke(ctx, ComponentMetadataServerService_SetMetadata_FullMethodName, in, out, cOpts...) 48 | if err != nil { 49 | return nil, err 50 | } 51 | return out, nil 52 | } 53 | 54 | // ComponentMetadataServerServiceServer is the server API for ComponentMetadataServerService service. 55 | // All implementations must embed UnimplementedComponentMetadataServerServiceServer 56 | // for forward compatibility. 57 | // 58 | // Provide component metadata json definitions, such as parameters. 59 | type ComponentMetadataServerServiceServer interface { 60 | // Provide metadata (can only be called once) 61 | SetMetadata(context.Context, *SetMetadataRequest) (*SetMetadataResponse, error) 62 | mustEmbedUnimplementedComponentMetadataServerServiceServer() 63 | } 64 | 65 | // UnimplementedComponentMetadataServerServiceServer must be embedded to have 66 | // forward compatible implementations. 67 | // 68 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 69 | // pointer dereference when methods are called. 70 | type UnimplementedComponentMetadataServerServiceServer struct{} 71 | 72 | func (UnimplementedComponentMetadataServerServiceServer) SetMetadata(context.Context, *SetMetadataRequest) (*SetMetadataResponse, error) { 73 | return nil, status.Errorf(codes.Unimplemented, "method SetMetadata not implemented") 74 | } 75 | func (UnimplementedComponentMetadataServerServiceServer) mustEmbedUnimplementedComponentMetadataServerServiceServer() { 76 | } 77 | func (UnimplementedComponentMetadataServerServiceServer) testEmbeddedByValue() {} 78 | 79 | // UnsafeComponentMetadataServerServiceServer may be embedded to opt out of forward compatibility for this service. 80 | // Use of this interface is not recommended, as added methods to ComponentMetadataServerServiceServer will 81 | // result in compilation errors. 82 | type UnsafeComponentMetadataServerServiceServer interface { 83 | mustEmbedUnimplementedComponentMetadataServerServiceServer() 84 | } 85 | 86 | func RegisterComponentMetadataServerServiceServer(s grpc.ServiceRegistrar, srv ComponentMetadataServerServiceServer) { 87 | // If the following call pancis, it indicates UnimplementedComponentMetadataServerServiceServer was 88 | // embedded by pointer and is nil. This will cause panics if an 89 | // unimplemented method is ever invoked, so we test this at initialization 90 | // time to prevent it from happening at runtime later due to I/O. 91 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 92 | t.testEmbeddedByValue() 93 | } 94 | s.RegisterService(&ComponentMetadataServerService_ServiceDesc, srv) 95 | } 96 | 97 | func _ComponentMetadataServerService_SetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 98 | in := new(SetMetadataRequest) 99 | if err := dec(in); err != nil { 100 | return nil, err 101 | } 102 | if interceptor == nil { 103 | return srv.(ComponentMetadataServerServiceServer).SetMetadata(ctx, in) 104 | } 105 | info := &grpc.UnaryServerInfo{ 106 | Server: srv, 107 | FullMethod: ComponentMetadataServerService_SetMetadata_FullMethodName, 108 | } 109 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 110 | return srv.(ComponentMetadataServerServiceServer).SetMetadata(ctx, req.(*SetMetadataRequest)) 111 | } 112 | return interceptor(ctx, in, info, handler) 113 | } 114 | 115 | // ComponentMetadataServerService_ServiceDesc is the grpc.ServiceDesc for ComponentMetadataServerService service. 116 | // It's only intended for direct use with grpc.RegisterService, 117 | // and not to be introspected or modified (even as a copy) 118 | var ComponentMetadataServerService_ServiceDesc = grpc.ServiceDesc{ 119 | ServiceName: "mavsdk.rpc.component_metadata_server.ComponentMetadataServerService", 120 | HandlerType: (*ComponentMetadataServerServiceServer)(nil), 121 | Methods: []grpc.MethodDesc{ 122 | { 123 | MethodName: "SetMetadata", 124 | Handler: _ComponentMetadataServerService_SetMetadata_Handler, 125 | }, 126 | }, 127 | Streams: []grpc.StreamDesc{}, 128 | Metadata: "component_metadata_server.proto", 129 | } 130 | -------------------------------------------------------------------------------- /Sources/gripper/gripper_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: gripper.proto 6 | 7 | package gripper 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | GripperService_Grab_FullMethodName = "/mavsdk.rpc.gripper.GripperService/Grab" 24 | GripperService_Release_FullMethodName = "/mavsdk.rpc.gripper.GripperService/Release" 25 | ) 26 | 27 | // GripperServiceClient is the client API for GripperService service. 28 | // 29 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 30 | // 31 | // Allows users to send gripper actions. 32 | type GripperServiceClient interface { 33 | // Gripper grab cargo. 34 | Grab(ctx context.Context, in *GrabRequest, opts ...grpc.CallOption) (*GrabResponse, error) 35 | // Gripper release cargo. 36 | Release(ctx context.Context, in *ReleaseRequest, opts ...grpc.CallOption) (*ReleaseResponse, error) 37 | } 38 | 39 | type gripperServiceClient struct { 40 | cc grpc.ClientConnInterface 41 | } 42 | 43 | func NewGripperServiceClient(cc grpc.ClientConnInterface) GripperServiceClient { 44 | return &gripperServiceClient{cc} 45 | } 46 | 47 | func (c *gripperServiceClient) Grab(ctx context.Context, in *GrabRequest, opts ...grpc.CallOption) (*GrabResponse, error) { 48 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 49 | out := new(GrabResponse) 50 | err := c.cc.Invoke(ctx, GripperService_Grab_FullMethodName, in, out, cOpts...) 51 | if err != nil { 52 | return nil, err 53 | } 54 | return out, nil 55 | } 56 | 57 | func (c *gripperServiceClient) Release(ctx context.Context, in *ReleaseRequest, opts ...grpc.CallOption) (*ReleaseResponse, error) { 58 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 59 | out := new(ReleaseResponse) 60 | err := c.cc.Invoke(ctx, GripperService_Release_FullMethodName, in, out, cOpts...) 61 | if err != nil { 62 | return nil, err 63 | } 64 | return out, nil 65 | } 66 | 67 | // GripperServiceServer is the server API for GripperService service. 68 | // All implementations must embed UnimplementedGripperServiceServer 69 | // for forward compatibility. 70 | // 71 | // Allows users to send gripper actions. 72 | type GripperServiceServer interface { 73 | // Gripper grab cargo. 74 | Grab(context.Context, *GrabRequest) (*GrabResponse, error) 75 | // Gripper release cargo. 76 | Release(context.Context, *ReleaseRequest) (*ReleaseResponse, error) 77 | mustEmbedUnimplementedGripperServiceServer() 78 | } 79 | 80 | // UnimplementedGripperServiceServer must be embedded to have 81 | // forward compatible implementations. 82 | // 83 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 84 | // pointer dereference when methods are called. 85 | type UnimplementedGripperServiceServer struct{} 86 | 87 | func (UnimplementedGripperServiceServer) Grab(context.Context, *GrabRequest) (*GrabResponse, error) { 88 | return nil, status.Errorf(codes.Unimplemented, "method Grab not implemented") 89 | } 90 | func (UnimplementedGripperServiceServer) Release(context.Context, *ReleaseRequest) (*ReleaseResponse, error) { 91 | return nil, status.Errorf(codes.Unimplemented, "method Release not implemented") 92 | } 93 | func (UnimplementedGripperServiceServer) mustEmbedUnimplementedGripperServiceServer() {} 94 | func (UnimplementedGripperServiceServer) testEmbeddedByValue() {} 95 | 96 | // UnsafeGripperServiceServer may be embedded to opt out of forward compatibility for this service. 97 | // Use of this interface is not recommended, as added methods to GripperServiceServer will 98 | // result in compilation errors. 99 | type UnsafeGripperServiceServer interface { 100 | mustEmbedUnimplementedGripperServiceServer() 101 | } 102 | 103 | func RegisterGripperServiceServer(s grpc.ServiceRegistrar, srv GripperServiceServer) { 104 | // If the following call pancis, it indicates UnimplementedGripperServiceServer was 105 | // embedded by pointer and is nil. This will cause panics if an 106 | // unimplemented method is ever invoked, so we test this at initialization 107 | // time to prevent it from happening at runtime later due to I/O. 108 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 109 | t.testEmbeddedByValue() 110 | } 111 | s.RegisterService(&GripperService_ServiceDesc, srv) 112 | } 113 | 114 | func _GripperService_Grab_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 115 | in := new(GrabRequest) 116 | if err := dec(in); err != nil { 117 | return nil, err 118 | } 119 | if interceptor == nil { 120 | return srv.(GripperServiceServer).Grab(ctx, in) 121 | } 122 | info := &grpc.UnaryServerInfo{ 123 | Server: srv, 124 | FullMethod: GripperService_Grab_FullMethodName, 125 | } 126 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 127 | return srv.(GripperServiceServer).Grab(ctx, req.(*GrabRequest)) 128 | } 129 | return interceptor(ctx, in, info, handler) 130 | } 131 | 132 | func _GripperService_Release_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 133 | in := new(ReleaseRequest) 134 | if err := dec(in); err != nil { 135 | return nil, err 136 | } 137 | if interceptor == nil { 138 | return srv.(GripperServiceServer).Release(ctx, in) 139 | } 140 | info := &grpc.UnaryServerInfo{ 141 | Server: srv, 142 | FullMethod: GripperService_Release_FullMethodName, 143 | } 144 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 145 | return srv.(GripperServiceServer).Release(ctx, req.(*ReleaseRequest)) 146 | } 147 | return interceptor(ctx, in, info, handler) 148 | } 149 | 150 | // GripperService_ServiceDesc is the grpc.ServiceDesc for GripperService service. 151 | // It's only intended for direct use with grpc.RegisterService, 152 | // and not to be introspected or modified (even as a copy) 153 | var GripperService_ServiceDesc = grpc.ServiceDesc{ 154 | ServiceName: "mavsdk.rpc.gripper.GripperService", 155 | HandlerType: (*GripperServiceServer)(nil), 156 | Methods: []grpc.MethodDesc{ 157 | { 158 | MethodName: "Grab", 159 | Handler: _GripperService_Grab_Handler, 160 | }, 161 | { 162 | MethodName: "Release", 163 | Handler: _GripperService_Release_Handler, 164 | }, 165 | }, 166 | Streams: []grpc.StreamDesc{}, 167 | Metadata: "gripper.proto", 168 | } 169 | -------------------------------------------------------------------------------- /Sources/offboard/offboard.go: -------------------------------------------------------------------------------- 1 | package offboard 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client OffboardServiceClient 9 | } 10 | 11 | /* 12 | Start Start offboard control. 13 | */ 14 | func (s *ServiceImpl) Start( 15 | ctx context.Context, 16 | 17 | ) (*StartResponse, error) { 18 | request := &StartRequest{} 19 | response, err := s.Client.Start(ctx, request) 20 | if err != nil { 21 | return nil, err 22 | } 23 | return response, nil 24 | } 25 | 26 | /* 27 | Stop Stop offboard control. 28 | 29 | The vehicle will be put into Hold mode: https://docs.px4.io/en/flight_modes/hold.html 30 | */ 31 | func (s *ServiceImpl) Stop( 32 | ctx context.Context, 33 | 34 | ) (*StopResponse, error) { 35 | request := &StopRequest{} 36 | response, err := s.Client.Stop(ctx, request) 37 | if err != nil { 38 | return nil, err 39 | } 40 | return response, nil 41 | } 42 | 43 | /* 44 | IsActive Check if offboard control is active. 45 | 46 | True means that the vehicle is in offboard mode and we are actively sending 47 | setpoints. 48 | */ 49 | func (s *ServiceImpl) IsActive( 50 | ctx context.Context, 51 | 52 | ) (*IsActiveResponse, error) { 53 | request := &IsActiveRequest{} 54 | response, err := s.Client.IsActive(ctx, request) 55 | if err != nil { 56 | return nil, err 57 | } 58 | return response, nil 59 | } 60 | 61 | /* 62 | SetAttitude Set the attitude in terms of roll, pitch and yaw in degrees with thrust. 63 | */ 64 | func (s *ServiceImpl) SetAttitude( 65 | ctx context.Context, 66 | attitude *Attitude, 67 | 68 | ) (*SetAttitudeResponse, error) { 69 | request := &SetAttitudeRequest{ 70 | Attitude: attitude, 71 | } 72 | response, err := s.Client.SetAttitude(ctx, request) 73 | if err != nil { 74 | return nil, err 75 | } 76 | return response, nil 77 | } 78 | 79 | /* 80 | SetActuatorControl Set direct actuator control values to groups #0 and #1. 81 | 82 | First 8 controls will go to control group 0, the following 8 controls to control group 1 (if 83 | actuator_control.num_controls more than 8). 84 | */ 85 | func (s *ServiceImpl) SetActuatorControl( 86 | ctx context.Context, 87 | actuatorControl *ActuatorControl, 88 | 89 | ) (*SetActuatorControlResponse, error) { 90 | request := &SetActuatorControlRequest{ 91 | ActuatorControl: actuatorControl, 92 | } 93 | response, err := s.Client.SetActuatorControl(ctx, request) 94 | if err != nil { 95 | return nil, err 96 | } 97 | return response, nil 98 | } 99 | 100 | /* 101 | SetAttitudeRate Set the attitude rate in terms of pitch, roll and yaw angular rate along with thrust. 102 | */ 103 | func (s *ServiceImpl) SetAttitudeRate( 104 | ctx context.Context, 105 | attitudeRate *AttitudeRate, 106 | 107 | ) (*SetAttitudeRateResponse, error) { 108 | request := &SetAttitudeRateRequest{ 109 | AttitudeRate: attitudeRate, 110 | } 111 | response, err := s.Client.SetAttitudeRate(ctx, request) 112 | if err != nil { 113 | return nil, err 114 | } 115 | return response, nil 116 | } 117 | 118 | /* 119 | SetPositionNed Set the position in NED coordinates and yaw. 120 | */ 121 | func (s *ServiceImpl) SetPositionNed( 122 | ctx context.Context, 123 | positionNedYaw *PositionNedYaw, 124 | 125 | ) (*SetPositionNedResponse, error) { 126 | request := &SetPositionNedRequest{ 127 | PositionNedYaw: positionNedYaw, 128 | } 129 | response, err := s.Client.SetPositionNed(ctx, request) 130 | if err != nil { 131 | return nil, err 132 | } 133 | return response, nil 134 | } 135 | 136 | /* 137 | SetPositionGlobal Set the position in Global coordinates (latitude, longitude, altitude) and yaw 138 | */ 139 | func (s *ServiceImpl) SetPositionGlobal( 140 | ctx context.Context, 141 | positionGlobalYaw *PositionGlobalYaw, 142 | 143 | ) (*SetPositionGlobalResponse, error) { 144 | request := &SetPositionGlobalRequest{ 145 | PositionGlobalYaw: positionGlobalYaw, 146 | } 147 | response, err := s.Client.SetPositionGlobal(ctx, request) 148 | if err != nil { 149 | return nil, err 150 | } 151 | return response, nil 152 | } 153 | 154 | /* 155 | SetVelocityBody Set the velocity in body coordinates and yaw angular rate. Not available for fixed-wing aircraft. 156 | */ 157 | func (s *ServiceImpl) SetVelocityBody( 158 | ctx context.Context, 159 | velocityBodyYawspeed *VelocityBodyYawspeed, 160 | 161 | ) (*SetVelocityBodyResponse, error) { 162 | request := &SetVelocityBodyRequest{ 163 | VelocityBodyYawspeed: velocityBodyYawspeed, 164 | } 165 | response, err := s.Client.SetVelocityBody(ctx, request) 166 | if err != nil { 167 | return nil, err 168 | } 169 | return response, nil 170 | } 171 | 172 | /* 173 | SetVelocityNed Set the velocity in NED coordinates and yaw. Not available for fixed-wing aircraft. 174 | */ 175 | func (s *ServiceImpl) SetVelocityNed( 176 | ctx context.Context, 177 | velocityNedYaw *VelocityNedYaw, 178 | 179 | ) (*SetVelocityNedResponse, error) { 180 | request := &SetVelocityNedRequest{ 181 | VelocityNedYaw: velocityNedYaw, 182 | } 183 | response, err := s.Client.SetVelocityNed(ctx, request) 184 | if err != nil { 185 | return nil, err 186 | } 187 | return response, nil 188 | } 189 | 190 | /* 191 | SetPositionVelocityNed Set the position in NED coordinates, with the velocity to be used as feed-forward. 192 | */ 193 | func (s *ServiceImpl) SetPositionVelocityNed( 194 | ctx context.Context, 195 | positionNedYaw *PositionNedYaw, 196 | 197 | velocityNedYaw *VelocityNedYaw, 198 | 199 | ) (*SetPositionVelocityNedResponse, error) { 200 | request := &SetPositionVelocityNedRequest{ 201 | PositionNedYaw: positionNedYaw, 202 | 203 | VelocityNedYaw: velocityNedYaw, 204 | } 205 | response, err := s.Client.SetPositionVelocityNed(ctx, request) 206 | if err != nil { 207 | return nil, err 208 | } 209 | return response, nil 210 | } 211 | 212 | /* 213 | SetPositionVelocityAccelerationNed Set the position, velocity and acceleration in NED coordinates, with velocity and acceleration used as feed-forward. 214 | */ 215 | func (s *ServiceImpl) SetPositionVelocityAccelerationNed( 216 | ctx context.Context, 217 | positionNedYaw *PositionNedYaw, 218 | 219 | velocityNedYaw *VelocityNedYaw, 220 | 221 | accelerationNed *AccelerationNed, 222 | 223 | ) (*SetPositionVelocityAccelerationNedResponse, error) { 224 | request := &SetPositionVelocityAccelerationNedRequest{ 225 | PositionNedYaw: positionNedYaw, 226 | 227 | VelocityNedYaw: velocityNedYaw, 228 | 229 | AccelerationNed: accelerationNed, 230 | } 231 | response, err := s.Client.SetPositionVelocityAccelerationNed(ctx, request) 232 | if err != nil { 233 | return nil, err 234 | } 235 | return response, nil 236 | } 237 | 238 | /* 239 | SetAccelerationNed Set the acceleration in NED coordinates. 240 | */ 241 | func (s *ServiceImpl) SetAccelerationNed( 242 | ctx context.Context, 243 | accelerationNed *AccelerationNed, 244 | 245 | ) (*SetAccelerationNedResponse, error) { 246 | request := &SetAccelerationNedRequest{ 247 | AccelerationNed: accelerationNed, 248 | } 249 | response, err := s.Client.SetAccelerationNed(ctx, request) 250 | if err != nil { 251 | return nil, err 252 | } 253 | return response, nil 254 | } 255 | -------------------------------------------------------------------------------- /Sources/param_server/param_server.go: -------------------------------------------------------------------------------- 1 | package param_server 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client ParamServerServiceClient 14 | } 15 | 16 | /* 17 | SetProtocol Set param protocol. 18 | 19 | The extended param protocol is used by default. This allows to use the previous/normal one. 20 | 21 | Note that camera definition files are meant to implement/use the extended protocol. 22 | */ 23 | func (s *ServiceImpl) SetProtocol( 24 | ctx context.Context, 25 | extendedProtocol bool, 26 | 27 | ) (*SetProtocolResponse, error) { 28 | request := &SetProtocolRequest{ 29 | ExtendedProtocol: extendedProtocol, 30 | } 31 | response, err := s.Client.SetProtocol(ctx, request) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return response, nil 36 | } 37 | 38 | /* 39 | RetrieveParamInt Retrieve an int parameter. 40 | 41 | If the type is wrong, the result will be `WRONG_TYPE`. 42 | */ 43 | func (s *ServiceImpl) RetrieveParamInt( 44 | ctx context.Context, 45 | name string, 46 | 47 | ) (*RetrieveParamIntResponse, error) { 48 | request := &RetrieveParamIntRequest{ 49 | Name: name, 50 | } 51 | response, err := s.Client.RetrieveParamInt(ctx, request) 52 | if err != nil { 53 | return nil, err 54 | } 55 | return response, nil 56 | } 57 | 58 | /* 59 | ProvideParamInt Provide an int parameter. 60 | 61 | If the type is wrong, the result will be `WRONG_TYPE`. 62 | */ 63 | func (s *ServiceImpl) ProvideParamInt( 64 | ctx context.Context, 65 | name string, 66 | value int32, 67 | 68 | ) (*ProvideParamIntResponse, error) { 69 | request := &ProvideParamIntRequest{ 70 | Name: name, 71 | Value: value, 72 | } 73 | response, err := s.Client.ProvideParamInt(ctx, request) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return response, nil 78 | } 79 | 80 | /* 81 | RetrieveParamFloat Retrieve a float parameter. 82 | 83 | If the type is wrong, the result will be `WRONG_TYPE`. 84 | */ 85 | func (s *ServiceImpl) RetrieveParamFloat( 86 | ctx context.Context, 87 | name string, 88 | 89 | ) (*RetrieveParamFloatResponse, error) { 90 | request := &RetrieveParamFloatRequest{ 91 | Name: name, 92 | } 93 | response, err := s.Client.RetrieveParamFloat(ctx, request) 94 | if err != nil { 95 | return nil, err 96 | } 97 | return response, nil 98 | } 99 | 100 | /* 101 | ProvideParamFloat Provide a float parameter. 102 | 103 | If the type is wrong, the result will be `WRONG_TYPE`. 104 | */ 105 | func (s *ServiceImpl) ProvideParamFloat( 106 | ctx context.Context, 107 | name string, 108 | value float32, 109 | 110 | ) (*ProvideParamFloatResponse, error) { 111 | request := &ProvideParamFloatRequest{ 112 | Name: name, 113 | Value: value, 114 | } 115 | response, err := s.Client.ProvideParamFloat(ctx, request) 116 | if err != nil { 117 | return nil, err 118 | } 119 | return response, nil 120 | } 121 | 122 | /* 123 | RetrieveParamCustom Retrieve a custom parameter. 124 | 125 | If the type is wrong, the result will be `WRONG_TYPE`. 126 | */ 127 | func (s *ServiceImpl) RetrieveParamCustom( 128 | ctx context.Context, 129 | name string, 130 | 131 | ) (*RetrieveParamCustomResponse, error) { 132 | request := &RetrieveParamCustomRequest{ 133 | Name: name, 134 | } 135 | response, err := s.Client.RetrieveParamCustom(ctx, request) 136 | if err != nil { 137 | return nil, err 138 | } 139 | return response, nil 140 | } 141 | 142 | /* 143 | ProvideParamCustom Provide a custom parameter. 144 | 145 | If the type is wrong, the result will be `WRONG_TYPE`. 146 | */ 147 | func (s *ServiceImpl) ProvideParamCustom( 148 | ctx context.Context, 149 | name string, 150 | value string, 151 | 152 | ) (*ProvideParamCustomResponse, error) { 153 | request := &ProvideParamCustomRequest{ 154 | Name: name, 155 | Value: value, 156 | } 157 | response, err := s.Client.ProvideParamCustom(ctx, request) 158 | if err != nil { 159 | return nil, err 160 | } 161 | return response, nil 162 | } 163 | 164 | /* 165 | RetrieveAllParams Retrieve all parameters. 166 | */ 167 | func (s *ServiceImpl) RetrieveAllParams( 168 | ctx context.Context, 169 | 170 | ) (*RetrieveAllParamsResponse, error) { 171 | request := &RetrieveAllParamsRequest{} 172 | response, err := s.Client.RetrieveAllParams(ctx, request) 173 | if err != nil { 174 | return nil, err 175 | } 176 | return response, nil 177 | } 178 | 179 | /* 180 | ChangedParamInt Subscribe to changed int param. 181 | */ 182 | func (a *ServiceImpl) ChangedParamInt( 183 | ctx context.Context, 184 | 185 | ) (<-chan *IntParam, error) { 186 | ch := make(chan *IntParam) 187 | request := &SubscribeChangedParamIntRequest{} 188 | stream, err := a.Client.SubscribeChangedParamInt(ctx, request) 189 | if err != nil { 190 | return nil, err 191 | } 192 | go func() { 193 | defer close(ch) 194 | for { 195 | m := &ChangedParamIntResponse{} 196 | err := stream.RecvMsg(m) 197 | if err == io.EOF { 198 | return 199 | } 200 | if err != nil { 201 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 202 | return 203 | } 204 | log.Fatalf("Unable to receive ChangedParamInt messages, err: %v", err) 205 | } 206 | ch <- m.GetParam() 207 | } 208 | }() 209 | return ch, nil 210 | } 211 | 212 | /* 213 | ChangedParamFloat Subscribe to changed float param. 214 | */ 215 | func (a *ServiceImpl) ChangedParamFloat( 216 | ctx context.Context, 217 | 218 | ) (<-chan *FloatParam, error) { 219 | ch := make(chan *FloatParam) 220 | request := &SubscribeChangedParamFloatRequest{} 221 | stream, err := a.Client.SubscribeChangedParamFloat(ctx, request) 222 | if err != nil { 223 | return nil, err 224 | } 225 | go func() { 226 | defer close(ch) 227 | for { 228 | m := &ChangedParamFloatResponse{} 229 | err := stream.RecvMsg(m) 230 | if err == io.EOF { 231 | return 232 | } 233 | if err != nil { 234 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 235 | return 236 | } 237 | log.Fatalf("Unable to receive ChangedParamFloat messages, err: %v", err) 238 | } 239 | ch <- m.GetParam() 240 | } 241 | }() 242 | return ch, nil 243 | } 244 | 245 | /* 246 | ChangedParamCustom Subscribe to changed custom param. 247 | */ 248 | func (a *ServiceImpl) ChangedParamCustom( 249 | ctx context.Context, 250 | 251 | ) (<-chan *CustomParam, error) { 252 | ch := make(chan *CustomParam) 253 | request := &SubscribeChangedParamCustomRequest{} 254 | stream, err := a.Client.SubscribeChangedParamCustom(ctx, request) 255 | if err != nil { 256 | return nil, err 257 | } 258 | go func() { 259 | defer close(ch) 260 | for { 261 | m := &ChangedParamCustomResponse{} 262 | err := stream.RecvMsg(m) 263 | if err == io.EOF { 264 | return 265 | } 266 | if err != nil { 267 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 268 | return 269 | } 270 | log.Fatalf("Unable to receive ChangedParamCustom messages, err: %v", err) 271 | } 272 | ch <- m.GetParam() 273 | } 274 | }() 275 | return ch, nil 276 | } 277 | -------------------------------------------------------------------------------- /Sources/geofence/geofence_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: geofence.proto 6 | 7 | package geofence 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | GeofenceService_UploadGeofence_FullMethodName = "/mavsdk.rpc.geofence.GeofenceService/UploadGeofence" 24 | GeofenceService_ClearGeofence_FullMethodName = "/mavsdk.rpc.geofence.GeofenceService/ClearGeofence" 25 | ) 26 | 27 | // GeofenceServiceClient is the client API for GeofenceService service. 28 | // 29 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 30 | // 31 | // Enable setting a geofence. 32 | type GeofenceServiceClient interface { 33 | // Upload geofences. 34 | // 35 | // Polygon and Circular geofences are uploaded to a drone. Once uploaded, the geofence will remain 36 | // on the drone even if a connection is lost. 37 | UploadGeofence(ctx context.Context, in *UploadGeofenceRequest, opts ...grpc.CallOption) (*UploadGeofenceResponse, error) 38 | // Clear all geofences saved on the vehicle. 39 | ClearGeofence(ctx context.Context, in *ClearGeofenceRequest, opts ...grpc.CallOption) (*ClearGeofenceResponse, error) 40 | } 41 | 42 | type geofenceServiceClient struct { 43 | cc grpc.ClientConnInterface 44 | } 45 | 46 | func NewGeofenceServiceClient(cc grpc.ClientConnInterface) GeofenceServiceClient { 47 | return &geofenceServiceClient{cc} 48 | } 49 | 50 | func (c *geofenceServiceClient) UploadGeofence(ctx context.Context, in *UploadGeofenceRequest, opts ...grpc.CallOption) (*UploadGeofenceResponse, error) { 51 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 52 | out := new(UploadGeofenceResponse) 53 | err := c.cc.Invoke(ctx, GeofenceService_UploadGeofence_FullMethodName, in, out, cOpts...) 54 | if err != nil { 55 | return nil, err 56 | } 57 | return out, nil 58 | } 59 | 60 | func (c *geofenceServiceClient) ClearGeofence(ctx context.Context, in *ClearGeofenceRequest, opts ...grpc.CallOption) (*ClearGeofenceResponse, error) { 61 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 62 | out := new(ClearGeofenceResponse) 63 | err := c.cc.Invoke(ctx, GeofenceService_ClearGeofence_FullMethodName, in, out, cOpts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | // GeofenceServiceServer is the server API for GeofenceService service. 71 | // All implementations must embed UnimplementedGeofenceServiceServer 72 | // for forward compatibility. 73 | // 74 | // Enable setting a geofence. 75 | type GeofenceServiceServer interface { 76 | // Upload geofences. 77 | // 78 | // Polygon and Circular geofences are uploaded to a drone. Once uploaded, the geofence will remain 79 | // on the drone even if a connection is lost. 80 | UploadGeofence(context.Context, *UploadGeofenceRequest) (*UploadGeofenceResponse, error) 81 | // Clear all geofences saved on the vehicle. 82 | ClearGeofence(context.Context, *ClearGeofenceRequest) (*ClearGeofenceResponse, error) 83 | mustEmbedUnimplementedGeofenceServiceServer() 84 | } 85 | 86 | // UnimplementedGeofenceServiceServer must be embedded to have 87 | // forward compatible implementations. 88 | // 89 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 90 | // pointer dereference when methods are called. 91 | type UnimplementedGeofenceServiceServer struct{} 92 | 93 | func (UnimplementedGeofenceServiceServer) UploadGeofence(context.Context, *UploadGeofenceRequest) (*UploadGeofenceResponse, error) { 94 | return nil, status.Errorf(codes.Unimplemented, "method UploadGeofence not implemented") 95 | } 96 | func (UnimplementedGeofenceServiceServer) ClearGeofence(context.Context, *ClearGeofenceRequest) (*ClearGeofenceResponse, error) { 97 | return nil, status.Errorf(codes.Unimplemented, "method ClearGeofence not implemented") 98 | } 99 | func (UnimplementedGeofenceServiceServer) mustEmbedUnimplementedGeofenceServiceServer() {} 100 | func (UnimplementedGeofenceServiceServer) testEmbeddedByValue() {} 101 | 102 | // UnsafeGeofenceServiceServer may be embedded to opt out of forward compatibility for this service. 103 | // Use of this interface is not recommended, as added methods to GeofenceServiceServer will 104 | // result in compilation errors. 105 | type UnsafeGeofenceServiceServer interface { 106 | mustEmbedUnimplementedGeofenceServiceServer() 107 | } 108 | 109 | func RegisterGeofenceServiceServer(s grpc.ServiceRegistrar, srv GeofenceServiceServer) { 110 | // If the following call pancis, it indicates UnimplementedGeofenceServiceServer was 111 | // embedded by pointer and is nil. This will cause panics if an 112 | // unimplemented method is ever invoked, so we test this at initialization 113 | // time to prevent it from happening at runtime later due to I/O. 114 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 115 | t.testEmbeddedByValue() 116 | } 117 | s.RegisterService(&GeofenceService_ServiceDesc, srv) 118 | } 119 | 120 | func _GeofenceService_UploadGeofence_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 121 | in := new(UploadGeofenceRequest) 122 | if err := dec(in); err != nil { 123 | return nil, err 124 | } 125 | if interceptor == nil { 126 | return srv.(GeofenceServiceServer).UploadGeofence(ctx, in) 127 | } 128 | info := &grpc.UnaryServerInfo{ 129 | Server: srv, 130 | FullMethod: GeofenceService_UploadGeofence_FullMethodName, 131 | } 132 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 133 | return srv.(GeofenceServiceServer).UploadGeofence(ctx, req.(*UploadGeofenceRequest)) 134 | } 135 | return interceptor(ctx, in, info, handler) 136 | } 137 | 138 | func _GeofenceService_ClearGeofence_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 139 | in := new(ClearGeofenceRequest) 140 | if err := dec(in); err != nil { 141 | return nil, err 142 | } 143 | if interceptor == nil { 144 | return srv.(GeofenceServiceServer).ClearGeofence(ctx, in) 145 | } 146 | info := &grpc.UnaryServerInfo{ 147 | Server: srv, 148 | FullMethod: GeofenceService_ClearGeofence_FullMethodName, 149 | } 150 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 151 | return srv.(GeofenceServiceServer).ClearGeofence(ctx, req.(*ClearGeofenceRequest)) 152 | } 153 | return interceptor(ctx, in, info, handler) 154 | } 155 | 156 | // GeofenceService_ServiceDesc is the grpc.ServiceDesc for GeofenceService service. 157 | // It's only intended for direct use with grpc.RegisterService, 158 | // and not to be introspected or modified (even as a copy) 159 | var GeofenceService_ServiceDesc = grpc.ServiceDesc{ 160 | ServiceName: "mavsdk.rpc.geofence.GeofenceService", 161 | HandlerType: (*GeofenceServiceServer)(nil), 162 | Methods: []grpc.MethodDesc{ 163 | { 164 | MethodName: "UploadGeofence", 165 | Handler: _GeofenceService_UploadGeofence_Handler, 166 | }, 167 | { 168 | MethodName: "ClearGeofence", 169 | Handler: _GeofenceService_ClearGeofence_Handler, 170 | }, 171 | }, 172 | Streams: []grpc.StreamDesc{}, 173 | Metadata: "geofence.proto", 174 | } 175 | -------------------------------------------------------------------------------- /Sources/shell/shell_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: shell.proto 6 | 7 | package shell 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | ShellService_Send_FullMethodName = "/mavsdk.rpc.shell.ShellService/Send" 24 | ShellService_SubscribeReceive_FullMethodName = "/mavsdk.rpc.shell.ShellService/SubscribeReceive" 25 | ) 26 | 27 | // ShellServiceClient is the client API for ShellService service. 28 | // 29 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 30 | // 31 | // Allow to communicate with the vehicle's system shell. 32 | type ShellServiceClient interface { 33 | // Send a command line. 34 | Send(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error) 35 | // Receive feedback from a sent command line. 36 | // 37 | // This subscription needs to be made before a command line is sent, otherwise, no response will be sent. 38 | SubscribeReceive(ctx context.Context, in *SubscribeReceiveRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ReceiveResponse], error) 39 | } 40 | 41 | type shellServiceClient struct { 42 | cc grpc.ClientConnInterface 43 | } 44 | 45 | func NewShellServiceClient(cc grpc.ClientConnInterface) ShellServiceClient { 46 | return &shellServiceClient{cc} 47 | } 48 | 49 | func (c *shellServiceClient) Send(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error) { 50 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 51 | out := new(SendResponse) 52 | err := c.cc.Invoke(ctx, ShellService_Send_FullMethodName, in, out, cOpts...) 53 | if err != nil { 54 | return nil, err 55 | } 56 | return out, nil 57 | } 58 | 59 | func (c *shellServiceClient) SubscribeReceive(ctx context.Context, in *SubscribeReceiveRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ReceiveResponse], error) { 60 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 61 | stream, err := c.cc.NewStream(ctx, &ShellService_ServiceDesc.Streams[0], ShellService_SubscribeReceive_FullMethodName, cOpts...) 62 | if err != nil { 63 | return nil, err 64 | } 65 | x := &grpc.GenericClientStream[SubscribeReceiveRequest, ReceiveResponse]{ClientStream: stream} 66 | if err := x.ClientStream.SendMsg(in); err != nil { 67 | return nil, err 68 | } 69 | if err := x.ClientStream.CloseSend(); err != nil { 70 | return nil, err 71 | } 72 | return x, nil 73 | } 74 | 75 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 76 | type ShellService_SubscribeReceiveClient = grpc.ServerStreamingClient[ReceiveResponse] 77 | 78 | // ShellServiceServer is the server API for ShellService service. 79 | // All implementations must embed UnimplementedShellServiceServer 80 | // for forward compatibility. 81 | // 82 | // Allow to communicate with the vehicle's system shell. 83 | type ShellServiceServer interface { 84 | // Send a command line. 85 | Send(context.Context, *SendRequest) (*SendResponse, error) 86 | // Receive feedback from a sent command line. 87 | // 88 | // This subscription needs to be made before a command line is sent, otherwise, no response will be sent. 89 | SubscribeReceive(*SubscribeReceiveRequest, grpc.ServerStreamingServer[ReceiveResponse]) error 90 | mustEmbedUnimplementedShellServiceServer() 91 | } 92 | 93 | // UnimplementedShellServiceServer must be embedded to have 94 | // forward compatible implementations. 95 | // 96 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 97 | // pointer dereference when methods are called. 98 | type UnimplementedShellServiceServer struct{} 99 | 100 | func (UnimplementedShellServiceServer) Send(context.Context, *SendRequest) (*SendResponse, error) { 101 | return nil, status.Errorf(codes.Unimplemented, "method Send not implemented") 102 | } 103 | func (UnimplementedShellServiceServer) SubscribeReceive(*SubscribeReceiveRequest, grpc.ServerStreamingServer[ReceiveResponse]) error { 104 | return status.Errorf(codes.Unimplemented, "method SubscribeReceive not implemented") 105 | } 106 | func (UnimplementedShellServiceServer) mustEmbedUnimplementedShellServiceServer() {} 107 | func (UnimplementedShellServiceServer) testEmbeddedByValue() {} 108 | 109 | // UnsafeShellServiceServer may be embedded to opt out of forward compatibility for this service. 110 | // Use of this interface is not recommended, as added methods to ShellServiceServer will 111 | // result in compilation errors. 112 | type UnsafeShellServiceServer interface { 113 | mustEmbedUnimplementedShellServiceServer() 114 | } 115 | 116 | func RegisterShellServiceServer(s grpc.ServiceRegistrar, srv ShellServiceServer) { 117 | // If the following call pancis, it indicates UnimplementedShellServiceServer was 118 | // embedded by pointer and is nil. This will cause panics if an 119 | // unimplemented method is ever invoked, so we test this at initialization 120 | // time to prevent it from happening at runtime later due to I/O. 121 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 122 | t.testEmbeddedByValue() 123 | } 124 | s.RegisterService(&ShellService_ServiceDesc, srv) 125 | } 126 | 127 | func _ShellService_Send_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 128 | in := new(SendRequest) 129 | if err := dec(in); err != nil { 130 | return nil, err 131 | } 132 | if interceptor == nil { 133 | return srv.(ShellServiceServer).Send(ctx, in) 134 | } 135 | info := &grpc.UnaryServerInfo{ 136 | Server: srv, 137 | FullMethod: ShellService_Send_FullMethodName, 138 | } 139 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 140 | return srv.(ShellServiceServer).Send(ctx, req.(*SendRequest)) 141 | } 142 | return interceptor(ctx, in, info, handler) 143 | } 144 | 145 | func _ShellService_SubscribeReceive_Handler(srv interface{}, stream grpc.ServerStream) error { 146 | m := new(SubscribeReceiveRequest) 147 | if err := stream.RecvMsg(m); err != nil { 148 | return err 149 | } 150 | return srv.(ShellServiceServer).SubscribeReceive(m, &grpc.GenericServerStream[SubscribeReceiveRequest, ReceiveResponse]{ServerStream: stream}) 151 | } 152 | 153 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 154 | type ShellService_SubscribeReceiveServer = grpc.ServerStreamingServer[ReceiveResponse] 155 | 156 | // ShellService_ServiceDesc is the grpc.ServiceDesc for ShellService service. 157 | // It's only intended for direct use with grpc.RegisterService, 158 | // and not to be introspected or modified (even as a copy) 159 | var ShellService_ServiceDesc = grpc.ServiceDesc{ 160 | ServiceName: "mavsdk.rpc.shell.ShellService", 161 | HandlerType: (*ShellServiceServer)(nil), 162 | Methods: []grpc.MethodDesc{ 163 | { 164 | MethodName: "Send", 165 | Handler: _ShellService_Send_Handler, 166 | }, 167 | }, 168 | Streams: []grpc.StreamDesc{ 169 | { 170 | StreamName: "SubscribeReceive", 171 | Handler: _ShellService_SubscribeReceive_Handler, 172 | ServerStreams: true, 173 | }, 174 | }, 175 | Metadata: "shell.proto", 176 | } 177 | -------------------------------------------------------------------------------- /Sources/transponder/transponder_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: transponder.proto 6 | 7 | package transponder 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | TransponderService_SubscribeTransponder_FullMethodName = "/mavsdk.rpc.transponder.TransponderService/SubscribeTransponder" 24 | TransponderService_SetRateTransponder_FullMethodName = "/mavsdk.rpc.transponder.TransponderService/SetRateTransponder" 25 | ) 26 | 27 | // TransponderServiceClient is the client API for TransponderService service. 28 | // 29 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 30 | // 31 | // Allow users to get ADS-B information 32 | // and set ADS-B update rates. 33 | type TransponderServiceClient interface { 34 | // Subscribe to 'transponder' updates. 35 | SubscribeTransponder(ctx context.Context, in *SubscribeTransponderRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TransponderResponse], error) 36 | // Set rate to 'transponder' updates. 37 | SetRateTransponder(ctx context.Context, in *SetRateTransponderRequest, opts ...grpc.CallOption) (*SetRateTransponderResponse, error) 38 | } 39 | 40 | type transponderServiceClient struct { 41 | cc grpc.ClientConnInterface 42 | } 43 | 44 | func NewTransponderServiceClient(cc grpc.ClientConnInterface) TransponderServiceClient { 45 | return &transponderServiceClient{cc} 46 | } 47 | 48 | func (c *transponderServiceClient) SubscribeTransponder(ctx context.Context, in *SubscribeTransponderRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TransponderResponse], error) { 49 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 50 | stream, err := c.cc.NewStream(ctx, &TransponderService_ServiceDesc.Streams[0], TransponderService_SubscribeTransponder_FullMethodName, cOpts...) 51 | if err != nil { 52 | return nil, err 53 | } 54 | x := &grpc.GenericClientStream[SubscribeTransponderRequest, TransponderResponse]{ClientStream: stream} 55 | if err := x.ClientStream.SendMsg(in); err != nil { 56 | return nil, err 57 | } 58 | if err := x.ClientStream.CloseSend(); err != nil { 59 | return nil, err 60 | } 61 | return x, nil 62 | } 63 | 64 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 65 | type TransponderService_SubscribeTransponderClient = grpc.ServerStreamingClient[TransponderResponse] 66 | 67 | func (c *transponderServiceClient) SetRateTransponder(ctx context.Context, in *SetRateTransponderRequest, opts ...grpc.CallOption) (*SetRateTransponderResponse, error) { 68 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 69 | out := new(SetRateTransponderResponse) 70 | err := c.cc.Invoke(ctx, TransponderService_SetRateTransponder_FullMethodName, in, out, cOpts...) 71 | if err != nil { 72 | return nil, err 73 | } 74 | return out, nil 75 | } 76 | 77 | // TransponderServiceServer is the server API for TransponderService service. 78 | // All implementations must embed UnimplementedTransponderServiceServer 79 | // for forward compatibility. 80 | // 81 | // Allow users to get ADS-B information 82 | // and set ADS-B update rates. 83 | type TransponderServiceServer interface { 84 | // Subscribe to 'transponder' updates. 85 | SubscribeTransponder(*SubscribeTransponderRequest, grpc.ServerStreamingServer[TransponderResponse]) error 86 | // Set rate to 'transponder' updates. 87 | SetRateTransponder(context.Context, *SetRateTransponderRequest) (*SetRateTransponderResponse, error) 88 | mustEmbedUnimplementedTransponderServiceServer() 89 | } 90 | 91 | // UnimplementedTransponderServiceServer must be embedded to have 92 | // forward compatible implementations. 93 | // 94 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 95 | // pointer dereference when methods are called. 96 | type UnimplementedTransponderServiceServer struct{} 97 | 98 | func (UnimplementedTransponderServiceServer) SubscribeTransponder(*SubscribeTransponderRequest, grpc.ServerStreamingServer[TransponderResponse]) error { 99 | return status.Errorf(codes.Unimplemented, "method SubscribeTransponder not implemented") 100 | } 101 | func (UnimplementedTransponderServiceServer) SetRateTransponder(context.Context, *SetRateTransponderRequest) (*SetRateTransponderResponse, error) { 102 | return nil, status.Errorf(codes.Unimplemented, "method SetRateTransponder not implemented") 103 | } 104 | func (UnimplementedTransponderServiceServer) mustEmbedUnimplementedTransponderServiceServer() {} 105 | func (UnimplementedTransponderServiceServer) testEmbeddedByValue() {} 106 | 107 | // UnsafeTransponderServiceServer may be embedded to opt out of forward compatibility for this service. 108 | // Use of this interface is not recommended, as added methods to TransponderServiceServer will 109 | // result in compilation errors. 110 | type UnsafeTransponderServiceServer interface { 111 | mustEmbedUnimplementedTransponderServiceServer() 112 | } 113 | 114 | func RegisterTransponderServiceServer(s grpc.ServiceRegistrar, srv TransponderServiceServer) { 115 | // If the following call pancis, it indicates UnimplementedTransponderServiceServer was 116 | // embedded by pointer and is nil. This will cause panics if an 117 | // unimplemented method is ever invoked, so we test this at initialization 118 | // time to prevent it from happening at runtime later due to I/O. 119 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 120 | t.testEmbeddedByValue() 121 | } 122 | s.RegisterService(&TransponderService_ServiceDesc, srv) 123 | } 124 | 125 | func _TransponderService_SubscribeTransponder_Handler(srv interface{}, stream grpc.ServerStream) error { 126 | m := new(SubscribeTransponderRequest) 127 | if err := stream.RecvMsg(m); err != nil { 128 | return err 129 | } 130 | return srv.(TransponderServiceServer).SubscribeTransponder(m, &grpc.GenericServerStream[SubscribeTransponderRequest, TransponderResponse]{ServerStream: stream}) 131 | } 132 | 133 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 134 | type TransponderService_SubscribeTransponderServer = grpc.ServerStreamingServer[TransponderResponse] 135 | 136 | func _TransponderService_SetRateTransponder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 137 | in := new(SetRateTransponderRequest) 138 | if err := dec(in); err != nil { 139 | return nil, err 140 | } 141 | if interceptor == nil { 142 | return srv.(TransponderServiceServer).SetRateTransponder(ctx, in) 143 | } 144 | info := &grpc.UnaryServerInfo{ 145 | Server: srv, 146 | FullMethod: TransponderService_SetRateTransponder_FullMethodName, 147 | } 148 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 149 | return srv.(TransponderServiceServer).SetRateTransponder(ctx, req.(*SetRateTransponderRequest)) 150 | } 151 | return interceptor(ctx, in, info, handler) 152 | } 153 | 154 | // TransponderService_ServiceDesc is the grpc.ServiceDesc for TransponderService service. 155 | // It's only intended for direct use with grpc.RegisterService, 156 | // and not to be introspected or modified (even as a copy) 157 | var TransponderService_ServiceDesc = grpc.ServiceDesc{ 158 | ServiceName: "mavsdk.rpc.transponder.TransponderService", 159 | HandlerType: (*TransponderServiceServer)(nil), 160 | Methods: []grpc.MethodDesc{ 161 | { 162 | MethodName: "SetRateTransponder", 163 | Handler: _TransponderService_SetRateTransponder_Handler, 164 | }, 165 | }, 166 | Streams: []grpc.StreamDesc{ 167 | { 168 | StreamName: "SubscribeTransponder", 169 | Handler: _TransponderService_SubscribeTransponder_Handler, 170 | ServerStreams: true, 171 | }, 172 | }, 173 | Metadata: "transponder.proto", 174 | } 175 | -------------------------------------------------------------------------------- /Sources/gimbal/gimbal.go: -------------------------------------------------------------------------------- 1 | package gimbal 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client GimbalServiceClient 14 | } 15 | 16 | /* 17 | SetAngles Set gimbal roll, pitch and yaw angles. 18 | 19 | This sets the desired roll, pitch and yaw angles of a gimbal. 20 | Will return when the command is accepted, however, it might 21 | take the gimbal longer to actually be set to the new angles. 22 | 23 | Note that the roll angle needs to be set to 0 when send_mode is Once. 24 | */ 25 | func (s *ServiceImpl) SetAngles( 26 | ctx context.Context, 27 | gimbalId int32, 28 | rollDeg float32, 29 | pitchDeg float32, 30 | yawDeg float32, 31 | gimbalMode *GimbalMode, 32 | 33 | sendMode *SendMode, 34 | 35 | ) (*SetAnglesResponse, error) { 36 | request := &SetAnglesRequest{ 37 | GimbalId: gimbalId, 38 | RollDeg: rollDeg, 39 | PitchDeg: pitchDeg, 40 | YawDeg: yawDeg, 41 | GimbalMode: *gimbalMode, 42 | SendMode: *sendMode, 43 | } 44 | response, err := s.Client.SetAngles(ctx, request) 45 | if err != nil { 46 | return nil, err 47 | } 48 | return response, nil 49 | } 50 | 51 | /* 52 | SetAngularRates Set gimbal angular rates. 53 | 54 | This sets the desired angular rates around roll, pitch and yaw axes of a gimbal. 55 | Will return when the command is accepted, however, it might 56 | take the gimbal longer to actually reach the angular rate. 57 | 58 | Note that the roll angle needs to be set to 0 when send_mode is Once. 59 | */ 60 | func (s *ServiceImpl) SetAngularRates( 61 | ctx context.Context, 62 | gimbalId int32, 63 | rollRateDegS float32, 64 | pitchRateDegS float32, 65 | yawRateDegS float32, 66 | gimbalMode *GimbalMode, 67 | 68 | sendMode *SendMode, 69 | 70 | ) (*SetAngularRatesResponse, error) { 71 | request := &SetAngularRatesRequest{ 72 | GimbalId: gimbalId, 73 | RollRateDegS: rollRateDegS, 74 | PitchRateDegS: pitchRateDegS, 75 | YawRateDegS: yawRateDegS, 76 | GimbalMode: *gimbalMode, 77 | SendMode: *sendMode, 78 | } 79 | response, err := s.Client.SetAngularRates(ctx, request) 80 | if err != nil { 81 | return nil, err 82 | } 83 | return response, nil 84 | } 85 | 86 | /* 87 | SetRoiLocation Set gimbal region of interest (ROI). 88 | 89 | This sets a region of interest that the gimbal will point to. 90 | The gimbal will continue to point to the specified region until it 91 | receives a new command. 92 | The function will return when the command is accepted, however, it might 93 | take the gimbal longer to actually rotate to the ROI. 94 | */ 95 | func (s *ServiceImpl) SetRoiLocation( 96 | ctx context.Context, 97 | gimbalId int32, 98 | latitudeDeg float64, 99 | longitudeDeg float64, 100 | altitudeM float32, 101 | 102 | ) (*SetRoiLocationResponse, error) { 103 | request := &SetRoiLocationRequest{ 104 | GimbalId: gimbalId, 105 | LatitudeDeg: latitudeDeg, 106 | LongitudeDeg: longitudeDeg, 107 | AltitudeM: altitudeM, 108 | } 109 | response, err := s.Client.SetRoiLocation(ctx, request) 110 | if err != nil { 111 | return nil, err 112 | } 113 | return response, nil 114 | } 115 | 116 | /* 117 | TakeControl Take control. 118 | 119 | There can be only two components in control of a gimbal at any given time. 120 | One with "primary" control, and one with "secondary" control. The way the 121 | secondary control is implemented is not specified and hence depends on the 122 | vehicle. 123 | 124 | Components are expected to be cooperative, which means that they can 125 | override each other and should therefore do it carefully. 126 | */ 127 | func (s *ServiceImpl) TakeControl( 128 | ctx context.Context, 129 | gimbalId int32, 130 | controlMode *ControlMode, 131 | 132 | ) (*TakeControlResponse, error) { 133 | request := &TakeControlRequest{ 134 | GimbalId: gimbalId, 135 | ControlMode: *controlMode, 136 | } 137 | response, err := s.Client.TakeControl(ctx, request) 138 | if err != nil { 139 | return nil, err 140 | } 141 | return response, nil 142 | } 143 | 144 | /* 145 | ReleaseControl Release control. 146 | 147 | Release control, such that other components can control the gimbal. 148 | */ 149 | func (s *ServiceImpl) ReleaseControl( 150 | ctx context.Context, 151 | gimbalId int32, 152 | 153 | ) (*ReleaseControlResponse, error) { 154 | request := &ReleaseControlRequest{ 155 | GimbalId: gimbalId, 156 | } 157 | response, err := s.Client.ReleaseControl(ctx, request) 158 | if err != nil { 159 | return nil, err 160 | } 161 | return response, nil 162 | } 163 | 164 | /* 165 | GimbalList Subscribe to list of gimbals. 166 | 167 | This allows to find out what gimbals are connected to the system. 168 | Based on the gimbal ID, we can then address a specific gimbal. 169 | */ 170 | func (a *ServiceImpl) GimbalList( 171 | ctx context.Context, 172 | 173 | ) (<-chan *GimbalList, error) { 174 | ch := make(chan *GimbalList) 175 | request := &SubscribeGimbalListRequest{} 176 | stream, err := a.Client.SubscribeGimbalList(ctx, request) 177 | if err != nil { 178 | return nil, err 179 | } 180 | go func() { 181 | defer close(ch) 182 | for { 183 | m := &GimbalListResponse{} 184 | err := stream.RecvMsg(m) 185 | if err == io.EOF { 186 | return 187 | } 188 | if err != nil { 189 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 190 | return 191 | } 192 | log.Fatalf("Unable to receive GimbalList messages, err: %v", err) 193 | } 194 | ch <- m.GetGimbalList() 195 | } 196 | }() 197 | return ch, nil 198 | } 199 | 200 | /* 201 | ControlStatus Subscribe to control status updates. 202 | 203 | This allows a component to know if it has primary, secondary or 204 | no control over the gimbal. Also, it gives the system and component ids 205 | of the other components in control (if any). 206 | */ 207 | func (a *ServiceImpl) ControlStatus( 208 | ctx context.Context, 209 | 210 | ) (<-chan *ControlStatus, error) { 211 | ch := make(chan *ControlStatus) 212 | request := &SubscribeControlStatusRequest{} 213 | stream, err := a.Client.SubscribeControlStatus(ctx, request) 214 | if err != nil { 215 | return nil, err 216 | } 217 | go func() { 218 | defer close(ch) 219 | for { 220 | m := &ControlStatusResponse{} 221 | err := stream.RecvMsg(m) 222 | if err == io.EOF { 223 | return 224 | } 225 | if err != nil { 226 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 227 | return 228 | } 229 | log.Fatalf("Unable to receive ControlStatus messages, err: %v", err) 230 | } 231 | ch <- m.GetControlStatus() 232 | } 233 | }() 234 | return ch, nil 235 | } 236 | 237 | /* 238 | GetControlStatus Get control status for specific gimbal. 239 | */ 240 | func (s *ServiceImpl) GetControlStatus( 241 | ctx context.Context, 242 | gimbalId int32, 243 | 244 | ) (*GetControlStatusResponse, error) { 245 | request := &GetControlStatusRequest{ 246 | GimbalId: gimbalId, 247 | } 248 | response, err := s.Client.GetControlStatus(ctx, request) 249 | if err != nil { 250 | return nil, err 251 | } 252 | return response, nil 253 | } 254 | 255 | /* 256 | Attitude Subscribe to attitude updates. 257 | 258 | This gets you the gimbal's attitude and angular rate. 259 | */ 260 | func (a *ServiceImpl) Attitude( 261 | ctx context.Context, 262 | 263 | ) (<-chan *Attitude, error) { 264 | ch := make(chan *Attitude) 265 | request := &SubscribeAttitudeRequest{} 266 | stream, err := a.Client.SubscribeAttitude(ctx, request) 267 | if err != nil { 268 | return nil, err 269 | } 270 | go func() { 271 | defer close(ch) 272 | for { 273 | m := &AttitudeResponse{} 274 | err := stream.RecvMsg(m) 275 | if err == io.EOF { 276 | return 277 | } 278 | if err != nil { 279 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 280 | return 281 | } 282 | log.Fatalf("Unable to receive Attitude messages, err: %v", err) 283 | } 284 | ch <- m.GetAttitude() 285 | } 286 | }() 287 | return ch, nil 288 | } 289 | 290 | /* 291 | GetAttitude Get attitude for specific gimbal. 292 | */ 293 | func (s *ServiceImpl) GetAttitude( 294 | ctx context.Context, 295 | gimbalId int32, 296 | 297 | ) (*GetAttitudeResponse, error) { 298 | request := &GetAttitudeRequest{ 299 | GimbalId: gimbalId, 300 | } 301 | response, err := s.Client.GetAttitude(ctx, request) 302 | if err != nil { 303 | return nil, err 304 | } 305 | return response, nil 306 | } 307 | -------------------------------------------------------------------------------- /Sources/core/core_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: core.proto 6 | 7 | package core 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | CoreService_SubscribeConnectionState_FullMethodName = "/mavsdk.rpc.core.CoreService/SubscribeConnectionState" 24 | CoreService_SetMavlinkTimeout_FullMethodName = "/mavsdk.rpc.core.CoreService/SetMavlinkTimeout" 25 | ) 26 | 27 | // CoreServiceClient is the client API for CoreService service. 28 | // 29 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 30 | // 31 | // Access to the connection state and core configurations 32 | type CoreServiceClient interface { 33 | // Subscribe to 'connection state' updates. 34 | SubscribeConnectionState(ctx context.Context, in *SubscribeConnectionStateRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ConnectionStateResponse], error) 35 | // Set timeout of MAVLink transfers. 36 | // 37 | // The default timeout used is generally (0.5 seconds) seconds. 38 | // If MAVSDK is used on the same host this timeout can be reduced, while 39 | // if MAVSDK has to communicate over links with high latency it might 40 | // need to be increased to prevent timeouts. 41 | SetMavlinkTimeout(ctx context.Context, in *SetMavlinkTimeoutRequest, opts ...grpc.CallOption) (*SetMavlinkTimeoutResponse, error) 42 | } 43 | 44 | type coreServiceClient struct { 45 | cc grpc.ClientConnInterface 46 | } 47 | 48 | func NewCoreServiceClient(cc grpc.ClientConnInterface) CoreServiceClient { 49 | return &coreServiceClient{cc} 50 | } 51 | 52 | func (c *coreServiceClient) SubscribeConnectionState(ctx context.Context, in *SubscribeConnectionStateRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ConnectionStateResponse], error) { 53 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 54 | stream, err := c.cc.NewStream(ctx, &CoreService_ServiceDesc.Streams[0], CoreService_SubscribeConnectionState_FullMethodName, cOpts...) 55 | if err != nil { 56 | return nil, err 57 | } 58 | x := &grpc.GenericClientStream[SubscribeConnectionStateRequest, ConnectionStateResponse]{ClientStream: stream} 59 | if err := x.ClientStream.SendMsg(in); err != nil { 60 | return nil, err 61 | } 62 | if err := x.ClientStream.CloseSend(); err != nil { 63 | return nil, err 64 | } 65 | return x, nil 66 | } 67 | 68 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 69 | type CoreService_SubscribeConnectionStateClient = grpc.ServerStreamingClient[ConnectionStateResponse] 70 | 71 | func (c *coreServiceClient) SetMavlinkTimeout(ctx context.Context, in *SetMavlinkTimeoutRequest, opts ...grpc.CallOption) (*SetMavlinkTimeoutResponse, error) { 72 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 73 | out := new(SetMavlinkTimeoutResponse) 74 | err := c.cc.Invoke(ctx, CoreService_SetMavlinkTimeout_FullMethodName, in, out, cOpts...) 75 | if err != nil { 76 | return nil, err 77 | } 78 | return out, nil 79 | } 80 | 81 | // CoreServiceServer is the server API for CoreService service. 82 | // All implementations must embed UnimplementedCoreServiceServer 83 | // for forward compatibility. 84 | // 85 | // Access to the connection state and core configurations 86 | type CoreServiceServer interface { 87 | // Subscribe to 'connection state' updates. 88 | SubscribeConnectionState(*SubscribeConnectionStateRequest, grpc.ServerStreamingServer[ConnectionStateResponse]) error 89 | // Set timeout of MAVLink transfers. 90 | // 91 | // The default timeout used is generally (0.5 seconds) seconds. 92 | // If MAVSDK is used on the same host this timeout can be reduced, while 93 | // if MAVSDK has to communicate over links with high latency it might 94 | // need to be increased to prevent timeouts. 95 | SetMavlinkTimeout(context.Context, *SetMavlinkTimeoutRequest) (*SetMavlinkTimeoutResponse, error) 96 | mustEmbedUnimplementedCoreServiceServer() 97 | } 98 | 99 | // UnimplementedCoreServiceServer must be embedded to have 100 | // forward compatible implementations. 101 | // 102 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 103 | // pointer dereference when methods are called. 104 | type UnimplementedCoreServiceServer struct{} 105 | 106 | func (UnimplementedCoreServiceServer) SubscribeConnectionState(*SubscribeConnectionStateRequest, grpc.ServerStreamingServer[ConnectionStateResponse]) error { 107 | return status.Errorf(codes.Unimplemented, "method SubscribeConnectionState not implemented") 108 | } 109 | func (UnimplementedCoreServiceServer) SetMavlinkTimeout(context.Context, *SetMavlinkTimeoutRequest) (*SetMavlinkTimeoutResponse, error) { 110 | return nil, status.Errorf(codes.Unimplemented, "method SetMavlinkTimeout not implemented") 111 | } 112 | func (UnimplementedCoreServiceServer) mustEmbedUnimplementedCoreServiceServer() {} 113 | func (UnimplementedCoreServiceServer) testEmbeddedByValue() {} 114 | 115 | // UnsafeCoreServiceServer may be embedded to opt out of forward compatibility for this service. 116 | // Use of this interface is not recommended, as added methods to CoreServiceServer will 117 | // result in compilation errors. 118 | type UnsafeCoreServiceServer interface { 119 | mustEmbedUnimplementedCoreServiceServer() 120 | } 121 | 122 | func RegisterCoreServiceServer(s grpc.ServiceRegistrar, srv CoreServiceServer) { 123 | // If the following call pancis, it indicates UnimplementedCoreServiceServer was 124 | // embedded by pointer and is nil. This will cause panics if an 125 | // unimplemented method is ever invoked, so we test this at initialization 126 | // time to prevent it from happening at runtime later due to I/O. 127 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 128 | t.testEmbeddedByValue() 129 | } 130 | s.RegisterService(&CoreService_ServiceDesc, srv) 131 | } 132 | 133 | func _CoreService_SubscribeConnectionState_Handler(srv interface{}, stream grpc.ServerStream) error { 134 | m := new(SubscribeConnectionStateRequest) 135 | if err := stream.RecvMsg(m); err != nil { 136 | return err 137 | } 138 | return srv.(CoreServiceServer).SubscribeConnectionState(m, &grpc.GenericServerStream[SubscribeConnectionStateRequest, ConnectionStateResponse]{ServerStream: stream}) 139 | } 140 | 141 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 142 | type CoreService_SubscribeConnectionStateServer = grpc.ServerStreamingServer[ConnectionStateResponse] 143 | 144 | func _CoreService_SetMavlinkTimeout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 145 | in := new(SetMavlinkTimeoutRequest) 146 | if err := dec(in); err != nil { 147 | return nil, err 148 | } 149 | if interceptor == nil { 150 | return srv.(CoreServiceServer).SetMavlinkTimeout(ctx, in) 151 | } 152 | info := &grpc.UnaryServerInfo{ 153 | Server: srv, 154 | FullMethod: CoreService_SetMavlinkTimeout_FullMethodName, 155 | } 156 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 157 | return srv.(CoreServiceServer).SetMavlinkTimeout(ctx, req.(*SetMavlinkTimeoutRequest)) 158 | } 159 | return interceptor(ctx, in, info, handler) 160 | } 161 | 162 | // CoreService_ServiceDesc is the grpc.ServiceDesc for CoreService service. 163 | // It's only intended for direct use with grpc.RegisterService, 164 | // and not to be introspected or modified (even as a copy) 165 | var CoreService_ServiceDesc = grpc.ServiceDesc{ 166 | ServiceName: "mavsdk.rpc.core.CoreService", 167 | HandlerType: (*CoreServiceServer)(nil), 168 | Methods: []grpc.MethodDesc{ 169 | { 170 | MethodName: "SetMavlinkTimeout", 171 | Handler: _CoreService_SetMavlinkTimeout_Handler, 172 | }, 173 | }, 174 | Streams: []grpc.StreamDesc{ 175 | { 176 | StreamName: "SubscribeConnectionState", 177 | Handler: _CoreService_SubscribeConnectionState_Handler, 178 | ServerStreams: true, 179 | }, 180 | }, 181 | Metadata: "core.proto", 182 | } 183 | -------------------------------------------------------------------------------- /Sources/telemetry_server/telemetry_server.go: -------------------------------------------------------------------------------- 1 | package telemetry_server 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type ServiceImpl struct { 8 | Client TelemetryServerServiceClient 9 | } 10 | 11 | /* 12 | PublishPosition Publish to 'position' updates. 13 | */ 14 | func (s *ServiceImpl) PublishPosition( 15 | ctx context.Context, 16 | position *Position, 17 | 18 | velocityNed *VelocityNed, 19 | 20 | heading *Heading, 21 | 22 | ) (*PublishPositionResponse, error) { 23 | request := &PublishPositionRequest{ 24 | Position: position, 25 | 26 | VelocityNed: velocityNed, 27 | 28 | Heading: heading, 29 | } 30 | response, err := s.Client.PublishPosition(ctx, request) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return response, nil 35 | } 36 | 37 | /* 38 | PublishHome Publish to 'home position' updates. 39 | */ 40 | func (s *ServiceImpl) PublishHome( 41 | ctx context.Context, 42 | home *Position, 43 | 44 | ) (*PublishHomeResponse, error) { 45 | request := &PublishHomeRequest{ 46 | Home: home, 47 | } 48 | response, err := s.Client.PublishHome(ctx, request) 49 | if err != nil { 50 | return nil, err 51 | } 52 | return response, nil 53 | } 54 | 55 | /* 56 | PublishSysStatus Publish 'sys status' updates. 57 | */ 58 | func (s *ServiceImpl) PublishSysStatus( 59 | ctx context.Context, 60 | battery *Battery, 61 | 62 | rcReceiverStatus bool, 63 | gyroStatus bool, 64 | accelStatus bool, 65 | magStatus bool, 66 | gpsStatus bool, 67 | 68 | ) (*PublishSysStatusResponse, error) { 69 | request := &PublishSysStatusRequest{ 70 | Battery: battery, 71 | 72 | RcReceiverStatus: rcReceiverStatus, 73 | GyroStatus: gyroStatus, 74 | AccelStatus: accelStatus, 75 | MagStatus: magStatus, 76 | GpsStatus: gpsStatus, 77 | } 78 | response, err := s.Client.PublishSysStatus(ctx, request) 79 | if err != nil { 80 | return nil, err 81 | } 82 | return response, nil 83 | } 84 | 85 | /* 86 | PublishExtendedSysState Publish 'extended sys state' updates. 87 | */ 88 | func (s *ServiceImpl) PublishExtendedSysState( 89 | ctx context.Context, 90 | vtolState *VtolState, 91 | 92 | landedState *LandedState, 93 | 94 | ) (*PublishExtendedSysStateResponse, error) { 95 | request := &PublishExtendedSysStateRequest{ 96 | VtolState: *vtolState, 97 | LandedState: *landedState, 98 | } 99 | response, err := s.Client.PublishExtendedSysState(ctx, request) 100 | if err != nil { 101 | return nil, err 102 | } 103 | return response, nil 104 | } 105 | 106 | /* 107 | PublishRawGps Publish to 'Raw GPS' updates. 108 | */ 109 | func (s *ServiceImpl) PublishRawGps( 110 | ctx context.Context, 111 | rawGps *RawGps, 112 | 113 | gpsInfo *GpsInfo, 114 | 115 | ) (*PublishRawGpsResponse, error) { 116 | request := &PublishRawGpsRequest{ 117 | RawGps: rawGps, 118 | 119 | GpsInfo: gpsInfo, 120 | } 121 | response, err := s.Client.PublishRawGps(ctx, request) 122 | if err != nil { 123 | return nil, err 124 | } 125 | return response, nil 126 | } 127 | 128 | /* 129 | PublishBattery Publish to 'battery' updates. 130 | */ 131 | func (s *ServiceImpl) PublishBattery( 132 | ctx context.Context, 133 | battery *Battery, 134 | 135 | ) (*PublishBatteryResponse, error) { 136 | request := &PublishBatteryRequest{ 137 | Battery: battery, 138 | } 139 | response, err := s.Client.PublishBattery(ctx, request) 140 | if err != nil { 141 | return nil, err 142 | } 143 | return response, nil 144 | } 145 | 146 | /* 147 | PublishStatusText Publish to 'status text' updates. 148 | */ 149 | func (s *ServiceImpl) PublishStatusText( 150 | ctx context.Context, 151 | statusText *StatusText, 152 | 153 | ) (*PublishStatusTextResponse, error) { 154 | request := &PublishStatusTextRequest{ 155 | StatusText: statusText, 156 | } 157 | response, err := s.Client.PublishStatusText(ctx, request) 158 | if err != nil { 159 | return nil, err 160 | } 161 | return response, nil 162 | } 163 | 164 | /* 165 | PublishOdometry Publish to 'odometry' updates. 166 | */ 167 | func (s *ServiceImpl) PublishOdometry( 168 | ctx context.Context, 169 | odometry *Odometry, 170 | 171 | ) (*PublishOdometryResponse, error) { 172 | request := &PublishOdometryRequest{ 173 | Odometry: odometry, 174 | } 175 | response, err := s.Client.PublishOdometry(ctx, request) 176 | if err != nil { 177 | return nil, err 178 | } 179 | return response, nil 180 | } 181 | 182 | /* 183 | PublishPositionVelocityNed Publish to 'position velocity' updates. 184 | */ 185 | func (s *ServiceImpl) PublishPositionVelocityNed( 186 | ctx context.Context, 187 | positionVelocityNed *PositionVelocityNed, 188 | 189 | ) (*PublishPositionVelocityNedResponse, error) { 190 | request := &PublishPositionVelocityNedRequest{ 191 | PositionVelocityNed: positionVelocityNed, 192 | } 193 | response, err := s.Client.PublishPositionVelocityNed(ctx, request) 194 | if err != nil { 195 | return nil, err 196 | } 197 | return response, nil 198 | } 199 | 200 | /* 201 | PublishGroundTruth Publish to 'ground truth' updates. 202 | */ 203 | func (s *ServiceImpl) PublishGroundTruth( 204 | ctx context.Context, 205 | groundTruth *GroundTruth, 206 | 207 | ) (*PublishGroundTruthResponse, error) { 208 | request := &PublishGroundTruthRequest{ 209 | GroundTruth: groundTruth, 210 | } 211 | response, err := s.Client.PublishGroundTruth(ctx, request) 212 | if err != nil { 213 | return nil, err 214 | } 215 | return response, nil 216 | } 217 | 218 | /* 219 | PublishImu Publish to 'IMU' updates (in SI units in NED body frame). 220 | */ 221 | func (s *ServiceImpl) PublishImu( 222 | ctx context.Context, 223 | imu *Imu, 224 | 225 | ) (*PublishImuResponse, error) { 226 | request := &PublishImuRequest{ 227 | Imu: imu, 228 | } 229 | response, err := s.Client.PublishImu(ctx, request) 230 | if err != nil { 231 | return nil, err 232 | } 233 | return response, nil 234 | } 235 | 236 | /* 237 | PublishScaledImu Publish to 'Scaled IMU' updates. 238 | */ 239 | func (s *ServiceImpl) PublishScaledImu( 240 | ctx context.Context, 241 | imu *Imu, 242 | 243 | ) (*PublishScaledImuResponse, error) { 244 | request := &PublishScaledImuRequest{ 245 | Imu: imu, 246 | } 247 | response, err := s.Client.PublishScaledImu(ctx, request) 248 | if err != nil { 249 | return nil, err 250 | } 251 | return response, nil 252 | } 253 | 254 | /* 255 | PublishRawImu Publish to 'Raw IMU' updates. 256 | */ 257 | func (s *ServiceImpl) PublishRawImu( 258 | ctx context.Context, 259 | imu *Imu, 260 | 261 | ) (*PublishRawImuResponse, error) { 262 | request := &PublishRawImuRequest{ 263 | Imu: imu, 264 | } 265 | response, err := s.Client.PublishRawImu(ctx, request) 266 | if err != nil { 267 | return nil, err 268 | } 269 | return response, nil 270 | } 271 | 272 | /* 273 | PublishUnixEpochTime Publish to 'unix epoch time' updates. 274 | */ 275 | func (s *ServiceImpl) PublishUnixEpochTime( 276 | ctx context.Context, 277 | timeUs uint64, 278 | 279 | ) (*PublishUnixEpochTimeResponse, error) { 280 | request := &PublishUnixEpochTimeRequest{ 281 | TimeUs: timeUs, 282 | } 283 | response, err := s.Client.PublishUnixEpochTime(ctx, request) 284 | if err != nil { 285 | return nil, err 286 | } 287 | return response, nil 288 | } 289 | 290 | /* 291 | PublishDistanceSensor Publish to "distance sensor" updates. 292 | */ 293 | func (s *ServiceImpl) PublishDistanceSensor( 294 | ctx context.Context, 295 | distanceSensor *DistanceSensor, 296 | 297 | ) (*PublishDistanceSensorResponse, error) { 298 | request := &PublishDistanceSensorRequest{ 299 | DistanceSensor: distanceSensor, 300 | } 301 | response, err := s.Client.PublishDistanceSensor(ctx, request) 302 | if err != nil { 303 | return nil, err 304 | } 305 | return response, nil 306 | } 307 | 308 | /* 309 | PublishAttitude Publish to "attitude" updates. 310 | */ 311 | func (s *ServiceImpl) PublishAttitude( 312 | ctx context.Context, 313 | angle *EulerAngle, 314 | 315 | angularVelocity *AngularVelocityBody, 316 | 317 | ) (*PublishAttitudeResponse, error) { 318 | request := &PublishAttitudeRequest{ 319 | Angle: angle, 320 | 321 | AngularVelocity: angularVelocity, 322 | } 323 | response, err := s.Client.PublishAttitude(ctx, request) 324 | if err != nil { 325 | return nil, err 326 | } 327 | return response, nil 328 | } 329 | 330 | /* 331 | PublishVisualFlightRulesHud Publish to "Visual Flight Rules HUD" updates. 332 | */ 333 | func (s *ServiceImpl) PublishVisualFlightRulesHud( 334 | ctx context.Context, 335 | fixedWingMetrics *FixedwingMetrics, 336 | 337 | ) (*PublishVisualFlightRulesHudResponse, error) { 338 | request := &PublishVisualFlightRulesHudRequest{ 339 | FixedWingMetrics: fixedWingMetrics, 340 | } 341 | response, err := s.Client.PublishVisualFlightRulesHud(ctx, request) 342 | if err != nil { 343 | return nil, err 344 | } 345 | return response, nil 346 | } 347 | -------------------------------------------------------------------------------- /Sources/mission/mission.go: -------------------------------------------------------------------------------- 1 | package mission 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client MissionServiceClient 14 | } 15 | 16 | /* 17 | UploadMission Upload a list of mission items to the system. 18 | 19 | The mission items are uploaded to a drone. Once uploaded the mission can be started and 20 | executed even if the connection is lost. 21 | */ 22 | func (s *ServiceImpl) UploadMission( 23 | ctx context.Context, 24 | missionPlan *MissionPlan, 25 | 26 | ) (*UploadMissionResponse, error) { 27 | request := &UploadMissionRequest{ 28 | MissionPlan: missionPlan, 29 | } 30 | response, err := s.Client.UploadMission(ctx, request) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return response, nil 35 | } 36 | 37 | /* 38 | UploadMissionWithProgress Upload a list of mission items to the system and report upload progress. 39 | 40 | The mission items are uploaded to a drone. Once uploaded the mission can be started and 41 | executed even if the connection is lost. 42 | */ 43 | func (a *ServiceImpl) UploadMissionWithProgress( 44 | ctx context.Context, 45 | missionPlan *MissionPlan, 46 | 47 | ) (<-chan *ProgressData, error) { 48 | ch := make(chan *ProgressData) 49 | request := &SubscribeUploadMissionWithProgressRequest{ 50 | MissionPlan: missionPlan, 51 | } 52 | stream, err := a.Client.SubscribeUploadMissionWithProgress(ctx, request) 53 | if err != nil { 54 | return nil, err 55 | } 56 | go func() { 57 | defer close(ch) 58 | for { 59 | m := &UploadMissionWithProgressResponse{} 60 | err := stream.RecvMsg(m) 61 | if err == io.EOF { 62 | return 63 | } 64 | if err != nil { 65 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 66 | return 67 | } 68 | log.Fatalf("Unable to receive UploadMissionWithProgress messages, err: %v", err) 69 | } 70 | ch <- m.GetProgressData() 71 | } 72 | }() 73 | return ch, nil 74 | } 75 | 76 | /* 77 | CancelMissionUpload Cancel an ongoing mission upload. 78 | */ 79 | func (s *ServiceImpl) CancelMissionUpload( 80 | ctx context.Context, 81 | 82 | ) (*CancelMissionUploadResponse, error) { 83 | request := &CancelMissionUploadRequest{} 84 | response, err := s.Client.CancelMissionUpload(ctx, request) 85 | if err != nil { 86 | return nil, err 87 | } 88 | return response, nil 89 | } 90 | 91 | /* 92 | DownloadMission Download a list of mission items from the system (asynchronous). 93 | 94 | Will fail if any of the downloaded mission items are not supported 95 | by the MAVSDK API. 96 | */ 97 | func (s *ServiceImpl) DownloadMission( 98 | ctx context.Context, 99 | 100 | ) (*DownloadMissionResponse, error) { 101 | request := &DownloadMissionRequest{} 102 | response, err := s.Client.DownloadMission(ctx, request) 103 | if err != nil { 104 | return nil, err 105 | } 106 | return response, nil 107 | } 108 | 109 | /* 110 | DownloadMissionWithProgress Download a list of mission items from the system (asynchronous) and report progress. 111 | 112 | Will fail if any of the downloaded mission items are not supported 113 | by the MAVSDK API. 114 | */ 115 | func (a *ServiceImpl) DownloadMissionWithProgress( 116 | ctx context.Context, 117 | 118 | ) (<-chan *ProgressDataOrMission, error) { 119 | ch := make(chan *ProgressDataOrMission) 120 | request := &SubscribeDownloadMissionWithProgressRequest{} 121 | stream, err := a.Client.SubscribeDownloadMissionWithProgress(ctx, request) 122 | if err != nil { 123 | return nil, err 124 | } 125 | go func() { 126 | defer close(ch) 127 | for { 128 | m := &DownloadMissionWithProgressResponse{} 129 | err := stream.RecvMsg(m) 130 | if err == io.EOF { 131 | return 132 | } 133 | if err != nil { 134 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 135 | return 136 | } 137 | log.Fatalf("Unable to receive DownloadMissionWithProgress messages, err: %v", err) 138 | } 139 | ch <- m.GetProgressData() 140 | } 141 | }() 142 | return ch, nil 143 | } 144 | 145 | /* 146 | CancelMissionDownload Cancel an ongoing mission download. 147 | */ 148 | func (s *ServiceImpl) CancelMissionDownload( 149 | ctx context.Context, 150 | 151 | ) (*CancelMissionDownloadResponse, error) { 152 | request := &CancelMissionDownloadRequest{} 153 | response, err := s.Client.CancelMissionDownload(ctx, request) 154 | if err != nil { 155 | return nil, err 156 | } 157 | return response, nil 158 | } 159 | 160 | /* 161 | StartMission Start the mission. 162 | 163 | A mission must be uploaded to the vehicle before this can be called. 164 | */ 165 | func (s *ServiceImpl) StartMission( 166 | ctx context.Context, 167 | 168 | ) (*StartMissionResponse, error) { 169 | request := &StartMissionRequest{} 170 | response, err := s.Client.StartMission(ctx, request) 171 | if err != nil { 172 | return nil, err 173 | } 174 | return response, nil 175 | } 176 | 177 | /* 178 | PauseMission Pause the mission. 179 | 180 | Pausing the mission puts the vehicle into 181 | [HOLD mode](https://docs.px4.io/en/flight_modes/hold.html). 182 | A multicopter should just hover at the spot while a fixedwing vehicle should loiter 183 | around the location where it paused. 184 | */ 185 | func (s *ServiceImpl) PauseMission( 186 | ctx context.Context, 187 | 188 | ) (*PauseMissionResponse, error) { 189 | request := &PauseMissionRequest{} 190 | response, err := s.Client.PauseMission(ctx, request) 191 | if err != nil { 192 | return nil, err 193 | } 194 | return response, nil 195 | } 196 | 197 | /* 198 | ClearMission Clear the mission saved on the vehicle. 199 | */ 200 | func (s *ServiceImpl) ClearMission( 201 | ctx context.Context, 202 | 203 | ) (*ClearMissionResponse, error) { 204 | request := &ClearMissionRequest{} 205 | response, err := s.Client.ClearMission(ctx, request) 206 | if err != nil { 207 | return nil, err 208 | } 209 | return response, nil 210 | } 211 | 212 | /* 213 | SetCurrentMissionItem Sets the mission item index to go to. 214 | 215 | By setting the current index to 0, the mission is restarted from the beginning. If it is set 216 | to a specific index of a mission item, the mission will be set to this item. 217 | 218 | Note that this is not necessarily true for general missions using MAVLink if loop counters 219 | are used. 220 | */ 221 | func (s *ServiceImpl) SetCurrentMissionItem( 222 | ctx context.Context, 223 | index int32, 224 | 225 | ) (*SetCurrentMissionItemResponse, error) { 226 | request := &SetCurrentMissionItemRequest{ 227 | Index: index, 228 | } 229 | response, err := s.Client.SetCurrentMissionItem(ctx, request) 230 | if err != nil { 231 | return nil, err 232 | } 233 | return response, nil 234 | } 235 | 236 | /* 237 | IsMissionFinished Check if the mission has been finished. 238 | */ 239 | func (s *ServiceImpl) IsMissionFinished( 240 | ctx context.Context, 241 | 242 | ) (*IsMissionFinishedResponse, error) { 243 | request := &IsMissionFinishedRequest{} 244 | response, err := s.Client.IsMissionFinished(ctx, request) 245 | if err != nil { 246 | return nil, err 247 | } 248 | return response, nil 249 | } 250 | 251 | /* 252 | MissionProgress Subscribe to mission progress updates. 253 | */ 254 | func (a *ServiceImpl) MissionProgress( 255 | ctx context.Context, 256 | 257 | ) (<-chan *MissionProgress, error) { 258 | ch := make(chan *MissionProgress) 259 | request := &SubscribeMissionProgressRequest{} 260 | stream, err := a.Client.SubscribeMissionProgress(ctx, request) 261 | if err != nil { 262 | return nil, err 263 | } 264 | go func() { 265 | defer close(ch) 266 | for { 267 | m := &MissionProgressResponse{} 268 | err := stream.RecvMsg(m) 269 | if err == io.EOF { 270 | return 271 | } 272 | if err != nil { 273 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 274 | return 275 | } 276 | log.Fatalf("Unable to receive MissionProgress messages, err: %v", err) 277 | } 278 | ch <- m.GetMissionProgress() 279 | } 280 | }() 281 | return ch, nil 282 | } 283 | 284 | /* 285 | GetReturnToLaunchAfterMission Get whether to trigger Return-to-Launch (RTL) after mission is complete. 286 | 287 | Before getting this option, it needs to be set, or a mission 288 | needs to be downloaded. 289 | */ 290 | func (s *ServiceImpl) GetReturnToLaunchAfterMission( 291 | ctx context.Context, 292 | 293 | ) (*GetReturnToLaunchAfterMissionResponse, error) { 294 | request := &GetReturnToLaunchAfterMissionRequest{} 295 | response, err := s.Client.GetReturnToLaunchAfterMission(ctx, request) 296 | if err != nil { 297 | return nil, err 298 | } 299 | return response, nil 300 | } 301 | 302 | /* 303 | SetReturnToLaunchAfterMission Set whether to trigger Return-to-Launch (RTL) after the mission is complete. 304 | 305 | This will only take effect for the next mission upload, meaning that 306 | the mission may have to be uploaded again. 307 | */ 308 | func (s *ServiceImpl) SetReturnToLaunchAfterMission( 309 | ctx context.Context, 310 | enable bool, 311 | 312 | ) (*SetReturnToLaunchAfterMissionResponse, error) { 313 | request := &SetReturnToLaunchAfterMissionRequest{ 314 | Enable: enable, 315 | } 316 | response, err := s.Client.SetReturnToLaunchAfterMission(ctx, request) 317 | if err != nil { 318 | return nil, err 319 | } 320 | return response, nil 321 | } 322 | -------------------------------------------------------------------------------- /Sources/action_server/action_server.go: -------------------------------------------------------------------------------- 1 | package action_server 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client ActionServerServiceClient 14 | } 15 | 16 | /* 17 | ArmDisarm Subscribe to ARM/DISARM commands 18 | */ 19 | func (a *ServiceImpl) ArmDisarm( 20 | ctx context.Context, 21 | 22 | ) (<-chan *ArmDisarm, error) { 23 | ch := make(chan *ArmDisarm) 24 | request := &SubscribeArmDisarmRequest{} 25 | stream, err := a.Client.SubscribeArmDisarm(ctx, request) 26 | if err != nil { 27 | return nil, err 28 | } 29 | go func() { 30 | defer close(ch) 31 | for { 32 | m := &ArmDisarmResponse{} 33 | err := stream.RecvMsg(m) 34 | if err == io.EOF { 35 | return 36 | } 37 | if err != nil { 38 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 39 | return 40 | } 41 | log.Fatalf("Unable to receive ArmDisarm messages, err: %v", err) 42 | } 43 | ch <- m.GetArm() 44 | } 45 | }() 46 | return ch, nil 47 | } 48 | 49 | /* 50 | FlightModeChange Subscribe to DO_SET_MODE 51 | */ 52 | func (a *ServiceImpl) FlightModeChange( 53 | ctx context.Context, 54 | 55 | ) (<-chan FlightMode, error) { 56 | ch := make(chan FlightMode) 57 | request := &SubscribeFlightModeChangeRequest{} 58 | stream, err := a.Client.SubscribeFlightModeChange(ctx, request) 59 | if err != nil { 60 | return nil, err 61 | } 62 | go func() { 63 | defer close(ch) 64 | for { 65 | m := &FlightModeChangeResponse{} 66 | err := stream.RecvMsg(m) 67 | if err == io.EOF { 68 | return 69 | } 70 | if err != nil { 71 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 72 | return 73 | } 74 | log.Fatalf("Unable to receive FlightModeChange messages, err: %v", err) 75 | } 76 | ch <- m.GetFlightMode() 77 | } 78 | }() 79 | return ch, nil 80 | } 81 | 82 | /* 83 | Takeoff Subscribe to takeoff command 84 | */ 85 | func (a *ServiceImpl) Takeoff( 86 | ctx context.Context, 87 | 88 | ) (<-chan bool, error) { 89 | ch := make(chan bool) 90 | request := &SubscribeTakeoffRequest{} 91 | stream, err := a.Client.SubscribeTakeoff(ctx, request) 92 | if err != nil { 93 | return nil, err 94 | } 95 | go func() { 96 | defer close(ch) 97 | for { 98 | m := &TakeoffResponse{} 99 | err := stream.RecvMsg(m) 100 | if err == io.EOF { 101 | return 102 | } 103 | if err != nil { 104 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 105 | return 106 | } 107 | log.Fatalf("Unable to receive Takeoff messages, err: %v", err) 108 | } 109 | ch <- m.GetTakeoff() 110 | } 111 | }() 112 | return ch, nil 113 | } 114 | 115 | /* 116 | Land Subscribe to land command 117 | */ 118 | func (a *ServiceImpl) Land( 119 | ctx context.Context, 120 | 121 | ) (<-chan bool, error) { 122 | ch := make(chan bool) 123 | request := &SubscribeLandRequest{} 124 | stream, err := a.Client.SubscribeLand(ctx, request) 125 | if err != nil { 126 | return nil, err 127 | } 128 | go func() { 129 | defer close(ch) 130 | for { 131 | m := &LandResponse{} 132 | err := stream.RecvMsg(m) 133 | if err == io.EOF { 134 | return 135 | } 136 | if err != nil { 137 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 138 | return 139 | } 140 | log.Fatalf("Unable to receive Land messages, err: %v", err) 141 | } 142 | ch <- m.GetLand() 143 | } 144 | }() 145 | return ch, nil 146 | } 147 | 148 | /* 149 | Reboot Subscribe to reboot command 150 | */ 151 | func (a *ServiceImpl) Reboot( 152 | ctx context.Context, 153 | 154 | ) (<-chan bool, error) { 155 | ch := make(chan bool) 156 | request := &SubscribeRebootRequest{} 157 | stream, err := a.Client.SubscribeReboot(ctx, request) 158 | if err != nil { 159 | return nil, err 160 | } 161 | go func() { 162 | defer close(ch) 163 | for { 164 | m := &RebootResponse{} 165 | err := stream.RecvMsg(m) 166 | if err == io.EOF { 167 | return 168 | } 169 | if err != nil { 170 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 171 | return 172 | } 173 | log.Fatalf("Unable to receive Reboot messages, err: %v", err) 174 | } 175 | ch <- m.GetReboot() 176 | } 177 | }() 178 | return ch, nil 179 | } 180 | 181 | /* 182 | Shutdown Subscribe to shutdown command 183 | */ 184 | func (a *ServiceImpl) Shutdown( 185 | ctx context.Context, 186 | 187 | ) (<-chan bool, error) { 188 | ch := make(chan bool) 189 | request := &SubscribeShutdownRequest{} 190 | stream, err := a.Client.SubscribeShutdown(ctx, request) 191 | if err != nil { 192 | return nil, err 193 | } 194 | go func() { 195 | defer close(ch) 196 | for { 197 | m := &ShutdownResponse{} 198 | err := stream.RecvMsg(m) 199 | if err == io.EOF { 200 | return 201 | } 202 | if err != nil { 203 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 204 | return 205 | } 206 | log.Fatalf("Unable to receive Shutdown messages, err: %v", err) 207 | } 208 | ch <- m.GetShutdown() 209 | } 210 | }() 211 | return ch, nil 212 | } 213 | 214 | /* 215 | Terminate Subscribe to terminate command 216 | */ 217 | func (a *ServiceImpl) Terminate( 218 | ctx context.Context, 219 | 220 | ) (<-chan bool, error) { 221 | ch := make(chan bool) 222 | request := &SubscribeTerminateRequest{} 223 | stream, err := a.Client.SubscribeTerminate(ctx, request) 224 | if err != nil { 225 | return nil, err 226 | } 227 | go func() { 228 | defer close(ch) 229 | for { 230 | m := &TerminateResponse{} 231 | err := stream.RecvMsg(m) 232 | if err == io.EOF { 233 | return 234 | } 235 | if err != nil { 236 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 237 | return 238 | } 239 | log.Fatalf("Unable to receive Terminate messages, err: %v", err) 240 | } 241 | ch <- m.GetTerminate() 242 | } 243 | }() 244 | return ch, nil 245 | } 246 | 247 | /* 248 | SetAllowTakeoff Can the vehicle takeoff 249 | */ 250 | func (s *ServiceImpl) SetAllowTakeoff( 251 | ctx context.Context, 252 | allowTakeoff bool, 253 | 254 | ) (*SetAllowTakeoffResponse, error) { 255 | request := &SetAllowTakeoffRequest{ 256 | AllowTakeoff: allowTakeoff, 257 | } 258 | response, err := s.Client.SetAllowTakeoff(ctx, request) 259 | if err != nil { 260 | return nil, err 261 | } 262 | return response, nil 263 | } 264 | 265 | /* 266 | SetArmable Can the vehicle arm when requested 267 | */ 268 | func (s *ServiceImpl) SetArmable( 269 | ctx context.Context, 270 | armable bool, 271 | forceArmable bool, 272 | 273 | ) (*SetArmableResponse, error) { 274 | request := &SetArmableRequest{ 275 | Armable: armable, 276 | ForceArmable: forceArmable, 277 | } 278 | response, err := s.Client.SetArmable(ctx, request) 279 | if err != nil { 280 | return nil, err 281 | } 282 | return response, nil 283 | } 284 | 285 | /* 286 | SetDisarmable Can the vehicle disarm when requested 287 | */ 288 | func (s *ServiceImpl) SetDisarmable( 289 | ctx context.Context, 290 | disarmable bool, 291 | forceDisarmable bool, 292 | 293 | ) (*SetDisarmableResponse, error) { 294 | request := &SetDisarmableRequest{ 295 | Disarmable: disarmable, 296 | ForceDisarmable: forceDisarmable, 297 | } 298 | response, err := s.Client.SetDisarmable(ctx, request) 299 | if err != nil { 300 | return nil, err 301 | } 302 | return response, nil 303 | } 304 | 305 | /* 306 | SetAllowableFlightModes Set which modes the vehicle can transition to (Manual always allowed) 307 | */ 308 | func (s *ServiceImpl) SetAllowableFlightModes( 309 | ctx context.Context, 310 | flightModes *AllowableFlightModes, 311 | 312 | ) (*SetAllowableFlightModesResponse, error) { 313 | request := &SetAllowableFlightModesRequest{ 314 | FlightModes: flightModes, 315 | } 316 | response, err := s.Client.SetAllowableFlightModes(ctx, request) 317 | if err != nil { 318 | return nil, err 319 | } 320 | return response, nil 321 | } 322 | 323 | /* 324 | GetAllowableFlightModes Get which modes the vehicle can transition to (Manual always allowed) 325 | */ 326 | func (s *ServiceImpl) GetAllowableFlightModes( 327 | ctx context.Context, 328 | 329 | ) (*GetAllowableFlightModesResponse, error) { 330 | request := &GetAllowableFlightModesRequest{} 331 | response, err := s.Client.GetAllowableFlightModes(ctx, request) 332 | if err != nil { 333 | return nil, err 334 | } 335 | return response, nil 336 | } 337 | 338 | /* 339 | SetArmedState Set/override the armed/disarmed state of the vehicle directly, and notify subscribers 340 | */ 341 | func (s *ServiceImpl) SetArmedState( 342 | ctx context.Context, 343 | isArmed bool, 344 | 345 | ) (*SetArmedStateResponse, error) { 346 | request := &SetArmedStateRequest{ 347 | IsArmed: isArmed, 348 | } 349 | response, err := s.Client.SetArmedState(ctx, request) 350 | if err != nil { 351 | return nil, err 352 | } 353 | return response, nil 354 | } 355 | 356 | /* 357 | SetFlightMode Set/override the flight mode of the vehicle directly, and notify subscribers 358 | */ 359 | func (s *ServiceImpl) SetFlightMode( 360 | ctx context.Context, 361 | flightMode *FlightMode, 362 | 363 | ) (*SetFlightModeResponse, error) { 364 | request := &SetFlightModeRequest{ 365 | FlightMode: *flightMode, 366 | } 367 | response, err := s.Client.SetFlightMode(ctx, request) 368 | if err != nil { 369 | return nil, err 370 | } 371 | return response, nil 372 | } 373 | -------------------------------------------------------------------------------- /Sources/mission_raw/mission_raw.go: -------------------------------------------------------------------------------- 1 | package mission_raw 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "log" 7 | 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | type ServiceImpl struct { 13 | Client MissionRawServiceClient 14 | } 15 | 16 | /* 17 | UploadMission Upload a list of raw mission items to the system. 18 | 19 | The raw mission items are uploaded to a drone. Once uploaded the mission 20 | can be started and executed even if the connection is lost. 21 | */ 22 | func (s *ServiceImpl) UploadMission( 23 | ctx context.Context, 24 | missionItems []*MissionItem, 25 | 26 | ) (*UploadMissionResponse, error) { 27 | request := &UploadMissionRequest{ 28 | MissionItems: missionItems, 29 | } 30 | response, err := s.Client.UploadMission(ctx, request) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return response, nil 35 | } 36 | 37 | /* 38 | UploadGeofence Upload a list of geofence items to the system. 39 | */ 40 | func (s *ServiceImpl) UploadGeofence( 41 | ctx context.Context, 42 | missionItems []*MissionItem, 43 | 44 | ) (*UploadGeofenceResponse, error) { 45 | request := &UploadGeofenceRequest{ 46 | MissionItems: missionItems, 47 | } 48 | response, err := s.Client.UploadGeofence(ctx, request) 49 | if err != nil { 50 | return nil, err 51 | } 52 | return response, nil 53 | } 54 | 55 | /* 56 | UploadRallyPoints Upload a list of rally point items to the system. 57 | */ 58 | func (s *ServiceImpl) UploadRallyPoints( 59 | ctx context.Context, 60 | missionItems []*MissionItem, 61 | 62 | ) (*UploadRallyPointsResponse, error) { 63 | request := &UploadRallyPointsRequest{ 64 | MissionItems: missionItems, 65 | } 66 | response, err := s.Client.UploadRallyPoints(ctx, request) 67 | if err != nil { 68 | return nil, err 69 | } 70 | return response, nil 71 | } 72 | 73 | /* 74 | CancelMissionUpload Cancel an ongoing mission upload. 75 | */ 76 | func (s *ServiceImpl) CancelMissionUpload( 77 | ctx context.Context, 78 | 79 | ) (*CancelMissionUploadResponse, error) { 80 | request := &CancelMissionUploadRequest{} 81 | response, err := s.Client.CancelMissionUpload(ctx, request) 82 | if err != nil { 83 | return nil, err 84 | } 85 | return response, nil 86 | } 87 | 88 | /* 89 | DownloadMission Download a list of raw mission items from the system (asynchronous). 90 | */ 91 | func (s *ServiceImpl) DownloadMission( 92 | ctx context.Context, 93 | 94 | ) (*DownloadMissionResponse, error) { 95 | request := &DownloadMissionRequest{} 96 | response, err := s.Client.DownloadMission(ctx, request) 97 | if err != nil { 98 | return nil, err 99 | } 100 | return response, nil 101 | } 102 | 103 | /* 104 | DownloadGeofence Download a list of raw geofence items from the system (asynchronous). 105 | */ 106 | func (s *ServiceImpl) DownloadGeofence( 107 | ctx context.Context, 108 | 109 | ) (*DownloadGeofenceResponse, error) { 110 | request := &DownloadGeofenceRequest{} 111 | response, err := s.Client.DownloadGeofence(ctx, request) 112 | if err != nil { 113 | return nil, err 114 | } 115 | return response, nil 116 | } 117 | 118 | /* 119 | DownloadRallypoints Download a list of raw rallypoint items from the system (asynchronous). 120 | */ 121 | func (s *ServiceImpl) DownloadRallypoints( 122 | ctx context.Context, 123 | 124 | ) (*DownloadRallypointsResponse, error) { 125 | request := &DownloadRallypointsRequest{} 126 | response, err := s.Client.DownloadRallypoints(ctx, request) 127 | if err != nil { 128 | return nil, err 129 | } 130 | return response, nil 131 | } 132 | 133 | /* 134 | CancelMissionDownload Cancel an ongoing mission download. 135 | */ 136 | func (s *ServiceImpl) CancelMissionDownload( 137 | ctx context.Context, 138 | 139 | ) (*CancelMissionDownloadResponse, error) { 140 | request := &CancelMissionDownloadRequest{} 141 | response, err := s.Client.CancelMissionDownload(ctx, request) 142 | if err != nil { 143 | return nil, err 144 | } 145 | return response, nil 146 | } 147 | 148 | /* 149 | StartMission Start the mission. 150 | 151 | A mission must be uploaded to the vehicle before this can be called. 152 | */ 153 | func (s *ServiceImpl) StartMission( 154 | ctx context.Context, 155 | 156 | ) (*StartMissionResponse, error) { 157 | request := &StartMissionRequest{} 158 | response, err := s.Client.StartMission(ctx, request) 159 | if err != nil { 160 | return nil, err 161 | } 162 | return response, nil 163 | } 164 | 165 | /* 166 | PauseMission Pause the mission. 167 | 168 | Pausing the mission puts the vehicle into 169 | [HOLD mode](https://docs.px4.io/en/flight_modes/hold.html). 170 | A multicopter should just hover at the spot while a fixedwing vehicle should loiter 171 | around the location where it paused. 172 | */ 173 | func (s *ServiceImpl) PauseMission( 174 | ctx context.Context, 175 | 176 | ) (*PauseMissionResponse, error) { 177 | request := &PauseMissionRequest{} 178 | response, err := s.Client.PauseMission(ctx, request) 179 | if err != nil { 180 | return nil, err 181 | } 182 | return response, nil 183 | } 184 | 185 | /* 186 | ClearMission Clear the mission saved on the vehicle. 187 | */ 188 | func (s *ServiceImpl) ClearMission( 189 | ctx context.Context, 190 | 191 | ) (*ClearMissionResponse, error) { 192 | request := &ClearMissionRequest{} 193 | response, err := s.Client.ClearMission(ctx, request) 194 | if err != nil { 195 | return nil, err 196 | } 197 | return response, nil 198 | } 199 | 200 | /* 201 | SetCurrentMissionItem Sets the raw mission item index to go to. 202 | 203 | By setting the current index to 0, the mission is restarted from the beginning. If it is set 204 | to a specific index of a raw mission item, the mission will be set to this item. 205 | */ 206 | func (s *ServiceImpl) SetCurrentMissionItem( 207 | ctx context.Context, 208 | index int32, 209 | 210 | ) (*SetCurrentMissionItemResponse, error) { 211 | request := &SetCurrentMissionItemRequest{ 212 | Index: index, 213 | } 214 | response, err := s.Client.SetCurrentMissionItem(ctx, request) 215 | if err != nil { 216 | return nil, err 217 | } 218 | return response, nil 219 | } 220 | 221 | /* 222 | MissionProgress Subscribe to mission progress updates. 223 | */ 224 | func (a *ServiceImpl) MissionProgress( 225 | ctx context.Context, 226 | 227 | ) (<-chan *MissionProgress, error) { 228 | ch := make(chan *MissionProgress) 229 | request := &SubscribeMissionProgressRequest{} 230 | stream, err := a.Client.SubscribeMissionProgress(ctx, request) 231 | if err != nil { 232 | return nil, err 233 | } 234 | go func() { 235 | defer close(ch) 236 | for { 237 | m := &MissionProgressResponse{} 238 | err := stream.RecvMsg(m) 239 | if err == io.EOF { 240 | return 241 | } 242 | if err != nil { 243 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 244 | return 245 | } 246 | log.Fatalf("Unable to receive MissionProgress messages, err: %v", err) 247 | } 248 | ch <- m.GetMissionProgress() 249 | } 250 | }() 251 | return ch, nil 252 | } 253 | 254 | /* 255 | MissionChanged Subscribes to mission changed. 256 | 257 | This notification can be used to be informed if a ground station has 258 | been uploaded or changed by a ground station or companion computer. 259 | 260 | @param callback Callback to notify about change. 261 | */ 262 | func (a *ServiceImpl) MissionChanged( 263 | ctx context.Context, 264 | 265 | ) (<-chan bool, error) { 266 | ch := make(chan bool) 267 | request := &SubscribeMissionChangedRequest{} 268 | stream, err := a.Client.SubscribeMissionChanged(ctx, request) 269 | if err != nil { 270 | return nil, err 271 | } 272 | go func() { 273 | defer close(ch) 274 | for { 275 | m := &MissionChangedResponse{} 276 | err := stream.RecvMsg(m) 277 | if err == io.EOF { 278 | return 279 | } 280 | if err != nil { 281 | if s, ok := status.FromError(err); ok && (s.Code() == codes.Canceled || s.Code() == codes.Unimplemented) { 282 | return 283 | } 284 | log.Fatalf("Unable to receive MissionChanged messages, err: %v", err) 285 | } 286 | ch <- m.GetMissionChanged() 287 | } 288 | }() 289 | return ch, nil 290 | } 291 | 292 | /* 293 | ImportQgroundcontrolMission Import a QGroundControl missions in JSON .plan format, from a file. 294 | 295 | Supported: 296 | - Waypoints 297 | - Survey 298 | Not supported: 299 | - Structure Scan 300 | */ 301 | func (s *ServiceImpl) ImportQgroundcontrolMission( 302 | ctx context.Context, 303 | qgcPlanPath string, 304 | 305 | ) (*ImportQgroundcontrolMissionResponse, error) { 306 | request := &ImportQgroundcontrolMissionRequest{ 307 | QgcPlanPath: qgcPlanPath, 308 | } 309 | response, err := s.Client.ImportQgroundcontrolMission(ctx, request) 310 | if err != nil { 311 | return nil, err 312 | } 313 | return response, nil 314 | } 315 | 316 | /* 317 | ImportQgroundcontrolMissionFromString Import a QGroundControl missions in JSON .plan format, from a string. 318 | 319 | Supported: 320 | - Waypoints 321 | - Survey 322 | Not supported: 323 | - Structure Scan 324 | */ 325 | func (s *ServiceImpl) ImportQgroundcontrolMissionFromString( 326 | ctx context.Context, 327 | qgcPlan string, 328 | 329 | ) (*ImportQgroundcontrolMissionFromStringResponse, error) { 330 | request := &ImportQgroundcontrolMissionFromStringRequest{ 331 | QgcPlan: qgcPlan, 332 | } 333 | response, err := s.Client.ImportQgroundcontrolMissionFromString(ctx, request) 334 | if err != nil { 335 | return nil, err 336 | } 337 | return response, nil 338 | } 339 | 340 | /* 341 | IsMissionFinished Check if the mission is finished. 342 | 343 | Returns true if the mission is finished, false otherwise. 344 | */ 345 | func (s *ServiceImpl) IsMissionFinished( 346 | ctx context.Context, 347 | 348 | ) (*IsMissionFinishedResponse, error) { 349 | request := &IsMissionFinishedRequest{} 350 | response, err := s.Client.IsMissionFinished(ctx, request) 351 | if err != nil { 352 | return nil, err 353 | } 354 | return response, nil 355 | } 356 | -------------------------------------------------------------------------------- /Sources/log_files/log_files_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.5.1 4 | // - protoc v3.12.4 5 | // source: log_files.proto 6 | 7 | package log_files 8 | 9 | import ( 10 | context "context" 11 | 12 | grpc "google.golang.org/grpc" 13 | codes "google.golang.org/grpc/codes" 14 | status "google.golang.org/grpc/status" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.64.0 or later. 20 | const _ = grpc.SupportPackageIsVersion9 21 | 22 | const ( 23 | LogFilesService_GetEntries_FullMethodName = "/mavsdk.rpc.log_files.LogFilesService/GetEntries" 24 | LogFilesService_SubscribeDownloadLogFile_FullMethodName = "/mavsdk.rpc.log_files.LogFilesService/SubscribeDownloadLogFile" 25 | LogFilesService_EraseAllLogFiles_FullMethodName = "/mavsdk.rpc.log_files.LogFilesService/EraseAllLogFiles" 26 | ) 27 | 28 | // LogFilesServiceClient is the client API for LogFilesService service. 29 | // 30 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 31 | // 32 | // Allow to download log files from the vehicle after a flight is complete. 33 | // For log streaming during flight check the logging plugin. 34 | type LogFilesServiceClient interface { 35 | // Get List of log files. 36 | GetEntries(ctx context.Context, in *GetEntriesRequest, opts ...grpc.CallOption) (*GetEntriesResponse, error) 37 | // Download log file. 38 | SubscribeDownloadLogFile(ctx context.Context, in *SubscribeDownloadLogFileRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[DownloadLogFileResponse], error) 39 | // Erase all log files. 40 | EraseAllLogFiles(ctx context.Context, in *EraseAllLogFilesRequest, opts ...grpc.CallOption) (*EraseAllLogFilesResponse, error) 41 | } 42 | 43 | type logFilesServiceClient struct { 44 | cc grpc.ClientConnInterface 45 | } 46 | 47 | func NewLogFilesServiceClient(cc grpc.ClientConnInterface) LogFilesServiceClient { 48 | return &logFilesServiceClient{cc} 49 | } 50 | 51 | func (c *logFilesServiceClient) GetEntries(ctx context.Context, in *GetEntriesRequest, opts ...grpc.CallOption) (*GetEntriesResponse, error) { 52 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 53 | out := new(GetEntriesResponse) 54 | err := c.cc.Invoke(ctx, LogFilesService_GetEntries_FullMethodName, in, out, cOpts...) 55 | if err != nil { 56 | return nil, err 57 | } 58 | return out, nil 59 | } 60 | 61 | func (c *logFilesServiceClient) SubscribeDownloadLogFile(ctx context.Context, in *SubscribeDownloadLogFileRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[DownloadLogFileResponse], error) { 62 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 63 | stream, err := c.cc.NewStream(ctx, &LogFilesService_ServiceDesc.Streams[0], LogFilesService_SubscribeDownloadLogFile_FullMethodName, cOpts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | x := &grpc.GenericClientStream[SubscribeDownloadLogFileRequest, DownloadLogFileResponse]{ClientStream: stream} 68 | if err := x.ClientStream.SendMsg(in); err != nil { 69 | return nil, err 70 | } 71 | if err := x.ClientStream.CloseSend(); err != nil { 72 | return nil, err 73 | } 74 | return x, nil 75 | } 76 | 77 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 78 | type LogFilesService_SubscribeDownloadLogFileClient = grpc.ServerStreamingClient[DownloadLogFileResponse] 79 | 80 | func (c *logFilesServiceClient) EraseAllLogFiles(ctx context.Context, in *EraseAllLogFilesRequest, opts ...grpc.CallOption) (*EraseAllLogFilesResponse, error) { 81 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 82 | out := new(EraseAllLogFilesResponse) 83 | err := c.cc.Invoke(ctx, LogFilesService_EraseAllLogFiles_FullMethodName, in, out, cOpts...) 84 | if err != nil { 85 | return nil, err 86 | } 87 | return out, nil 88 | } 89 | 90 | // LogFilesServiceServer is the server API for LogFilesService service. 91 | // All implementations must embed UnimplementedLogFilesServiceServer 92 | // for forward compatibility. 93 | // 94 | // Allow to download log files from the vehicle after a flight is complete. 95 | // For log streaming during flight check the logging plugin. 96 | type LogFilesServiceServer interface { 97 | // Get List of log files. 98 | GetEntries(context.Context, *GetEntriesRequest) (*GetEntriesResponse, error) 99 | // Download log file. 100 | SubscribeDownloadLogFile(*SubscribeDownloadLogFileRequest, grpc.ServerStreamingServer[DownloadLogFileResponse]) error 101 | // Erase all log files. 102 | EraseAllLogFiles(context.Context, *EraseAllLogFilesRequest) (*EraseAllLogFilesResponse, error) 103 | mustEmbedUnimplementedLogFilesServiceServer() 104 | } 105 | 106 | // UnimplementedLogFilesServiceServer must be embedded to have 107 | // forward compatible implementations. 108 | // 109 | // NOTE: this should be embedded by value instead of pointer to avoid a nil 110 | // pointer dereference when methods are called. 111 | type UnimplementedLogFilesServiceServer struct{} 112 | 113 | func (UnimplementedLogFilesServiceServer) GetEntries(context.Context, *GetEntriesRequest) (*GetEntriesResponse, error) { 114 | return nil, status.Errorf(codes.Unimplemented, "method GetEntries not implemented") 115 | } 116 | func (UnimplementedLogFilesServiceServer) SubscribeDownloadLogFile(*SubscribeDownloadLogFileRequest, grpc.ServerStreamingServer[DownloadLogFileResponse]) error { 117 | return status.Errorf(codes.Unimplemented, "method SubscribeDownloadLogFile not implemented") 118 | } 119 | func (UnimplementedLogFilesServiceServer) EraseAllLogFiles(context.Context, *EraseAllLogFilesRequest) (*EraseAllLogFilesResponse, error) { 120 | return nil, status.Errorf(codes.Unimplemented, "method EraseAllLogFiles not implemented") 121 | } 122 | func (UnimplementedLogFilesServiceServer) mustEmbedUnimplementedLogFilesServiceServer() {} 123 | func (UnimplementedLogFilesServiceServer) testEmbeddedByValue() {} 124 | 125 | // UnsafeLogFilesServiceServer may be embedded to opt out of forward compatibility for this service. 126 | // Use of this interface is not recommended, as added methods to LogFilesServiceServer will 127 | // result in compilation errors. 128 | type UnsafeLogFilesServiceServer interface { 129 | mustEmbedUnimplementedLogFilesServiceServer() 130 | } 131 | 132 | func RegisterLogFilesServiceServer(s grpc.ServiceRegistrar, srv LogFilesServiceServer) { 133 | // If the following call pancis, it indicates UnimplementedLogFilesServiceServer was 134 | // embedded by pointer and is nil. This will cause panics if an 135 | // unimplemented method is ever invoked, so we test this at initialization 136 | // time to prevent it from happening at runtime later due to I/O. 137 | if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { 138 | t.testEmbeddedByValue() 139 | } 140 | s.RegisterService(&LogFilesService_ServiceDesc, srv) 141 | } 142 | 143 | func _LogFilesService_GetEntries_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 144 | in := new(GetEntriesRequest) 145 | if err := dec(in); err != nil { 146 | return nil, err 147 | } 148 | if interceptor == nil { 149 | return srv.(LogFilesServiceServer).GetEntries(ctx, in) 150 | } 151 | info := &grpc.UnaryServerInfo{ 152 | Server: srv, 153 | FullMethod: LogFilesService_GetEntries_FullMethodName, 154 | } 155 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 156 | return srv.(LogFilesServiceServer).GetEntries(ctx, req.(*GetEntriesRequest)) 157 | } 158 | return interceptor(ctx, in, info, handler) 159 | } 160 | 161 | func _LogFilesService_SubscribeDownloadLogFile_Handler(srv interface{}, stream grpc.ServerStream) error { 162 | m := new(SubscribeDownloadLogFileRequest) 163 | if err := stream.RecvMsg(m); err != nil { 164 | return err 165 | } 166 | return srv.(LogFilesServiceServer).SubscribeDownloadLogFile(m, &grpc.GenericServerStream[SubscribeDownloadLogFileRequest, DownloadLogFileResponse]{ServerStream: stream}) 167 | } 168 | 169 | // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. 170 | type LogFilesService_SubscribeDownloadLogFileServer = grpc.ServerStreamingServer[DownloadLogFileResponse] 171 | 172 | func _LogFilesService_EraseAllLogFiles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 173 | in := new(EraseAllLogFilesRequest) 174 | if err := dec(in); err != nil { 175 | return nil, err 176 | } 177 | if interceptor == nil { 178 | return srv.(LogFilesServiceServer).EraseAllLogFiles(ctx, in) 179 | } 180 | info := &grpc.UnaryServerInfo{ 181 | Server: srv, 182 | FullMethod: LogFilesService_EraseAllLogFiles_FullMethodName, 183 | } 184 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 185 | return srv.(LogFilesServiceServer).EraseAllLogFiles(ctx, req.(*EraseAllLogFilesRequest)) 186 | } 187 | return interceptor(ctx, in, info, handler) 188 | } 189 | 190 | // LogFilesService_ServiceDesc is the grpc.ServiceDesc for LogFilesService service. 191 | // It's only intended for direct use with grpc.RegisterService, 192 | // and not to be introspected or modified (even as a copy) 193 | var LogFilesService_ServiceDesc = grpc.ServiceDesc{ 194 | ServiceName: "mavsdk.rpc.log_files.LogFilesService", 195 | HandlerType: (*LogFilesServiceServer)(nil), 196 | Methods: []grpc.MethodDesc{ 197 | { 198 | MethodName: "GetEntries", 199 | Handler: _LogFilesService_GetEntries_Handler, 200 | }, 201 | { 202 | MethodName: "EraseAllLogFiles", 203 | Handler: _LogFilesService_EraseAllLogFiles_Handler, 204 | }, 205 | }, 206 | Streams: []grpc.StreamDesc{ 207 | { 208 | StreamName: "SubscribeDownloadLogFile", 209 | Handler: _LogFilesService_SubscribeDownloadLogFile_Handler, 210 | ServerStreams: true, 211 | }, 212 | }, 213 | Metadata: "log_files.proto", 214 | } 215 | --------------------------------------------------------------------------------