空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

ネットワークのお勉強その1

f:id:robonchu:20170520144353p:plain

IPアドレス

192.168.1.128

以下の2つから構成されている

  1. ネットワーク・アドレス(192.168.1.)
  2. ホスト・アドレス(128)

ネットワーク・アドレスは、ネットワーク全体でお互いのネットワークを識別するために使われ、 ホスト・アドレスは、同一ネットワーク内でお互いのホストを識別するために使われる、ということである。

参考: 基礎から学ぶWindowsネットワーク:第7回 IPアドレスとネットマスク (2/3) - @IT

ネットマスク

  • IPアドレスからネットワーク・アドレス部を抽出するためのマスク値
  • ネットワークの範囲を定義するために使用する

参考: 基礎から学ぶWindowsネットワーク:第7回 IPアドレスとネットマスク (1/3) - @IT

ゲートウェイ

  • 所属するネットワークの外へアクセスする際に使用する「出入り口」の代表となる機器のこと
  • 異なるネットワーク同士を接続するネットワーク機器のこと

参考:デフォルトゲートウェイとは TCP/IP入門 デフォルトゲートウェイとは | IPラーニング

マシンA : 192.168.2.1/255.255.255.0

マシンB : 192.168.2.2/255.255.255.0

この2つは同じネットワークなので、双方向通信が可能

マシンC : 192.168.2.1/255.255.0.0

このCは上記2つと同じネットワークではないので通信することができない。

通信するためにはネットワーク同士をつなぐゲートウェイが必要になる。

ffmpegとpythonで動画をいじろう

ffmpegのインストー

sudo apt-get install ffmpeg

動画の変換

ffmpeg -i test1.MOV -strict -2 test1.mp4

動画の結合

ffmpeg -i test1.mp4 -i test2.mp4 -strict -2 -filter_complex "concat=n=2:v=1:a=1" output.mp4

動画の倍速方法

(TBD)

pythonでフォルダ内の指定ファイルをの取り込み

import os 
files = os.listdir('<dir path>')
 
for file in files:
    print file

こちらだとワイルドカードが使える

import glob
 
files = glob.glob('<dir path>/*.*')
 
for file in files:
    print file

pythonでコマンド実行するには

import subprocess
cmd = "ls -a"
subprocess.call( cmd, shell=True  ) 

フォルダ内の.MOVファイルをmp4ファイルに変換して、結合するdamedameコード

video_con.py

import sys
import glob
import subprocess
import os

args = sys.argv
files = glob.glob(args[1]+"/*")
num = 0

join_mov = str("")

for file in zipfiles:
    num += 1
    slice = file[0:-4]
    cmd1 = "ffmpeg -i "+file+" -strict -2 "+slice+".mp4"
    subprocess.call( cmd, shell=True  )
    join_mov += " -i "+ slice+".mp4"

cmd2 = "ffmpeg"+join_mov+" -strict -2 -filter_complex "+"\"concat=n="+str(num)+":v=1:a=1\" output.mp4"
subprocess.call( cmd2, shell=True  )

実行方法

python video_con.py <path>

たとえば~/video/test/*の.movファイルを変換したいとすると以下のように記述

python video_con.py ~/video/test

rosを使ってセンサ取得データの保存

rosを使ってセンサ取得データを保存する。

 環境

  • os: ubuntu16.04
  • ros: kinetic

usb_cam編

インストー

  • usb_camのインストー

参考:づーまー日記: 【備忘録】 ROS Kinetic でusb-camのインストール方法&使い方

データの表示

ターミナル1

$ roscore

ターミナル2

$ rosrun usb_cam usb_cam_node

ターミナル3

$ rosrun image_view image_view image:=/usb_cam/ime_raw

データの保存

  1. image_viewのGUIの保存ボタンで画像を保存
  2. rosbagの使用
$ rostopic list
$ rosbag record /usb_cam/camera_info /usb_cam/image_raw -O usb_cam_data.bag

-O でファイル名を指定

rosbagでのデータの再生方法

$ rosbag play -l images.bag

-l でループ再生

rosbagでbagファイルを確認

$ rosbag info usb_cam_data.bag

kinect, Xtion編

参考: demura.net | Xtion Pro LiveをUSB3.0とROS Indigoで使うメモ https://staff.aist.go.jp/kanezaki.asako/pdf/SSII2016_AsakoKanezaki_tutorial.pdf 

Numpy / pandasのお勉強

numpy

配列も@で行列のように計算できる。python3.5以降。

In [7]: import numpy as np

In [8]: A = np.array([[1,2],[3,4]])

In [9]: B = np.array([[5,6],[7,8]])

In [10]: C = A @ B @ A.T

In [11]: C
Out[11]: 
array([[ 63, 145],
       [143, 329]])

以下は同じ意味

In [12]: A = np.array([[1,2],[3,4]])

In [13]: B = np.array(((1,2),(3,4)))

いろいろな配列の作り方があるよ

In [24]: np.zeros((2,2))
Out[24]: 
array([[ 0.,  0.],
       [ 0.,  0.]])

In [25]: np.arange(1,100,20)
Out[25]: array([ 1, 21, 41, 61, 81])

メソッド

In [26]: A.shape
Out[26]: (2, 2)

行列計算

In [28]: A
Out[28]: 
array([[1, 2],
       [3, 4]])

In [29]: np.linalg.inv(A)
Out[29]: 
array([[-2. ,  1. ],
       [ 1.5, -0.5]])

In [30]: np.linalg.det(A)
Out[30]: -2.0000000000000004

In [31]: np.linalg.matrix_rank(A)
Out[31]: 2

配列の操作

In [34]: matrixA = np.arange(9).reshape(3,3)

In [35]: matrixA
Out[35]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [36]: a = matrixA[1][1:];a
Out[36]: array([4, 5])

In [37]: a[1] = 10

In [38]: matrixA
Out[38]: 
array([[ 0,  1,  2],
       [ 3,  4, 10],
       [ 6,  7,  8]])

In [39]: matrixA[0,1]
Out[39]: 1

In [40]: matrixB = matrixA[1:,1:];matrixB
Out[40]: 
array([[ 4, 10],
       [ 7,  8]])

In [41]: matrixB[:,:]=100

In [42]: matrixA
Out[42]: 
array([[  0,   1,   2],
       [  3, 100, 100],
       [  6, 100, 100]])

In [44]: matrixC = np.random.rand(2,2);matrixC
Out[44]: 
array([[ 0.47235181,  0.13044348],
       [ 0.86500587,  0.17257454]])

In [45]: maskC = matrixC > 0.2; maskC
Out[45]: 
array([[ True, False],
       [ True, False]], dtype=bool)

In [46]: matrixD = matrixC[maskC]

In [47]: matrixD
Out[47]: array([ 0.47235181,  0.86500587])

↓すごくわかりやすい!!! 参考:

www.slideshare.net

C++のお勉強(1)

やりたいこと

C++スキルアップ

教科書

本を書きました。『基礎からしっかり学ぶC++の教科書』 | 配電盤

環境構築

$ sudo apt-get install g++

ビルド方法(単体)

$ g++ Sample.cpp 

or

makefileを以下のように記載し、$ make

Sample: Sample.cpp
    g++ -o Sample Sample.cpp
    ##g++ -std=c++11 -o Sample Sample.cpp

ビルド方法(複数)

$ g++ -c Sample1.cpp -o Sample1.o
$ g++ -c Sample2.cpp -o Sample2.o
$ g++ Sample1.o Sample2.o

or

Sample: Sample1.o Sample2.o
    gcc -o Sample Sample1.o Sample2.o

Sample1.o: Sample1.cpp
    gcc -c Sample1.cpp

Sample2.o: Sample2.cpp
    gcc -c Sample2.cpp

参考:

ヘッダーと.cppを作ってコンパイル

メイクファイルをじわーっと作ってみる

ターミナルでC++のコンパイル - Qiita

デバッグツール

gdbの使い方

  • ビルド時に-gをつけて実行
$ g++ -g -O0 Sample.cpp
  • gdb立ち上げ
$ gdb a.out
  • 使ってみる:ステップ実行
$ break main
$ run
$ next
$ next
...
$ quit

参考:  gcc+gdbによるプログラムのデバッグ 第1回 ステップ実行、変数の操作、ブレークポイント

ポインタ

Sample1

#include <iostream>
#include <string>
using namespace std;

class Robot{
  string name;
public:
  Robot(){}
  Robot(string n):name(n){}
  void SetName(string n){
    name = n;
  }
  void Speak() const;
};

void Robot::Speak() const {
    cout << "My name is " << name << "!" <<endl;
}


int main (){

  Robot dora;
  Robot *p2;
  p2 = &dora;
  cout << p2 << endl;
  
  p2->SetName("Atom");  //(*p2).SetName("Atom");
  p2->Speak();   //(*p2).Speak();

  Robot *x;
  x = new Robot;
  x -> SetName("Tetsujin");
  x -> Speak();
  delete x;

  Robot *y;
  y = new Robot("Chappy");
  y -> Speak();
  delete y;

  int i;
  int num;
  string temp;
  Robot *r;
  cout << "Please a number of Robot you want to make."<<endl;
  cin >> num;

  r = new Robot[num];

  for (i =0 ; i<num;i++){
    cout << "Please type robot's name." <<endl;
    cin >> temp;
    r[i].SetName(temp);
  }

  for (i=0;i<num;i++){
    r[i].Speak();
    }

  delete [] r;
}

Sample2

#include <iostream>
using namespace std;

int main(){
  int x = 1;
  int* px = &x;
  int** ppx = &px;
  *px = 10;
  cout << x <<endl;
  cout << **ppx <<endl;
}

10
10

スマートポインタ

メモリリークを自動的に防いでくれる

#include <iostream>
#include <complex>
#include <memory>
using namespace std;

int main(){
  using cpdb = complex<double>;
  
  shared_ptr<cpdb> x = make_shared<cpdb>();
  cout << *x << endl;

  shared_ptr<cpdb> y = make_shared<cpdb>(1.1,2);
  cout << *y << endl;

  shared_ptr<cpdb> z = make_shared<cpdb>(*y);
  cout << *z << endl;
}

継承

#include <iostream>
using namespace std;

class Robot
{
  string name;
public:
  void SetName(string n){name = n;}
  string GetName() const{ return name;}
  void InputData();
  void ShowData() const;
};

void Robot::InputData(){
  cout << "input Name:";
  cin >> name;
}

void Robot::ShowData() const{
  cout << "name:"<<name<<endl;
}

class FRobot : public Robot
{
  int power;
public:
  void SetPower(int p){ power = p;}
  int GetPower() const{ return power;}
  void InputData();
  void ShowData() const;
  int FullPower() const { return power * 10;}
};

void FRobot::InputData(){
  Robot::InputData();
  cout << "input power:"<<endl;
  cin >> power;
}

void FRobot::ShowData() const{
  Robot::ShowData();
  cout << "FullPower is :" << FullPower() << "!!!" << endl;
}

int main()
{
  FRobot f[3];
  string temp;
  int i,sum;

  for (i=0;i<3;i++){
    f[i].InputData();
  }
  cout << endl;

  cout << "display all robot power" << endl;
  for(i = 0; i< 3; i++){
    cout <<"Mark" <<i + 1 << "!"<<endl;
    f[i].ShowData();
    cout << "----------------" <<endl;
  }

  sum = 0;
  for (i = 0 ; i <3 ; i++){
    sum += f[i].FullPower();
  }
  cout << "ALL ROBOT FULL POWER :" << sum <<"!!!"<<endl;
}

参照引数の関数

参照引数の場合、引数にコピーしないため軽量

void func(X& a){...}
or
void func(const X& a)

上は、引数のデータが書き換わる可能性あり

下は、書き換わることを防ぐ

関数の引数の種類

  1. int → void func1 (int x) {}
  2. const int → void func2 (const int x) {}
  3. int& → void func3 (int& x) {}
  4. const int& → void func4 (const int& x) {}
  5. int&& → void func5 (int&& x) {}
  6. const int&& → void func6 (const int&& x) {}
  7. int → void func7 (int x) {}
  8. const int → void func8 (const int x) {}

これだけ考えられるが基本的にはfunc1~4を考えれば良い。

参考:右辺値参照・ムーブセマンティクス - cpprefjp C++日本語リファレンス

テンプレート

include <iostream>
#include <string>
using namespace std;

template <typename T>
void SwitchValue(T& x, T& y){
  T temp = x;
  x = y;
  y = temp;
}

int main(){
  int a = 1;
  int b = 2;
  SwitchValue(a,b);
  cout << a << endl;
  cout << b << endl;

  string c = "1";
  string d = "2";
  SwitchValue(c,d);
  cout << c << endl;
  cout << d << endl;

}

参考:第 4 章 テンプレート (C++ プログラミングガイド)

イテレータ

参考:C++ iterator 入門 C++ イテレータ入門 - プログラミングの教科書を置いておくところ

別名

using uint = unsigned int; //typedef unsigned int uint;
uint x = 0; //  equal unsigned int x = 0

キャスト

#include <iostream>
using namespace std;

int main(){
  int x = 0;
  x = static_cast<int>(1.11);
  cout << x << endl;
  x = (int)1.11;
  cout << x << endl;
  x = int(1.11);
  cout << x << endl;
}

ビット演算

#include <iostream>
using namespace std;

int main(){
  int x = 1;
  int y = 5;
  cout << (y >> 1) << endl; //2
  cout << (y << 1) << endl; //10
  cout << (y >> 2) << endl; //1
  cout << (y << 2) << endl; //20
  cout << (x & y) << endl; //1
  cout << (x | y) << endl; //5
  cout << (x ^ y) << endl; //4
  cout << (~x) << endl; //-2
}

列挙型

#include <iostream>
using namespace std;

int main(){
  enum robots { Atom, Tetsujin, Dora };
  robots x = Tetsujin;
  cout << (x==Tetsujin ? "Mark21": "Mark0")<<endl;
}

静的変数

一度だけ初期化され、その後共有される

以下の例ではstaticがないと、出力は1,1,1になる

#include <iostream>
using namespace std;

int increment(){
  static int x = 0;
  ++x;
  return x;
}

int main(){
  cout << increment() <<endl; //1
  cout << increment() <<endl; //2
  cout << increment() <<endl; //3
}

名前空間

#include <iostream>
using namespace std;

int x;

namespace NAME1{
  int x = 1;
}

namespace NAME2{
  int x = 2;
}

int main(){
  int x = 3;
  cout << x << endl;//3
  cout << ::x << endl;//0
  cout << NAME1::x << endl;//1
  cout << NAME2::x << endl;//2
}

コンテナ

#include <iostream>
#include <complex>
#include <vector>
using namespace std;

int main() {

  using cpdb = complex<double>;
  vector<int> v1;
  v1.push_back(2);
  v1.push_back(3);
  v1.push_back(4);
  v1.push_back(5);

  vector<int> v2(4);
  v2[0]=6;
  v2[1]=7;
  v2[2]=8;
  v2[3]=9;

  vector<int> v3{10,11,12,13};

  for (int i = 0 ; i < v1.size() ;i++){
    cout << v1[i] << endl;
    cout << v2[i] << endl;
    cout << v3[i] << endl;
  }

  v3.pop_back();
  v3.erase(v3.begin() + 1);

  for (int i = 0 ; i < v3.size() ;i++){
    cout << v3[i] << endl;
  }

  vector<int> v4(v1);

  for (int i = 0 ; i < v4.size() ;i++){
    cout << v4[i] << endl;
  }

  vector<cpdb> v5;
  v5.reserve(10);
  v5.emplace_back(1.11,2.0);
  cout << v5.capacity() << endl;
  
  vector<vector<int>> v6{{1,2,3},{4,5,6}};

  cout << v6.size() <<endl;
  cout << v6[0].size() <<endl;
  cout << v6[0][2] << endl;
}

例外

#include <iostream>
using namespace std;

void DoSomething(){
  throw runtime_error("error!");
}

int main(){
  try{
    DoSomething();
  }
  catch (exception& e){
    cerr << e.what() <<endl;
  }
  cout << "Normal Stop.";
}

kerasを動かしてみる~その1~

TJOさんの記事を参考にKerasを動かして見ました。感謝です。

参考: KerasをTensorFlowバックエンドで試してみた:「もっと多くの人に機械学習とDeep Learningを」という時代の幕開け - 六本木で働くデータサイエンティストのブログ

tensorflowのインストー

参考のInstalling with virtualenvをそのまま実行

参考:Installing TensorFlow on Ubuntu  |  TensorFlow

$source ~/tensorflow/bin/activeでtensorflow環境へ切り替え

kerasを動かすときはこの環境へ切り替えておくこと

Kerasのインストー

$sudo pip install kerasでインストー

Kerasの実行

TJOさんの「KerasのCNNでMNIST短縮版の分類をやってみる」のコードを一箇所書替えて実行

score = model.evaluate(x_test, y_test, show_accuracy=True, verbose=0)
↓
score = model.evaluate(x_test, y_test, verbose=0)

実行結果:Test accuracy: 0.976

とりあえず動きましたー

構造を変更したり、データオーギュメンテーションとかして理解を深めるぞ〜!

これから読んで勉強したい記事:

KerasをTensorFlowバックエンドで試してみた:「もっと多くの人に機械学習とDeep Learningを」という時代の幕開け - 六本木で働くデータサイエンティストのブログ

はじめての Deep Learning - Keras で MLP for MNIST · m0t0k1ch1st0ry

[Python]強化学習(DQN)を実装しながらKerasに慣れる - Qiita 

DeepLearning系ライブラリ、Kerasがあまりにも便利だったので使い方メモ - プロクラシスト

Tensorflowの上位ラッパーライブラリ Kerasを試してみる - デジタル・デザイン・ラボラトリーな日々

深層学習やってみる - Kerasで手書き数字認識(MNIST) - ポンダッドの日記

Raspberry Pi 深層学習ライブラリで物体認識(Keras with TensorFlow・Open CV) - Qiita

SSD: Single Shot MultiBox Detector 高速リアルタイム物体検出デモをKerasで試す - Qiita

KerasでCIFAR-10の一般物体認識 - 人工知能に関する断創録

SSDによる物体検出を試してみた - TadaoYamaokaの日記

Kerasで学ぶAutoencoder

Implementation of FCN via Keras - MATHGRAM good!

aidiary.hatenablog.com

【ディープラーニング】kerasで多クラス分類 - testtest2222’s blog

DeepLearning系ライブラリ、Kerasがあまりにも便利だったので使い方メモ - プロクラシスト

www.slideshare.net