2016年9月23日金曜日

C言語(C++)の演算子の優先順位の話

トラブったのでメモ
 
C++でVector3という3次元ベクトルのクラスを作り演算子「+」をベクトルの足し算に、「*」をベクトルの内積に、「^」をベクトルの外積としてオーバーロードしました。そして以下のように実行しました。
 =======code start=======
Vector3 a, b, c;
float s;
//a, b, sへの値の代入
c=a*s+a^b;
=======code end=========
 このときもちろん c=(a*s)+(a^b) と実行することを期待していたのですが実際は c=((a*s)+a)^b と実行されました。

C言語の演算子の優先順位

演算子の優先順位はCもC++の一緒です。ここに良くまとまっているので、見やすいです。大まかに示すと
優先度高
・添え字系
・単項演算子系
・積算系
・加算系
・シフト
・条件演算子
・ビット演算子
・論理演算子
優先度低
となっています。
演算子はオーバーロードしても演算子の優先順位は変わりません。今回使った3つの演算子の優先順位は 積算(*) > 加算(+) > ビット反転(^) だったのに割り当てた機能を元に 内積(*) = 外積(^) > 加算(+) と勘違いしたことが原因でした。
これに懲りて外積は剰余(%)に割り当てることにします。

2016年9月18日日曜日

足先加重センサーについて

現在使っているロボットでは足先に加重センサーを入れています。最終的には足先の加重を見ることで平地以外の、でこぼこした道や、柔らかい地面の上も安定して歩けるようにしたいと思っています。一応見たところ誤差100gぐらいで精度良く足先の加重が読めているみたいです。

電気部

センサーの本体は秋月で売っている圧力センサーであるFSR400です。これは電気的には可変抵抗として見えて無負荷で抵抗が無限大、圧力がかかるごとに抵抗が下がっていくとデータシートに書いています。以下にデータシートから切り抜いたグラフを示しますが、抵抗は大体圧力と反比例するみたいです(グラフの軸は両対数)。
真ん中の測定回路は単純ですが出力が線形にならないのがちょっといやです。そこで以下のような回路を組みます。
良く見るとただの非反転増幅器です。ただゲインを決める抵抗のうち分母に来る側の抵抗にFSR400が、また増幅される電圧が一定になっているだけです。0.56*1+(4.7k/(FSR400の抵抗))[V]が出力されるはずです。

機械部

設計図の一部を下に示します。13番がFSR400です(丸の上側の数字が部品の番号です)。足先(17番)に加重がかかると15番の分がFSR400に接触して圧力を加えます。図では見えませんが15番と17番の間にはばねが入ってサスペンションの役割を果たします。
 評価
足先にかかった荷重とセンサーの出力値の関係を以下のグラフに示します。今回作るのは6脚歩行ロボットなので上記の足部分は6つあります。今回はそのうちの3つを計測しました。
系統1と2でずれがありましたが、系統3では15番の部品の表面が粗くスムーズに動いていない分が差になっているような気がします。おおむね精度良く値を取得できる気がします。


回路の設計では上記のグラフは線形になるはずでしたがうまくいきませんでした。一応エクセルの近似曲線を出したところ2次できれいに近似できました。2kgより上は加えたのですが値が変わらないので、これがセンサーの限界みたいです。

2016年9月15日木曜日

ドキュメントジェネレーターDoxygenの導入

Doxygenはソースコードに一定の書式でコメントを書いておくと、そこからソースコードのドキュメントを自動で生成してくれるソフトです。今回はPythonへの適用の方法を書いていきます。Linux/Debianで使用します。

1.インストール

$apt-get install doxygen doxygen-gui graphviz

2.GUIで設定

$doxywizard
でGUIでの設定画面が開きます。まずStep1というところにソースファイルのあるディレクトリを指定します。
設定すべき項目は「Wizard」の「Mode」ではOptimize for Java or C# (for Pythonという物はなく、これを選ぶのが良いらしい)

「Output」ではHTMLのみにチェックを付けて、ラジオボタンはwith navigation panelにします。

あとは「Run」のタブでRun Doxygenを選ぶだけでHTMLというディレクトリが生成されてそのならのIndex.htmlを開くと生成されたドキュメントが読めます。

メニューバーの「Setting」からUse current setting for startupを選ぶと現在の設定がデフォルトに登録されます。

3.書き方

以下のようなファイルを変換すると

## @package pyexample
#  Documentation for this module.

## Documentation for a function.
def func():
    pass

## Documentation for a class.
class PyClass:

    ## The constructor.
    def __init__(self):
        self._memVar = 0;

    ## Documentation for a method.
    #  @param self The object pointer.
    #  @return 0 fixed
    def PyMethod(self):
        return 0

    ## A class variable.
    classVar = 0;
 

下記のようになります(全部写っていないのですが雰囲気だけ)。

pythonのは#から先がコメントになります。doxygenで使うテキストはコメント部分に書きます。
ただし最初の行だけは##から始める必要があります。
例えばクラスの説明をしたい場合にはクラスの宣言の直前に書くとその部分がクラスの説明とみなされます。また@から始まる特別なコマンドがあります。DoxygenのWebサイトに一覧がありますが主なものを乗せておきます。
  • @package
    パッケージの情報を記述します。
  • @date
    日付の情報を記述します
  • @version
    バージョン情報を記述します。
  • @code~@endcode
    コードを記述します。この領域では改行の省略などがされなく、書いたものがそのまま表示されます。@codeではじめて、必ず@endcodeで閉じる必要があります。
  • @param
    関数の説明文でパラメーターの説明を記述します。@param [変数名] [説明]と書きます。
  • @return
    関数の説明文で返り値の説明を記述します。








2016年9月13日火曜日

githubの使い方

メモ代わりに書いていきます。

  • githubにアカウント開設
    学生なら初期プラン無料(=-7$)のサービスがある
    アカウント(!=メールアドレス)とパスワードはターミナルでの操作で必要になるので注意
  • リポジトリの作成
    作成したいディレクトリに移動
    $git init
  • ファイルの登録("."でディレクトリの全部のファイルを登録)
    $git add .
  • コミット
    ("."でディレクトリの全部のファイルを登録)
    $git commit .
  • コミット(addの省略)
    commitはaddしたもの(=staged)しか行われなく、commitするたびにuncommit(=stagedでない)に変わる。毎回addする必要がある。-aで追跡対象ファイルをaddしてからcommitする。
    $git commit -a
  • リポジトリの登録を登録
    これをやると下記のpull pushが楽になる
    リポジトリ $git remote add origin  https://github.com/○○○/□□□.git
  • プル
    $git pull origin master
  • プッシュ
    $git push origin master

注意点

  • リポジトリ != ディレクトリ
    リポジトリはファイルの変更を記録するファイルみたいなもの、ディレクトリにリポジトリを追加(init)してもディレクトリの中身はリポジトリに追加されません(addが必要)
  • リモートとローカルの違い
    普段変更する(= commit)するのがローカルリポジトリ。ネットワーク上に合ってたまに変更する(= push)のがリモートリポジトリ
  • リモートリポジトリに初回のpushする前にpullしないといけない
  • pushする前にcommitしないと駄目
  • pullする前にもcommitしないと駄目