Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Golang, make and robotics #gocon

1,516 views

Published on

Go Conference 2015 summerでの発表内容です。
gRPC(Protocol Buffers)とGoとAVRを使ったロボットの制御を行っています。

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Golang, make and robotics #gocon

  1. 1. Goと電子工作とロボット たけいひでゆき @HideyukiTakei Jun. 21, 2015 / Go Conference
  2. 2. 自己紹介 • H/W: 回路設計、マイコン、外装設計、中国 • SW: フロントエンドJS、Android、AWS • かわいいロボットが好き
  3. 3. 自己紹介
  4. 4. アジェンダ • いま趣味で作っているロボットのご紹介 • Goでメジャーな電子工作のツールGobot • Arduino と Firmata • 意外と面倒なシリアル通信でのデータやりとり • RPCの必要性とgRPC • 動くデモ! • コードの説明
  5. 5. 趣味のロボットづくり • 盆栽ロボットを作りたい • 亀+植物 • かわいく動かしたい • ゆくゆくは野に放ちたい • 野良ロボット
  6. 6. ServoMotor RS304MD Front-Right ServoMotor RS304MD Front-Left ServoMotor RS304MD Back-Right ServoMotor RS304MD Back-Left ServoMotor RS304MD Yaw ServoMotor RS304MD Tail USART Eye LED * 2Solar Cell I2C AVR ATXMEGA32D4 PWM Pressure Sensor Temperature & Humidity Sensor 9 Axis Sensors (3Acc, 3Gyro, GPS LS20031 3.0-4.2V Energy Harvesting 構成 USART
  7. 7. だいたい試作はできた
  8. 8. • eagle: プリント基板設計ソフトウェア • elecrow, fusion pcb: プリント基板製造サービス • Inventor: 3DCAD • Shapeways: 3Dプリントサービス • AVR & GCC: 8bitマイコン(C言語で開発) 試作でよく使うもの
  9. 9. • ロボットを外部からコントロールしたい • せっかくなのでGoを使おう なにで制御しよう
  10. 10. Goで電子回路の定番?
  11. 11. いろいろ対応
  12. 12. Gobot & RaspberryPi Goのコード with Gobot Raspbian GPIO, I2C • RaspberryPi上でGoのコードが動く • 直接GPIOやI2Cを叩くことができる!
  13. 13. Gobot & Arduino Goのコード with Gobot Firmata USB-Serial • PCからArduinoを操作する • Arduino上にプログラムを転送しない
  14. 14. ArudinoとFirmata 都度ファームウェアを USB経由で書き込む • Arduinoの場合 • 書き込んだ後はケーブル外してOK • 電源断してもファームウェアは保存されてる
  15. 15. ArudinoとFirmata 外部から制御するため のファームウェアを あらかじめ書き込む • Firmataの場合 • 主体はPC • PCがないと動かない • プログラムはArduinoに保存されない
  16. 16. FirmataのGood/Bad • Good • 通信とかコマンドとかメッセージとか 意識する必要がない • 様々な言語から叩ける • Bad • 基本的にはプリミティブな命令しかない ので、リアルタイム性が高いものには  不向き • 単独では動かない
  17. 17. カスタムプロトコルの道 • UART?BLE?Bluetooth? • だいたいはUARTでOKか • マイコン側/PC側のプログラムも必要 • UARTが1つ埋まる • printfデバッグがしにくくなる • プロトコル決めないと • めんどくさい
  18. 18. そこでRPC • マイコン側の関数をコールする • 複雑な操作を1つの関数にまとめる • 16x16のLEDマトリックスに「あ」と描く • コマンドサーボ複数個の同時位置指定 • 通信経路はUART • BluetoothのSPPやUSB-Serialが使える • なにか良いRPCないか…
  19. 19. ロボット PC そこで!gRPC! • シリアライズは Protocol Buffers • IDLでメッセージやRPCの構造を定義 • protocでソースコードも生成される • 正確にはgRPC-USBSerialゲートウェイ • よし、このゲートウェイをGoで書こう! • データ形式はAVRまでProtocol Bufferで! AVR (マイコン) gRPCサーバ(Go) Serial gRPC クライアント USB
  20. 20. 歩行デモ 5(Go)個のサーボモータを 制御しながら 5(Go)歩 あるきます
  21. 21. 歩行のデモ 盆栽を3月頃に調達しました が 5月に枯れてしまいました… 元気だった頃の盆栽
  22. 22. ロボット Protocol BuffersをAVRで • nanopb • http://koti.kapsi.fi/jpa/nanopb/ • 組み込み向けProtocolBufferのC実装 • 最低限の機能のみ実装 • 2-10 kB ROM, <1 kB RAMがターゲット • 今回のマイコンは32kB ROM、4kB RAM AVR (マイコン) gRPCサーバ(Go) Serial gRPC クライアント USB moveServos moveServos PC
  23. 23. robot.proto(IDL) syntax = "proto3"; package robot; service Soth { rpc moveServos (MoveServosRequest) returns (MoveServosResponse) {} } message MoveServosRequest { int32 servo_front_right_position = 1; int32 servo_front_left_position = 2; int32 servo_back_right_position = 3; int32 servo_back_left_position = 4; int32 servo_yaw_position = 5; } message MoveServosResponse { }
  24. 24. ロボット PC IDLのコンパイル $ protoc --go_out=. robot.proto $ prptpc --nanopb_out=. robot.proto これで、goとcのコードが出てくる AVR (マイコン) gRPCサーバ(Go) Serial gRPC クライアント USB robot.pb.go moveServos moveServos robot.pb.h robot.pb.c
  25. 25. gRPCサーバ type server struct{ s *serial.Port m sync.Mutex } func (srv *server) MoveServos(ctx context.Context, in *pb.MoveServosRequest) (*pb.MoveServosResponse, error) { srv.m.Lock() defer srv.m.Unlock() writeRobotSerial(srv.s, in) return &pb.MoveServosResponse{}, nil } シリアル通信ライブラリは github.com/tarm/serial
  26. 26. gRPCサーバ func main() { c := &serial.Config{ Name: /dev/tty.usbserial-DJ004Q2V , Baud: 115200} serial, err := serial.OpenPort(c) if err != nil { log.Fatal(err) } lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterSothServer(s, &server{s: serial}) s.Serve(lis) } シリアル通信用初期化 gRPCサーバ起動
  27. 27. gRPCクライアント c := pb.NewSothClient(conn) r, err := c.MoveServos(context.Background(), &pb.MoveServosRequest{ ServoFrontRightPosition: 700, ServoFrontLeftPosition: 900, ServoBackRightPosition: 900, ServoBackLeftPosition: 700, ServoYawPosition: 900 })
  28. 28. Goで楽しいロボットを 創りましょう!
  29. 29. codelunch.fmというポッドキャストにも 出演しました。聴いてみてください! 宣伝 Android、Ruby/Node.jsが 得意なエンジニア大募集! (もちろんGoも)

×