October 07, 2007

2007 八ヶ岳

八ヶ岳に行ってきました。快晴で最高でした。

2007akadake.jpg
横岳より赤岳。奥に見えるのは、恐らく甲斐駒、北、仙丈。

八ヶ岳に行ったのは2年ぶり5回目なんですが、行く度にいい山だと改めて思います。
今回は1泊2日で桜平~夏沢峠~硫黄岳~横岳~赤岳~頂上小屋泊~阿弥陀岳~御小屋尾根~美濃戸という経路をとりましたが、こんなに行っていても初めての経験というのはあるもので、桜平から入るのと御小屋尾根ははじめてでした。御小屋尾根のルートは阿弥陀からの下りがかなり急でガレているので気をつける必要がありました。またエアリアに載っていない美濃戸小屋に直接降りるルート(結局こちらを使いました)があったりするので注意が必要です。

okoya_minoto.jpg
問題のルート(赤線)。画像は国土地理院より。

また初体験といえば、美濃戸~新宿間の直行バスを帰りに使ってみました。2年前から運行が開始したそうで、毎日新聞が企画しています。こちらも快適でした。

22:00 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (2) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/595

October 15, 2007

Super Sylphide 進捗状況(11) -- Time Keeper

つい先日大きな出張が完了したので、オートパイロットシステムSuper Sylphideをサクっと完成させてしまおうと考えています。そのような中、とある試験をGPSが使用不能な環境下で行うことになりそうなので、それに備えた準備をすることになりました。そこで問題となったのが、こちらのオートパイロットシステムで取得したデータと、他のシステムのデータの同期をとるという作業です。

GPSの一般的な使い方であるカーナビなどではあまり取り上げられることがないのですが、実はGPSは手軽な高精度時計として利用することが可能です。詳しい話は専門書に譲りますが、GPSが現在位置を出力する原理は、人工衛星から放出されたGPS電波が地上に到達するまでの時間を計測することから成り立っています。つまり時間や時刻を管理する時計の精度は、GPSの性能を決定する非常に重要なファクターです。実際、GPSの電波を放出している人工衛星には非常に高価な原子時計が何台も搭載されています。そういうわけでGPSは手軽な高精度時計として使用することができます。

今まではGPSが利用可能であったので、気軽に他のシステムによって取得されたデータと同期をとることができました。特に現在使用中のGPSモジュール LEA-4Tは1秒単位のパルス信号(1pps)が取り出せるので、時刻同期用の時計としても重宝していました。ところが今回はGPSが利用できないので、代替手段を考えなければいけません。
そこで代わりのシステムを作ることにしました。その名もTime Keeper。

time_keeper_brd_top.gif
time_keeper_brd_bottom.gif
基板表裏。36 x 21 mm。

使い方はSuper Sylphideにおいて、GPSが載ったボード、並びにそれからの出力を受けとるボードとの間に、このTime Keeperを挿入します。Time Keeperは、GPSが利用可能な間は先ほどの1ppsをそのまま出力します。GPSが使用不能になった場合はTime Keeper内蔵のReal Time Clock (RTC)に切り替えて、1ppsを継続出力します。主電源が落ちてもRTCの動作は保証できるよう、バックアップ電源としてスーパーキャパシタを搭載しました。

例によって現時点でのEagleのファイル(回路図レイアウト)を置いておきます。マイコン兼RTCとしてSilicon LaboratoriesのC8051F410を使っていますが、まだファームウェアは書いていません。

※その後、本体の航法プログラムのROM化が完了しました。
※さらにその後、Time Keeperのファームウェアを公開しました。

22:08 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/596

October 21, 2007

memcpyによるクラスのコピー

C++の話です。オリジナルのQueue、すなわちFIFO(First In First Out)といった方がわかりやすいでしょうか、を実装することになりました。基本的なアルゴリズムなので、車輪の再発明は極力避けるべきだ、というのが常識だと思いますが、STLがないDSP用のプログラムを書かなければならない為やむを得ずといったところです。実のところ、本人的にはこういう基礎アルゴリズムを実装するのは、勘を養うことにもなりますし結構楽しんでやってしまいました。

実装にあたって、当初はcharやintといった基本型程度しか使わないかなと思っていたので、FIFOへの書込み、読み出しはmemcpyを使って実装していました。ところが途中から汎用化欲がフツフツと沸き始め、ええぃ普通のクラスも管理できれば、いつかどこかで楽しい思いをできるに違いないと思えてきたのです。

そこで今回のお題なわけですが、果たして自分で作ったクラスのコピーをとるのはmemcpyでいいのでしょうか。答えを言ってしまうと、memcpyでは問題がおこる場合があります。実際に今回は2つの問題に遭遇しました。

まず第1のケースは、以下に示すコードのような、参照カウンタを利用してライトウェイトな実装になっている場合です。

class LightWeight{
    private:
        struct storage_t {
            int ref; ///< 参照カウンタ
            int value; ///< 何か値
            storage_t() : ref_count(0) {}
        };
        storage_t *content;
    public:
        LightWeight() : content(new storage_t()) {} ///< コンストラクタ
        ~LightWeight(){ ///<デストラクタ
            if(content && ((--(content->ref)) <= 0)){
                delete content;
            }
        }
        LightWeight(const LightWeight &obj){ ///< コピーコンストラクタ
            if(content = obj.content){(content->ref)++;}
        }
        LightWeight &operator=(const LightWeight &obj){ ///<代入演算子
            if(this != &obj){
                if(content && ((--(content->ref)) <= 0)){delete content;}
                if(content = obj.content){(content->ref)++;}
            }
            return *this;
        }
        int &content(){return (content ? (content->value) : *(int *)NULL);}
};

このようなLightWeightクラスをコピーする場合は、代入演算子か、コピーコンストラクタによるコピーで参照カウンタの整合性を確保してやる必要があります。もしmemcpyで単純にコピーをすると参照カウンタが本来参照されている数よりも少なくなってしまい、Segmentation Faultが発生してしまいました。

遭遇した第2のケースですが、継承関係があり仮想関数が使用されている場合です。同じくコードで示します。

#include <iostream>

using namespace std;

class Base{
    public:
        virtual void hoge(){cout << "Base::hoge" << endl;}
        void ada(){hoge();}
};
class Sub : public Base{
    public:
        virtual void hoge(){cout << "Sub::hoge" << endl;}
};
int main(){
    Sub sub;
    Base base;
    base = sub;
    base.ada(); ///< (1)
    memcpy(&base, &sub, sizeof(Base));
    base.ada(); ///< (2)
    base = sub;
    base.ada(); ///< (3)
}

memecpyと代入演算子(=)の役割が同じであるならば、(1)、(2)、(3)、いずれも同じ出力が得られるはずですが、実はそうなりません。(1)では"Base::hoge"が、(2)と(3)では"Sub::hoge"が出力されます。これは仮想関数を成り立たせる仕組みの仮想関数テーブル(詳細はGoogle先生『仮想関数テーブル』)がコピーされるかどうかの違いで、本来はコピーされるべきではない仮想関数テーブルまでもがmemcpyではコピーされてしまうためにおきた問題です。例で示したコードだとあまり深刻さが伝わらないですが、子クラスで定義されたメンバ変数にアクセスする仮想関数がある場合などはおかしなことが起きると思います。

他にもmemcpyを使うと問題がおこるケースがあると思いますので、結局のところ、実装したFIFOでは、memcpyを使うか、代入演算子を使うか、あるいはもっと他の方法を使うか、ファンクタで選べるようにしました。拙いコードfifo.hをおいておきます。

23:27 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/597

October 26, 2007

GPSチップアンテナ(LNA付き)

以前、sparkfunで販売されているGPSチップアンテナの記事を書きました。しかし結局パッシブアンテナ(アンプが入っていない素のままのアンテナ)の形態では、手持ちのGPS受信機u-blox LEA-4Tでは全く受からなかったので、今回はそこにアンプを足してみましたという内容です。
内容にあまり期待されてしまうと申し訳ないので、先に結論を言ってしまうと、残念ながら今回も実用にはなりませんでした。人柱レポートだと思ってくださると幸いです。

今回新たに設計したのは、前回の素のままアンテナに、LNA(Low Noise Amplifier)としてMaxim MAX2641を足したものです。例によってEagle回路図レイアウトをおいておきます。

gps_chip_antenna_brd_revC_top.gifgps_chip_antenna_brd_revC_bottom.gif
IC1がLNA。

高周波部品になると、大体の製品においてインピーダンスマッチングをとるために従うべき推奨回路というのがあります。MAX2641にも例外にもれず推奨回路があるのですが、残念ながら多くの小型GPS受信機が採用している、信号線でアンテナ内蔵アンプへの給電を行う形態には対応していなかった(DCブロックがされていない)ので、LNAの出力後のマッチング回路はスミスチャートを使って自己設計しました。その際に利用したスミスチャートをのせておきます。ちなみにこれはGSMC(GTK Smith chart caliculator)というソフトで描きました。実行環境はcygwin(X11)です。

GPS_recommended.gifGPS_redesigned.gif
推奨回路(左)と自己設計(右)。

ということで、できた物の写真をあげておきます。基板はOlimexで作りました。

gps_chip_antenna_revB_board.jpg

で、結論ですが、u-blox LEA-4Tで試してみたところ、受かりませんでした。恐らくゲインがまだまだ足りないのではないかと思います。うまく受かるアンテナのスペックをみると大体25dBを超えていますが、MAX2641 1個での性能は15.7dBなので、よりゲインの高い、例えばNEC uPC8215TU(リンク先はPDF)を使う、あるいはアンプを2段にするなどが考えられます。

断っておきますが、使用している部品に非は全くないと思います。MAX2641をはじめコンデンサやインダクタはRF対応品のまともなものを使用していますので、ひとえに設計者の能力不足が根本的な原因であることは間違いありません。あとの要因を強いてあげるとすれば、本来このような用途向けではないOlimex基板を利用していることが、それなりに影響しているのだと思います。

アマチュアではそろそろ限界なので、次回LNAをよりゲインの高いものに換えてもだめなようでしたら、この計画は諦めようと思います。たとえ諦めたとしても、最後にどこかでネットワークアナライザが借りられれば、大変有益なフィードバックが得られると思います。

※その後、Takeyasuさんにアンテナの特性を解析していただきました。

00:43 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (11) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/598

October 29, 2007

Super Sylphide 進捗状況(12) -- DSPプログラムROM化

オートパイロットシステムsuper Sylphideですが、航法(INS/GPSナビゲーション)部分がほぼ完成したので、プログラムをROM化しスタンドアローンで動作するようになりました。現在、倍精度浮動小数点(double)で、18状態量(位置で5、速度で3、姿勢で4、センサバイアスで6)、カルマンフィルタの誤差共分散行列では16 x 16のアルゴリズムが100Hzで回っています。
そこで今回は、作成したDSPプログラムをROM化する行程をまとめておこうと思います。

長くなりそうなので、トップページからこられた方を続きをどうぞ。

※その後、Super Sylphide絡みでTime Keeperのファームウェアを公開しました。

続きを読む "Super Sylphide 進捗状況(12) -- DSPプログラムROM化"
10:13 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (2) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/599