// Code generated by protoc-gen-go. DO NOT EDIT.
// source: lab/servo.proto

package lab

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// Servo Setup Type describes the capabilities of servos.
// Next Tag : 3
type ServoSetupType int32

const (
	ServoSetupType_SERVO_SETUP_REGULAR ServoSetupType = 0
	ServoSetupType_SERVO_SETUP_DUAL_V4 ServoSetupType = 1
	// SERVO_SETUP_INVALID explicitly marks errors in servo setup.
	ServoSetupType_SERVO_SETUP_INVALID ServoSetupType = 2
)

var ServoSetupType_name = map[int32]string{
	0: "SERVO_SETUP_REGULAR",
	1: "SERVO_SETUP_DUAL_V4",
	2: "SERVO_SETUP_INVALID",
}

var ServoSetupType_value = map[string]int32{
	"SERVO_SETUP_REGULAR": 0,
	"SERVO_SETUP_DUAL_V4": 1,
	"SERVO_SETUP_INVALID": 2,
}

func (x ServoSetupType) String() string {
	return proto.EnumName(ServoSetupType_name, int32(x))
}

func (ServoSetupType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_34a04ba68a815039, []int{0}
}

// NEXT TAG: 8
type Servo struct {
	// Servo-specific configs
	ServoHostname string `protobuf:"bytes,2,opt,name=servo_hostname,json=servoHostname,proto3" json:"servo_hostname,omitempty"`
	ServoPort     int32  `protobuf:"varint,3,opt,name=servo_port,json=servoPort,proto3" json:"servo_port,omitempty"`
	ServoSerial   string `protobuf:"bytes,4,opt,name=servo_serial,json=servoSerial,proto3" json:"servo_serial,omitempty"`
	// Based on https://docs.google.com/document/d/1TPp7yp-uwFUh5xOnBLI4jPYtYD7IcdyQ1dgqFqtcJEU/edit?ts=5d8eafb7#heading=h.csdfk1i6g0l
	// servo_type will contain different setup of servos. So string is recommended than enum.
	ServoType            string         `protobuf:"bytes,5,opt,name=servo_type,json=servoType,proto3" json:"servo_type,omitempty"`
	ServoSetup           ServoSetupType `protobuf:"varint,7,opt,name=servo_setup,json=servoSetup,proto3,enum=lab.ServoSetupType" json:"servo_setup,omitempty"`
	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
	XXX_unrecognized     []byte         `json:"-"`
	XXX_sizecache        int32          `json:"-"`
}

func (m *Servo) Reset()         { *m = Servo{} }
func (m *Servo) String() string { return proto.CompactTextString(m) }
func (*Servo) ProtoMessage()    {}
func (*Servo) Descriptor() ([]byte, []int) {
	return fileDescriptor_34a04ba68a815039, []int{0}
}

func (m *Servo) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Servo.Unmarshal(m, b)
}
func (m *Servo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Servo.Marshal(b, m, deterministic)
}
func (m *Servo) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Servo.Merge(m, src)
}
func (m *Servo) XXX_Size() int {
	return xxx_messageInfo_Servo.Size(m)
}
func (m *Servo) XXX_DiscardUnknown() {
	xxx_messageInfo_Servo.DiscardUnknown(m)
}

var xxx_messageInfo_Servo proto.InternalMessageInfo

func (m *Servo) GetServoHostname() string {
	if m != nil {
		return m.ServoHostname
	}
	return ""
}

func (m *Servo) GetServoPort() int32 {
	if m != nil {
		return m.ServoPort
	}
	return 0
}

func (m *Servo) GetServoSerial() string {
	if m != nil {
		return m.ServoSerial
	}
	return ""
}

func (m *Servo) GetServoType() string {
	if m != nil {
		return m.ServoType
	}
	return ""
}

func (m *Servo) GetServoSetup() ServoSetupType {
	if m != nil {
		return m.ServoSetup
	}
	return ServoSetupType_SERVO_SETUP_REGULAR
}

func init() {
	proto.RegisterEnum("lab.ServoSetupType", ServoSetupType_name, ServoSetupType_value)
	proto.RegisterType((*Servo)(nil), "lab.Servo")
}

func init() { proto.RegisterFile("lab/servo.proto", fileDescriptor_34a04ba68a815039) }

var fileDescriptor_34a04ba68a815039 = []byte{
	// 278 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xc1, 0x4a, 0xf3, 0x40,
	0x14, 0x46, 0xff, 0xb4, 0x4d, 0xfb, 0x77, 0xaa, 0x31, 0x4c, 0x17, 0x66, 0x23, 0x44, 0x41, 0x08,
	0x82, 0x19, 0xd0, 0xbe, 0x40, 0xa4, 0x41, 0x2b, 0x41, 0xcb, 0xa4, 0xc9, 0x42, 0x17, 0x61, 0x22,
	0x31, 0x0d, 0x24, 0xbd, 0xc3, 0xcc, 0x44, 0xe8, 0x33, 0xfa, 0x52, 0xd2, 0x89, 0x55, 0xec, 0xf2,
	0x9e, 0xef, 0x70, 0x16, 0x17, 0x9d, 0xd4, 0x2c, 0x27, 0xb2, 0x10, 0x1f, 0xe0, 0x73, 0x01, 0x0a,
	0x70, 0xbf, 0x66, 0xf9, 0xc5, 0xa7, 0x81, 0xcc, 0x78, 0x07, 0xf1, 0x25, 0xb2, 0xf4, 0x9a, 0xad,
	0x41, 0xaa, 0x0d, 0x6b, 0x0a, 0xa7, 0xe7, 0x1a, 0xde, 0x98, 0x1e, 0x6b, 0xfa, 0xf0, 0x0d, 0xf1,
	0x19, 0x42, 0x9d, 0xc6, 0x41, 0x28, 0xa7, 0xef, 0x1a, 0x9e, 0x49, 0xc7, 0x9a, 0x2c, 0x41, 0x28,
	0x7c, 0x8e, 0x8e, 0xba, 0x59, 0x16, 0xa2, 0x62, 0xb5, 0x33, 0xd0, 0x8d, 0x89, 0x66, 0xb1, 0x46,
	0xbf, 0x05, 0xb5, 0xe5, 0x85, 0x63, 0x6a, 0xa1, 0x2b, 0xac, 0xb6, 0xbc, 0xc0, 0x33, 0x34, 0xd9,
	0x17, 0x54, 0xcb, 0x9d, 0x91, 0x6b, 0x78, 0xd6, 0xcd, 0xd4, 0xaf, 0x59, 0xee, 0xc7, 0x5d, 0x45,
	0xb5, 0x7c, 0x67, 0x52, 0x24, 0x7f, 0xee, 0xc7, 0xc1, 0xff, 0xa1, 0x3d, 0xba, 0x7a, 0x45, 0xd6,
	0x5f, 0x07, 0x9f, 0xa2, 0x69, 0x1c, 0xd2, 0xf4, 0x39, 0x8b, 0xc3, 0x55, 0xb2, 0xcc, 0x68, 0x78,
	0x9f, 0x44, 0x01, 0xb5, 0xff, 0x1d, 0x0e, 0xf3, 0x24, 0x88, 0xb2, 0x74, 0x66, 0x1b, 0x87, 0xc3,
	0xe2, 0x29, 0x0d, 0xa2, 0xc5, 0xdc, 0xee, 0xdd, 0x91, 0x97, 0xeb, 0x12, 0xfc, 0xb7, 0xb5, 0x80,
	0xa6, 0x6a, 0x1b, 0x1f, 0x44, 0x49, 0xf6, 0x07, 0x48, 0x52, 0x6d, 0xde, 0x05, 0x23, 0xfa, 0xb3,
	0xa4, 0x04, 0x52, 0xb3, 0x3c, 0x1f, 0xea, 0xeb, 0xf6, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x28, 0x4e,
	0x1f, 0x9e, 0x7a, 0x01, 0x00, 0x00,
}
