ESP32の開発環境を整える
開発規模が大きくなったので,Arduino for VSCodeからEPS-IDFに移行
逆運動学計算に時間がかかりすぎて,ゲイン下げないと振動するから複スレッドにしたい
想定読者
C++,CMake,単体テスト(gtest),git submoduleに関心がある人かな
非線形カルマンフィルタとか追加しているけど,単体テスト参照
GitHub - Libra23/robot-ws
g++でビルドすると単体テストが可能で,同じソースでesp-idfでビルドするとesp32用バイナリができる
ESP32をEPS-IDFで開発 & CMakeでのビルド
本家通りに導入,,,Macで開発環境を構築
Get Started - ESP32 - — ESP-IDF Programming Guide latest documentation
cloneしてinstall.shしておしまい.下記のコマンドを実行するとPATHにESP-IDF関連が追加される.
source ~/esp/esp-idf/export.sh
ターミナル開いて,printenvでPATHが追加されたことを確認
~/esp/esp-idf/examples/ の下にサンプルがあるので活用(やっぱりhello_world!!)
idf.py buildを使わずにCMakeでビルドしてみる
cd ~/esp/esp-idf/examples/get-started/hello_world cmake -B build -G Ninja # buildフォルダに出力makeよりNinjaの方がビルドが早いらしい ninja -C build # ninja flash # buildフォルダに移動してシリアルポートを指定してフラッシュできる
ソースフォルダのリネーム
esp-idfでは"main"フォルダ下のソースは特別扱いで,コンパイルに必要な準備をしてくれるので基本的に"main"が良さそう
ただ,ソースフォルダはsrc/,テストフォルダはtest/ にしたいので"src"にリネーム
プロジェクトトップディレクトリのCMakeLists.txtを編集
cmake_minimum_required(VERSION 3.5) set(EXTRA_COMPONENT_DIRS "./src") # srcフォルダを見てもらうようにEXTRA_COMPONENT_DIRSに追加 include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(hello-world)
srcディレクトリのCMakeLists.txtを編集
idf_component_register(SRCS "hello_world_main.cpp" INCLUDE_DIRS "." REQUIRES spi_flash) # srcフォルダだと必要な物を自分で準備する必要がある
ESP32で本家Eigen
ここからはrobot-wsレポジトリの話
Eigenをeigenとして,googletestをgtestとして追加
robot-ws/src/algorithm/math_utility.hppがEigenをIncludeしている
深いレイヤーのCMakeListから紹介
robot-ws/src/algorithm/CMakeLists.txt
# src/algorithm message("!!! src/algorithm !!!") # make library aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRCS) # directory内のソースをまとめる add_library(algorithm STATIC ${SRCS}) # ライブラリを作る target_include_directories(algorithm PUBLIC ${CMAKE_SOURCE_DIR}/src/eigen) # ライブラリに必要なファイルをincludeする
robot-ws/src/CMakeLists.txt
message("!!! src !!!") # create object idf_component_register(SRCS "app_main.cpp" INCLUDE_DIRS ".") # espのオブジェクト作成 # subdirectory add_subdirectory(algorithm) # src/algorithmのCMakeListを追加 # register library target_link_libraries(${COMPONENT_LIB} algorithm) # src/algorithm/CMakeList.txtで作成したライブラリーをリンク
topレイヤー(robot-ws/)のCMakeListはhello_worldのtopレイヤーと同じ("main"ではなく"src"を使っているので)
これでEigenが使える
GoogleTestを用いたアルゴリズムの単体テスト
これはg++で
robot-ws/testにgoogletestを追加
googletestはEigenと異なりインクルードライブラリではないので
robot-ws/test/CMakeLists.txt
# test # enable ctest enable_testing() #ctestの有効化 # subdirectory add_subdirectory(algorithm) add_subdirectory(gtest) # googletestもビルド
robot-ws/test/algorithm/CMakeLists.txt
# test/algorithm # create excute object aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRCS) add_executable(algorithm_test ${SRCS}) # link library target_link_libraries(algorithm_test algorithm gtest_main) target_include_directories(algorithm_test PUBLIC ${PROJECT_SOURCE_DIR}/src/algorithm) # make test add_test(algorithm_test algorithm_test)
適当に逆運動学の単体テスト
/** * @test check inverse kinematic */ TEST_F(KinematicTest, CheckInverseKinematic) { // prepare q Joint q_expect; q_expect << 45.0, 45.0, 45.0; q_expect *= DEG_TO_RAD; // set tip_trans Affine3d tip_trans_expect; kinematic_.Forward(q_expect, Affine3d::Identity(), tip_trans_expect); std::cout << q_expect.transpose() * RAD_TO_DEG << std::endl; std::cout << tip_trans_expect.translation().transpose() << std::endl; // check IK Joint q_standard; q_standard << 45.0, 30.0, 60.0; q_standard *= DEG_TO_RAD; Joint q_ik; bool ik_ret = kinematic_.Inverse(tip_trans_expect, Affine3d::Identity(), q_standard, q_ik); std::cout << q_ik.transpose() * RAD_TO_DEG << std::endl; for (int i = 0; i < NUM_JOINT; i++) { EXPECT_NEAR(q_expect(i), q_ik(i), TOLERANCE); } }
乱数使って回すのと,Vectorの判定関数作んないと,,,
build用コマンド
robot-ws/scriptの中にbuild用にシェルコマンド
./script/build.sh # g++用 ./script/build_esp32.sh # esp-idf用(一度実行すると実行したターミナルではパスが有効になるので上記コマンドは同じターミナルでは使えなくなる)