October 07, 20072007 八ヶ岳
[Mountain]
八ヶ岳に行ってきました。快晴で最高でした。 八ヶ岳に行ったのは2年ぶり5回目なんですが、行く度にいい山だと改めて思います。
また初体験といえば、美濃戸~新宿間の直行バスを帰りに使ってみました。2年前から運行が開始したそうで、毎日新聞が企画しています。こちらも快適でした。 October 15, 2007Super Sylphide 進捗状況(11) -- Time Keeperつい先日大きな出張が完了したので、オートパイロットシステムSuper Sylphideをサクっと完成させてしまおうと考えています。そのような中、とある試験をGPSが使用不能な環境下で行うことになりそうなので、それに備えた準備をすることになりました。そこで問題となったのが、こちらのオートパイロットシステムで取得したデータと、他のシステムのデータの同期をとるという作業です。 GPSの一般的な使い方であるカーナビなどではあまり取り上げられることがないのですが、実はGPSは手軽な高精度時計として利用することが可能です。詳しい話は専門書に譲りますが、GPSが現在位置を出力する原理は、人工衛星から放出されたGPS電波が地上に到達するまでの時間を計測することから成り立っています。つまり時間や時刻を管理する時計の精度は、GPSの性能を決定する非常に重要なファクターです。実際、GPSの電波を放出している人工衛星には非常に高価な原子時計が何台も搭載されています。そういうわけでGPSは手軽な高精度時計として使用することができます。 今まではGPSが利用可能であったので、気軽に他のシステムによって取得されたデータと同期をとることができました。特に現在使用中のGPSモジュール LEA-4Tは1秒単位のパルス信号(1pps)が取り出せるので、時刻同期用の時計としても重宝していました。ところが今回はGPSが利用できないので、代替手段を考えなければいけません。
使い方はSuper Sylphideにおいて、GPSが載ったボード、並びにそれからの出力を受けとるボードとの間に、このTime Keeperを挿入します。Time Keeperは、GPSが利用可能な間は先ほどの1ppsをそのまま出力します。GPSが使用不能になった場合はTime Keeper内蔵のReal Time Clock (RTC)に切り替えて、1ppsを継続出力します。主電源が落ちてもRTCの動作は保証できるよう、バックアップ電源としてスーパーキャパシタを搭載しました。 例によって現時点でのEagleのファイル(回路図、レイアウト)を置いておきます。マイコン兼RTCとしてSilicon LaboratoriesのC8051F410を使っていますが、まだファームウェアは書いていません。 ※その後、本体の航法プログラムのROM化が完了しました。 October 21, 2007memcpyによるクラスのコピー
[Computer]
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{ memecpyと代入演算子(=)の役割が同じであるならば、(1)、(2)、(3)、いずれも同じ出力が得られるはずですが、実はそうなりません。(1)では"Base::hoge"が、(2)と(3)では"Sub::hoge"が出力されます。これは仮想関数を成り立たせる仕組みの仮想関数テーブル(詳細はGoogle先生『仮想関数テーブル』)がコピーされるかどうかの違いで、本来はコピーされるべきではない仮想関数テーブルまでもがmemcpyではコピーされてしまうためにおきた問題です。例で示したコードだとあまり深刻さが伝わらないですが、子クラスで定義されたメンバ変数にアクセスする仮想関数がある場合などはおかしなことが起きると思います。 他にもmemcpyを使うと問題がおこるケースがあると思いますので、結局のところ、実装したFIFOでは、memcpyを使うか、代入演算子を使うか、あるいはもっと他の方法を使うか、ファンクタで選べるようにしました。拙いコードfifo.hをおいておきます。 October 26, 2007GPSチップアンテナ(LNA付き)以前、sparkfunで販売されているGPSチップアンテナの記事を書きました。しかし結局パッシブアンテナ(アンプが入っていない素のままのアンテナ)の形態では、手持ちのGPS受信機u-blox LEA-4Tでは全く受からなかったので、今回はそこにアンプを足してみましたという内容です。 今回新たに設計したのは、前回の素のままアンテナに、LNA(Low Noise Amplifier)としてMaxim MAX2641を足したものです。例によってEagleの回路図とレイアウトをおいておきます。
高周波部品になると、大体の製品においてインピーダンスマッチングをとるために従うべき推奨回路というのがあります。MAX2641にも例外にもれず推奨回路があるのですが、残念ながら多くの小型GPS受信機が採用している、信号線でアンテナ内蔵アンプへの給電を行う形態には対応していなかった(DCブロックがされていない)ので、LNAの出力後のマッチング回路はスミスチャートを使って自己設計しました。その際に利用したスミスチャートをのせておきます。ちなみにこれはGSMC(GTK Smith chart caliculator)というソフトで描きました。実行環境はcygwin(X11)です。 ということで、できた物の写真をあげておきます。基板はOlimexで作りました。 で、結論ですが、u-blox LEA-4Tで試してみたところ、受かりませんでした。恐らくゲインがまだまだ足りないのではないかと思います。うまく受かるアンテナのスペックをみると大体25dBを超えていますが、MAX2641 1個での性能は15.7dBなので、よりゲインの高い、例えばNEC uPC8215TU(リンク先はPDF)を使う、あるいはアンプを2段にするなどが考えられます。 断っておきますが、使用している部品に非は全くないと思います。MAX2641をはじめコンデンサやインダクタはRF対応品のまともなものを使用していますので、ひとえに設計者の能力不足が根本的な原因であることは間違いありません。あとの要因を強いてあげるとすれば、本来このような用途向けではないOlimex基板を利用していることが、それなりに影響しているのだと思います。 アマチュアではそろそろ限界なので、次回LNAをよりゲインの高いものに換えてもだめなようでしたら、この計画は諦めようと思います。たとえ諦めたとしても、最後にどこかでネットワークアナライザが借りられれば、大変有益なフィードバックが得られると思います。 ※その後、Takeyasuさんにアンテナの特性を解析していただきました。 October 29, 2007Super Sylphide 進捗状況(12) -- DSPプログラムROM化オートパイロットシステムsuper Sylphideですが、航法(INS/GPSナビゲーション)部分がほぼ完成したので、プログラムをROM化しスタンドアローンで動作するようになりました。現在、倍精度浮動小数点(double)で、18状態量(位置で5、速度で3、姿勢で4、センサバイアスで6)、カルマンフィルタの誤差共分散行列では16 x 16のアルゴリズムが100Hzで回っています。 長くなりそうなので、トップページからこられた方を続きをどうぞ。 ※その後、Super Sylphide絡みでTime Keeperのファームウェアを公開しました。 続きを読む "Super Sylphide 進捗状況(12) -- DSPプログラムROM化" |
かれんだ~
スポンサード リンク
|