土曜日, 7月 09, 2016

Arduino: 赤外線距離センサー


赤外線距離センサーとは、赤外線LEDとフォトトランジスタを組み合わせ、反射してくる赤外線を測ることで距離を測るものです。



距離センサーというと超音波を使うものなどありますが、赤外線距離センサはまとめて売られている赤外線LEDとフォトトランジスタさえあればそのままセンサが量産できます。

LEDへの電流を制限する抵抗の値が小さいと発熱するので気を付ける必要があります。

人間の目は赤外線を検出できませんが、CCDであれば赤外線LEDが光っているのが分かります。



このセンサをモジュール化してみました。以下使ってみて気づいたことです。



このセンサは計測する物体が赤外線を反射しなければ使えません。白っぽければ反応しますが、そうでなければだめです。それはまだいいんですが…

このセンサーは赤外線を検出する方式ですので、赤外線がどこかほかからくればそれで反応します。つまり、太陽光のもとでは使えないってことです。

ライン・トレーサーなどで使われるのがこの赤外線距離センサーです。目的が限られてますね。注意しましょう。

木曜日, 7月 07, 2016

C++: べき集合の要素を数え上げる

べき集合というものがあります。部分集合の集合というものなんですが、べき集合の要素を出力するプログラムを書いてみました。

原理は簡単です。要素が n 個あるとして、含まれる場合を1、含まれない場合を0とすると

0 0 0
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1

これで完全な数え上げとなります。シフト演算子とか論理ANDとかを使うと、要素の数え上げができるわけですね。

では{ドイツ、フランス、英国}という集合を考えてみましょう。べき集合はこんなふうです。

{ }
{ Germany }
{ France }
{ Germany France }
{ United Kingdom }
{ Germany United Kingdom }
{ France United Kingdom }
{ Germany France United Kingdom }

すべてのケースを考えるというのはこの小さな集合だけでも大変ですね。

じゃあ、もう少し増やしてみましょう。イタリアとオランダ、スペインを加えてみました。

{ }
{ Germany }
{ France }
{ Germany France }
{ United Kingdom }
{ Germany United Kingdom }
{ France United Kingdom }
{ Germany France United Kingdom }
{ Italy }
{ Germany Italy }
{ France Italy }
{ Germany France Italy }
{ United Kingdom Italy }
{ Germany United Kingdom Italy }
{ France United Kingdom Italy }
{ Germany France United Kingdom Italy }
{ Netherlands }
{ Germany Netherlands }
{ France Netherlands }
{ Germany France Netherlands }
{ United Kingdom Netherlands }
{ Germany United Kingdom Netherlands }
{ France United Kingdom Netherlands }
{ Germany France United Kingdom Netherlands }
{ Italy Netherlands }
{ Germany Italy Netherlands }
{ France Italy Netherlands }
{ Germany France Italy Netherlands }
{ United Kingdom Italy Netherlands }
{ Germany United Kingdom Italy Netherlands }
{ France United Kingdom Italy Netherlands }
{ Germany France United Kingdom Italy Netherlands }
{ Spain }
{ Germany Spain }
{ France Spain }
{ Germany France Spain }
{ United Kingdom Spain }
{ Germany United Kingdom Spain }
{ France United Kingdom Spain }
{ Germany France United Kingdom Spain }
{ Italy Spain }
{ Germany Italy Spain }
{ France Italy Spain }
{ Germany France Italy Spain }
{ United Kingdom Italy Spain }
{ Germany United Kingdom Italy Spain }
{ France United Kingdom Italy Spain }
{ Germany France United Kingdom Italy Spain }
{ Netherlands Spain }
{ Germany Netherlands Spain }
{ France Netherlands Spain }
{ Germany France Netherlands Spain }
{ United Kingdom Netherlands Spain }
{ Germany United Kingdom Netherlands Spain }
{ France United Kingdom Netherlands Spain }
{ Germany France United Kingdom Netherlands Spain }
{ Italy Netherlands Spain }
{ Germany Italy Netherlands Spain }
{ France Italy Netherlands Spain }
{ Germany France Italy Netherlands Spain }
{ United Kingdom Italy Netherlands Spain }
{ Germany United Kingdom Italy Netherlands Spain }
{ France United Kingdom Italy Netherlands Spain }
{ Germany France United Kingdom Italy Netherlands Spain }

そうですね。どのような通商交渉が成り立つでしょうか。

では極め付け、EUが存在しないと仮定して、EU加盟国の各国のそれぞれ組み合わせを考えたとします。

と、書きだそうとするとファイルの大きさがギガを超えてきたのでギブアップです。

組み合わせを考えるとなんと 268435456 となります。

これを考えるとEUのフレームワークってのは偉大ですね。

あらたな世界秩序ってのをつくろう、ってのは無謀じゃないでしょうか。

#include <iostream>
using namespace std;
int main()
{
string set[]={
"Germany",
"France",
"United Kingdom",
"Italy",
"Netherlands",
"Spain"
};
/*
string set[]={
"Austria",
"Belgium",
"Bulgaria",
"Croatia",
"Cyprus",
"Czech Republic",
"Denmark",
"Estonia",
"Finland",
"France",
"Germany",
"Greece",
"Hungary",
"Ireland",
"Italy",
"Latvia",
"Lithuania",
"Luxembourg",
"Malta",
"Netherlands",
"Poland",
"Portugal",
"Romania",
"Slovakia",
"Slovenia",
"Spain",
"Sweden",
"United Kingdom"
};
*/
int n=sizeof(set)/sizeof(set[0]);
for(int i=0;i<(1<< n);i++)
{
cout << "{ ";
for(int j=0;j<n;j++)
{
if(((i>>j)&1)==1)
{
cout << set[j] << " ";
}
}
cout <<"}"<< endl;
}
return 0;
}
view raw powerset.cpp hosted with ❤ by GitHub

水曜日, 7月 06, 2016

C++: 逆ポーランド記法

数式の表現方法で、ポーランド記法ってのがあります。

普通の数式では

a + b

と書くところを、演算子(プラス記号)の順序を変えて、

+ a b

と書きます。

これだって数式は表せるわけですね。Lisp などでは (+ a b) となります。

+ + a b c

これだと、どうなるでしょう。

a + b + c

こうですね。

逆ポーランド記法というのあります。逆ポーランド記法であると、a + b が

a b +

となります。日本語だと思えばいいんですね。「a と b を足す」という形です。

a b c + +

これだと、「a と b と c と足して、また足す」となります。

以下は、逆ポーランド記法の数式を処理するプログラムです。

→  reverse-polish-notaion

#括弧の処理を追加しました。(2016-07-10)


#include <iostream>
#include <sstream>
#include <stack>
#include <stdlib.h>
using namespace std;
string parse()
{
string str;
stack<string> stk;
char c;
int x,y,z;
while(cin >> c, c != '=')
{
switch(c)
{
case '(':
stk.push(parse());
break;
case ')':
if(!stk.empty())
{
return stk.top();
}
break;
case '+':
case '*':
case '-':
case '/':
x=atoi(stk.top().c_str());stk.pop();
y=atoi(stk.top().c_str());stk.pop();
if(c=='+')
z=x+y;
else if(c=='-')
z=y-x;
else if(c=='*')
z=x*y;
else if(c=='/')
{
if(x!=0)
z=y/x;
else
{
cout << "Error: Division by zero" << endl;
throw 0;
}
}
stk.push(static_cast<ostringstream*>( &(ostringstream() << z) )->str());
break;
default:
cin.putback(c); cin >> str;
stk.push(str);
break;
}
}
if(!stk.empty())
{
return stk.top();
}
throw 0;
}
int main()
{
try
{
cout << parse();
}
catch(int e)
{
cout << "Parse error" << endl;
}
return 0;
}
view raw calc.cpp hosted with ❤ by GitHub

月曜日, 7月 04, 2016

g++: テンプレートを使う場合の分割コンパイル

テンプレートを使う場合、実装を別ファイルで行うとややこしくなります。

こんなテンプレートを使うヘッダーファイルがあったとします。

template <class T> class A
{
public:
int a;
A();
};
view raw header.h hosted with ❤ by GitHub

ここで、別ファイルで実装します。

#include "header.h"
template <class T> A<T>::A()
{
a=0;
}
view raw a.cpp hosted with ❤ by GitHub

このヘッダーファイルをインクルードして、別ファイルで呼び出すとリンカがエラーを出します。

#include <iostream>
#include "header.h"
using namespace std;
int main()
{
A<int> a;
cout << a.a << endl;
return 0;
}
view raw main.cpp hosted with ❤ by GitHub

ヘッダーファイルで実装すると問題は解決です。

template <class T> class A
{
public:
int a;
A()
{
a=0;
}
};
view raw header-new.h hosted with ❤ by GitHub

Qt: 外部プログラムを起動する

  Qt/C++ のアプリは、外部へ直接アクセスできます。これはネットアプリでは不可能な Qt のメリットです。 外部プログラムを起動することもできます。QProcess::startDetached() を使うと独立したプロセスを立ち上げることができます。 この QProces...