Skip to main content

Posts

Showing posts from March, 2020

LiDAR Localization

LiDAR で検知したものを高精度地図上のものとマッチさせる。 マッチさせるアルゴリズムは複数あるが、そのうちの一つが Iterative closest point(ICP) approach 。 物体のそれぞれのポイントについて、距離の平均誤差が小さくなるように回転や Translate( ? ) させる Filter approach は別のやり方。 Apollo では Histogram Filter approach をとっている。 これは Sum of Squared Difference(SSD) とも呼ばれる。 違いの値がより小さい点が中心点。 Kalman filter もまた他の approach 。 このアプローチでは、前回値と次の地点の予測値を使う。 LiDAR による Localization の強みは Robustness 。地図とセンサーがあればいつでもローカライズ可能。 ただし弱点もある。高精度地図とセンサーに頼っているが、地図を常に最深化することは難しい。 また、一時的にしか存在しない要素 ( 歩行者や車など ) や道路の封鎖なども発生する。

Localizationの話

GPS は通常 1-3m の誤差、建物や山などでは 10-50m もの誤差が発生することもある 高精度地図と自車との位置を照らして、その位置の差を地図上の座標にマップする 自車座標は常に Plus の値をとる (X が前、 Y が左 ) 位置を知るには、少なくとも 3 点のランドマークとそれらへの自車からの距離を知る必要がある。 (Triangulation,  三角測量 ) 1 箇所ではあるランドマークの周囲が全て候補に、 2 箇所では交差する 2 点が候補になってしまうため。 ただし、これは 2D の話で 3D の場合はさらにもう一つないと高度で外してしまうかもしれない。 GPS はアメリカの作ったもの。この種のシステムのことを Global Navigation Satellite System(GNSS) という。 (GPS は GNSS の中で最も使われているシステム ) GPS は 3 つの要素からなる。サテライト、コントロールステーション、 GPS レシーバー。 距離は光の速さ x レシーバーまでの時間となる、が、光の速さは 3x10^8 なので、少しの誤差で大きく値がずれてしまう。そのためすべてのサテライトはかなり正確な原子時計を持っている。 また、この誤差を減らすために Real Time Kinematic(RTK) positioning を使用する。 これは、地上の基地局が GPS の電波を受け取り自身の位置を測定、そして Ground Truth と呼ばれる当該基地局が既に知っている自身の位置との差異を求め、ここで求めた差異の分を他のレシーバーに伝えることで、他のレシーバーの誤差を修正する役割を持つ。 これにより比較的正確な位置 (10cm 未満程度 ) を測定することはできるようになったが、それでも、障害物がある場所や郊外では不正確になる問題、そして位置の更新頻度が低い (10Hz / 10 times per sec) Inertial Navigation 。現在地がわかって、速度 ( 加速度 ) がわかって、その上で道が直線だったら時間 t の後に位置している場所もわかるという話。 ではどれくらいの加速度かをどのように測るか。 一つは例えばジャイロスコープで測

OpenShiftでのサービスカタログへの表示

TL;DR: openshift ネームスペースのテンプレートに追加するだけ kind: Template にした上で Image Stream 等々を指定。プレースホルダーを使うこともできる。 parameters を用意して画面から入力させることができる。 /tmp/src  下に Git のリポジトリを配置するのが通常 assemble と run というスクリプトを埋め込む。 GUI 上で Start Build すれば assemble が、そして起動のタイミングで run が動く buildConfig の from で imageStream から取得、作ったら to への指定で出力 ただしセキュリティ準拠の甘いコンテナを動かす場合には苦労がある。 runasuser を更新する必要あり。 USERID を指定する。

JMCとJFR

JFR の可視化には JMC と GraalVM が使える。 GraalVM の方が全体感を掴んだりスレッドの中での動き、メソッドにかかっている時間を追っていくのはやりやすい印象。 他方で、 JMC では JFR での記録中に把握したものを診断結果のような形で出してくれたり、 JMC ・ JFR 中に稼働していた他のプロセスの影響などを出してくれるのでこちらも非常に便利。 また、 JMC では Deprecated になったフラグを使っていると、そのフラグについての警告を出してくれるのも魅力の一つに思う。

JFRのDumpをGraalVMで可視化する

JFRのDumpをGraalVMで確認する。 どうやらJMXでコンテナ内のアプリに直接繋いで云々というのはちょっと通常やることではない雰囲気を覚えた。 で、だとしてもパフォーマンスチューニングはしたい。 となれば、JFRの記録をとって、それをなんらかの方法で可視化すれば良いということになる。 JFRの記録の方は簡単。 おなじみjpsでプロセス番号を調べて(e.g. 6798)、 jcmd 6798 JFR.start とする。 そして、 jcmd 6798 JFR . dump name= 1 filename= dump .jfr なんてやればその時点までの記録がファイルに残る。 問題は可視化の方法で、以前にJFRをローカルで動かして、そのプロセスに対してGraalVMが接続してなんらか確認、なんてことはした。 で、ローカルファイルの場合は?というのが今回のお題。 結論としてはこちらも簡単だった。プラグインインストールが必要という点だけわかれば後は簡単。 次の記事を参考に、GraalVMを起動後、Toolから”VisualVM-JFR”と”VisualVM-JFR-Generic”を選ぶ。 JDK Flight Recorder Support in VisualVM - graalvm - Medium  https://medium.com/graalvm/jfr-support-in-visualvm-62fddd4f0795 これでインストールが完了して再起動をかけると、左にJFR Snapshotsと出るようになるのでダブルクリックで開いて先ほど記録したJFRのファイルを読み込ませてあげれば良い。 (ブログ記事を流し読みした時、え、手元のGraalVMにはJFR Snapshotsなんてないんだけど……とちょっと焦った) ちなみに、拡張子は.jfrでないと選べない。この記録を残している時、まさにまんまとjfr.dumpなんて名前で記録していたものだから選べなくてrenameを強いられた。

QuarkusとJMX

Quarkusで有効になっているこのポートの正体はなんだろう。 8080/tcp, 8778/tcp, 9779/tcp Quarkus(Javaの超高速Webアプリフレームワーク)では、コンテナで動かす際に特に気にせずに公式がサンプルで出してくるfabric8のイメージを使っていると、アプリの8080ポートの他に8778、9779のポートも待ち受けている。 パフォーマンスチューニングするのに、ローカルで動かしているものを測定することはもちろんできるのだけど、本番環境でリモート接続して測定できないかなと思い改めてこれらのポートを確認してみた。 まず、8778は Jolokia  https://jolokia.org/  だった。 Jolokia is remote JMX with JSON over HTTP.と公式には書いてある。 要するに直接リモートのJMXを繋がせるのではなく、HTTP経由かつJSONによる応答形式でJMXに繋いだときに得られる応答を返す代物。 これがあるとファイアウォールのようなプロトコル等に制約のある環境下でも使いやすいかもね、なんて話も公式サイトに書いてあった。 それから、9779は Prometheusの JMX Exporter  https://github.com/prometheus/jmx_exporter  だった。 要はPrometheusで見れるようにするエージェントの1つ。 これもJolokiaと同じくHTTP経由でのアクセスをできるようにしてくれる。 どちらを使いたいかは環境次第だと思うけれど(個人的な経験からするとPrometheusからの方が見れるイメージがすぐに思い浮かんだ)、 どちらにせよJMXそのものを公開するのではなくてHTTP且つエージェントを経由して公開しようという流れなのがわかった。 上記の2つのツールはどちらもHTTPSにも対応させることができるし認証の設定をすることもできる様子。 今回はとりあえずPrometheusで見れるようにしてみた。 と言っても、ほとんどPrometheusの経験がないので、とりあえず、という感じだけれど。 普段自分のアプリはdocker composeで動かしているので、次のようにしてPrometheusのイメージをアプリのネットワーク内で動かす。 こうすることで、

Rust 1.41

PodcastでRust 1.41について聞いた。 Rustは触り始めたばかりだから全然わからないことだらけだけど、もうすぐMacの32bitマシン向けのサポートが終わるってことはわかった。 rust 1.41で入った機能があったらしいが忘れてしまった。ただ、良さげな機能だったので rustup updateでアップデートする。 プロジェクトごとにバージョンが異なる状況では次のようにすれば使用バージョンを変えられるっぽい。 rustup override set 1 .30 .0 ちなみに、以前からある機能だけど、cargo docでは使用している依存関係なども全て表示できる。 しかもその画面で各依存先の使用例などもみれる。これはすごい。

Javaパフォーマンスチューニング3

パフォーマンスチューニングの続編。Java Performance 2nd Editionより。 ・パフォーマンス測定時の注意 パフォーマンス測定時にはランダムサンプルとフラグサンプル(任意の箇所にフラグを指定して測定)がある。 (ところでその分類によると、任意の間隔、例えば100ms周期、という指定はランダムにあたるのだろうか、フラグにあたるのだろうか) どちらにせよサンプリングエラーは発生してしまうが、特にフラグサンプルの場合、適切なフラグを付けないと、本当に改善すべき点が見えず、実際とは異なる結果が測定されてしまう蓋然性が高まる。 ・改善対象の選定 JDKやJVMそのものを書き換えないと改善できないところに注力してしまうことがないように注意する必要がある。 ・測定結果の可視化 オープンソースの async-profiler project を使用すればどのメソッドがCPU時間をどれほど使っているかがボトムアップでわかる ・Sampling Profiler と Instrumented Profiler Instrumented profilers(日本語訳はなんだろう)は読み込まれるバイトコードの変更することで様々な計測ができるようになるもの 。 Sampling Profilerでまずはざっくりとみて、そこからInstrumented Profilerでドリルダウンしていくと良いらしい その他、Native profilerではgcの可視化なども見れるのでgcの時間が長かったらgcタイミングをチューニングする ・メソッドやスレッドの時系列確認ツール どのメソッドやスレッドでブロックが発生してしまっているかを見る。 jvisualvm を使用すると良い(Instrumented Profilersに該当するらしい) そのほか、Oracle Developer Studio profiling toolで使えるthread timeline chartだとブロッキングが可視化できる ・JFRによる記録とJMCによる確認 OpenJdk11, OracleJDdk8から同梱されているツールであるJava Flight Recorder(JFR)。 JVM上で発生したイベントを確認することで事後の分析を実現する。 ここで記録したJFRの記録はJava Missio

OpenShiftで認証の必要なレジストリのイメージを使う

認証が必要なレジストリからのcontainerのpull方法。 oc get secret default -us-icr-io -o yaml -n default これを保存して、保存したファイル名に対して oc create -f deploy .yaml ここで、namespaceを自身の指定したprojectに変更する必要あり 変更後、GUIからdeploymentを作成(“Deploy Image”)、Image Nameで指定、 結果としてPodsを見るとImage Pullに失敗しているので、 DeploymentをEdit、Imagesのadvanced image optionsを選ぶ その後Pull Secretに先ほど作ったSecretを指定すると、今度はImage Pullに失敗しなくなっている ファイルのマウントについては、 Resouces > Config MapsからConfig Mapを作る Nameは表示名、KeyはUniqueにする必要あり、Valueをマウントしたいファイルアップロード そして作成後にAdd to Application でアプリを選んでVolume指定 ただし、ファイルだとそのままマウントできないので、 指定完了後にdeploymentへいってから Edit YAML, spec > containers > image > volumeMountsのところに次のように追加(application.propertiesを差し込むケース) subPath : application .properties OpenShiftになっても、Kubernetesで必要だったYAML系の対応はやはり必要なのね。ないよりは遥かに楽になっているけれど。

自動運転の基礎

Udacityの自動運転の入門コースの続き。 このコースにおいては、Mapは次の3つを含む。 - Localization - Perception - Path Planning OpenDRIVEフォーマット=高精度なマップを共有するためのフォーマット Apollo OpenDRIVEとStandard OpenDRIVEでは一部に違いがある。 例えばStandard DRIVEではScenarioをシミュレーションに適用するが、Apolloだとそれをより現実的なレベルの自動運転のシーンに適用するらしい。 Mapの生成は5つのプロセスからなる - Data Sourcing(道路情報など) - Data Processing(Point Cloudの登録や地点登録等々) - Object Detection(物体の認識やPoint Cloudの分類) - Manual Verification(レーンや信号仮想のレーンなどにより確認) - Map Products(HD MapやLocalization Map、Point Cloud Mapなどを作る) Self-Driving Fundamentals: Featuring Apollo | Udacity  https://www.udacity.com/course/self-driving-car-fundamentals-featuring-apollo--ud0419 レーダー・ライダーの話が少し出たので改めて検索しなおしたそれぞれの違い。 「ミリ波レーダー」はミリ波、「LiDAR」は赤外線を使う。 同じ電波でも、ミリ波と赤外線では波長が違う。 ミリ波は波長が長く、赤外線は波長が短い。 波長が長い=障害物を迂回できるが画素数が低い 波長が短い=近距離を高画素で捉える このページが分かりやすかった。 【初心者向け】カメラ、ミリ波レーダー、LiDAR(ライダー)の違いと自動運転レベルの定義|ぷんたむの悟りの書  https://punhundon-lifeshift.com/autonomous_driving

雨の日をハレにする

憂鬱な湿った空気 朝起きて、目が覚めて、雨模様の空を見るとガッカリする。 特に、子持ちである自分の立場では、この天気の時点で行き先がかなり限定され、他にも行き先が限定された人たちで溢れたそのそれぞれの場所は、湿気でムワッとしていて、それを想像すると、より一層鬱屈な気持ちにさせられる。 多分、同じ気持ちの子持ちの人は、少なくないのではないかと思っている。 水の中の砂 そんな様相に、近頃我が家では変化が起きた。 妻が子供のために、長靴とレインコートを買ったのだった。 我が子は、かけてあるレインコートを見ては「今日はこれ、着ていく?」と問いかけてくる。 もちろん、毎度答えはNoだったのだけど、この雨の日、今日ばかりは違う。 おろしたてのレインコートと少しぶかぶかの長靴を身に纏ってはしゃぐ。 自分だけ傘があってはなんなので、同じくレインコートをかぶって一緒にでかける。 水たまりを見つけると、初めは恐る恐るだったけれども、2つ、3つと飛び込むうちに楽しくなって、 道行く先にあるあらゆる水に飛び込んではしゃいでいた。 これだけ楽しそうに過ごしているのだから、買った甲斐があったというものだと思う。 この一連のジャンプして水たまりに飛び込む様子の中で、水の中にある砂の動きに少しワクワクした。 飛び込んだ瞬間にふわっ、と砂が水の中に広がって、その後にしゅーーーっと散って、落ち着いていく。 水たまりをわざと踏む大人なんてそうそういないから、そんな素敵な瞬間を見る機会はずっとなかった。面白い発見だったなあ。 昔に人伝に聞いた、横浜ランドマークタワーを紹介する係の方の話を思い出す。 雨の日の展望台は眺めがいつもと違い、一面雲に覆われて下界が見えない。がっかりする人も、多い。 少し不正確かもしれないけれど、その係の人が 「ランドマークタワーから雲を見下ろす体験ができるのは、雨の日にここに登ってこられた皆様だけです」 といった趣旨の話をしてくれたのだとか。 雨の日に登った体験が、そのおかげで途端に特別なものに感じたんだ、といったトーンでその話は締め括られていた覚えがある。 雨の日を「ハレ」の日にできる、そんな魔法を秘めている。 そして多分、この長靴とレインコートも同じよ