🚗

AutowareでLSPの準備をする

に公開

きっかけ

諸々あって、自動運転関係の勉強をしなければならず、TIER IVのautowareの勉強を始めようとしているんですが、最近の自分はAIの力を借りなければ無知のコードを読めない体質になってしまったので、

https://zenn.dev/coffeecupjp/articles/89bb2b40ced6eb

https://marketplace.visualstudio.com/items?itemName=coffeecupjapan.cpp-reader

autowareのコードベース1つを読むのにも、LSPの設定が必要になっていました。
ただ、autowareのLSP設定の記事が、

https://autowarefoundation.gitlab.io/autoware.auto/AutowareAuto/ide-specific-configuration.html

くらいしかなく、ここに書いている

colcon build --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=1

でLSPの設定をしても、compile_commands.jsonの設定が上手くいかないことが多かったので、後にautowareをLSPを使って読みたい人向けに、autowareでのLSPの設定方法を残します。

autowareとは?

Autoware Foundation が主導する自動運転ソフトウェアの世界最大級OSS(オープンソース) が Autoware です。
日本発で、研究用途から実車・商用運用までを想定した、実務寄りの自動運転スタックとして位置づけられています。

一言で言うと、ROS 2を基盤にした、モジュラー型(分割設計)の自動運転ソフトウェアスタックになっていて、以下が主な特徴になります。

  • センサ入力から車両制御までを 明確に分割
  • 実運用・安全・説明責任を重視
  • End-to-Endではなく Pipeline / Modular設計

なぜautowareでLSPが必要なのか?

Autowareのコードは難しいので、基本的にAIと一緒にコードを読むことになると思います。その時にAIにコンテキストを与えすぎずに最小限のコンテキストだけ渡すための役割分担として使うのが、LSPです。
もちろん、LSPなしでCursorやCopilotのchat機能でコードを読むことができますが、一回のクエリでトークンが数十万トークンとか使いたくない時などには、以下のVSCode拡張機能が使えると思います(今回はC++なので、C++ですがJava, C, Rubyなどもあります)。

https://marketplace.visualstudio.com/items?itemName=coffeecupjapan.cpp-reader

autowareでLSPを設定する方法

では、本題のautowareでLSPを設定する方法を見てみましょう。
最初の方は、

https://autowarefoundation.github.io/autoware-documentation/main/installation/autoware/source-installation/

を参考にしています。

  1. autowareのレポジトリをクローンし、VSCodeでautowareレポジトリを開く
git clone https://github.com/autowarefoundation/autoware.git
cd autoware
code . # vscodeで開く
  1. 「dev Containers」のVSCode拡張機能をインストールします

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers

  1. VSCodeで「Command + Shift + p」でコマンドパレットを開き、「Dev Containers: Reopen in Container」を押し、「autoware:core-devel」を開きます。

  2. dockerのビルドなどが終わると、新しい画面でautowareのコードベースが改めて表示されます。こちらdocker内の環境になるので、基本的にLinux環境になります。

  3. 以下のコマンドをうち、環境変数を読み込みます

./setup-dev-env.sh
  1. 以下のコマンドをうち、autoware全体のレポジトリをダウンロードします
cd /workspaces/autoware
mkdir -p src
vcs import src < repositories/autoware.repos
  1. ROSのパッケージをダウンロードします
source /opt/ros/humble/setup.bash
# Make sure all previously installed ros-$ROS_DISTRO-* packages are upgraded to their latest version
sudo apt update && sudo apt upgrade
rosdep update
rosdep install -y --from-paths src --ignore-src --rosdistro $ROS_DISTRO
  1. dockerデスクトップの設定で、CPU Limitを8以上・Memory Limitを15GB以上にします

  1. 注意 ここはドキュメントの方法と異なるので、注意してください。特にメモリが16GBまでしかない人は注意 ここでは、一回ビルドをして、compile_commands.jsonを生成します。作り方は以下のコマンドになります。
# 一回普通にビルドする。メモリ16GBだと、コケがちですが、コケたら最初からやり直してください。キャッシュは残っています
colcon build --symlink-install \
  --executor sequential \
  --cmake-args \
    -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  --cmake-force-configure
# 1度ビルドに成功したら、並列でビルドします。これでビルドしないと、compile_commands.jsonが正しくないような気がします
colcon build --symlink-install \
    --cmake-args \
    -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo
  1. build配下にcompile_commands.jsonが生成されるのですが、このままだと上手くいかないこともあります。ので、以下のスクリプトを走らせます(dockerにnodeは入っていないならローカルからnodeを動かして生成してください)。このコードでは、compile_commands.jsonのcommandをargumentsに変えています。
fixArguments.js
import fs from "fs/promises";
import shellQuote from "shell-quote";

function commandToArguments(command) {
  return shellQuote.parse(command).filter(x => typeof x === "string");
}

async function readAndEditFile() {
  try {
    const content = await fs.readFile("./compile_commands.json", "utf-8");
    const commands = JSON.parse(content);
    for (const entry of commands) {
      const args = commandToArguments(entry.command);
      entry.command = undefined;
      entry.arguments = args;
    }
    await fs.writeFile("./compile_commands_arg2.json", JSON.stringify(commands, null, 2));
  } catch(e) {
    console.error(e);
    return;
  }
}

readAndEditFile();
mkdir node
cp fixArguments.js node/fixArguments.js
cp build/compile_commands.json node/compile_commands.json
cd node
npm init -y
npm i shell-quote
node fixArguments.js # これでcompile_commands_arg2.jsonが生成される
  1. ここで生成された「compile_commands_arg2.json」の以下の行をすべて消します
      "-fopenmp",
  1. ここまででできた「compile_commands_arg2.json」を「/workspaces/autoware」配下にある「compile_commands.json」に置き換えます。

  2. ここまでできたら、clangdを入れて、お好きなC++のVSCode拡張機能を使います。するとclangdが「build」配下に.cacheディレクトリを作り、キャッシュを生成すると思うので、それを確認します。

clangdのインストール
sudo wget https://apt.llvm.org/llvm.sh
sudo chmod +x llvm.sh
sudo ./llvm.sh 20

私が使っているVSCode拡張機能。

https://marketplace.visualstudio.com/items?itemName=coffeecupjapan.cpp-reader

最後に

何か間違っている部分があったら、教えてください。

Discussion