0
1

More than 1 year has passed since last update.

ROSの開発環境でflaskのrender_templateを使う

Last updated at Posted at 2022-11-25

簡単ではあるが、地味に記事がない内容だったので、まとめておく

動作環境

項目 説明
OS Ubuntu 20.04.05 LTS
ROSディストリビューション noetic
Flask 2.2.2
Python3 3.9.14

ROSでflaskを使う

参考サイト

手順

$ catkin_make
$ source devel/setup.bash

を使用した後、新たなプロジェクトとして

$ cd src
$ catkin_create_pkg ros_flask_test

として、ros_flask_testというプロジェクトを作成。

ros_flask_test内は、(例えばVisual Studio Codeを使うとして)
以下のフォルダ構成とする

Screenshot from 2022-11-25 15-42-12.png

flask_server.pyはinit_nodeとしてros_flask_testを、
ローカルホストでポート番号を11000として使うとすると

flask_server.py
import rospy
import threading
from flask import Flask

app = Flask(__name__)  
    
threading.Thread(target=lambda: rospy.init_node('ros_flask_test', disable_signals=True)).start()

@app.route('/')
def root_page():
  return "Hello World"

if __name__ == '__main__':    
  app.run(debug=True, port=11000)

このプログラムでは使わないが、some_page.htmlとして

some_page.html
<html>
<body>
Test Page
</body>
</html>

CMakelists.txt

CMakelists.txt
cmake_minimum_required(VERSION 3.0.2)
project(ros_flask_test)

find_package(catkin REQUIRED)

catkin_package(
)

include_directories(
)

catkin_install_python(
  PROGRAMS
  scripts/flask_server.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

として、プロジェクトより上のフォルダに移動して

$ catkin_make

とすることで、ビルド完了。

$ rosrun ros_flask_test flask_server.py

を実行することで、

Screenshot from 2022-11-25 15-45-31.png

ちゃんとサーバが実行され、

Screenshot from 2022-11-25 15-46-01.png

Hello Worldが表示された。

この方法はWeb APIの方法に近いと思われる。

ROS(開発環境)でrender_templateを使いたい

上手く行かない例

素直に、先程のflask_server.pyを拡張する。

flask_server.py
import rospy
import threading
from flask import Flask, render_template

app = Flask(__name__)  
print(app.root_path)            # ここをチェックする
    
threading.Thread(target=lambda: rospy.init_node('ros_flask_test', disable_signals=True)).start()

@app.route('/')
def root_page():
  return "Hello World"

@app.route('/some_page')
def some_page():
  return render_template("some_page.html")

if __name__ == '__main__':    
  app.run(debug=True, port=11000)

つまり、

http://127.0.0.1:5000/some_page

を開けば、some_page.htmlがレンダリングされて表示されるはず。シンプルな内容だ。

ところが、これを実行すると

Screenshot from 2022-11-25 15-49-40.png

TemplateNotFoundエラーが出る。

まあ、通常のflaskであれば、このディレクトリ構成で良いのだが、
要はディレクトリが良くないわけだ。

改善

というわけで、# ここをチェックするの行で出てきたprintで何が出てきたかを調べると、

〜(rospyを実行しているディレクトリ)/devel/lib/ros_flask_test

となっていることが分かる。

そして、確かによく見てみると

Screenshot from 2022-11-25 15-53-07.png

devel/libフォルダにもpyファイルがあるのだ。

ただここは開発環境用の自動スクリプトであるから、
ここを編集して、というわけにはいかない。

そこで、flaskのroot_pathを常に変えられるように実行する。

ros_flank_testのフォルダの下にlaunchフォルダを作成し、
local_html_render.launchというファイルをとりあえず作る(何でも良い)。

local_html_render.launch
<launch>
    <node pkg="ros_flask_test" type="flask_server.py" 
          name="flask_server" respawn="true" output="screen">
        <param name="flask_root_path" value="$(find ros_flask_test)/scripts/" />
    </node>
</launch>

とし、

flask_server.pyを

flask_server.py
import rospy
import threading
from flask import Flask, render_template
import rosparam

root_path = rosparam.get_param("/flask_server/flask_root_path")
if root_path != "":
    app = Flask(__name__, root_path=root_path)
else:
    app = Flask(__name__)    
    
threading.Thread(target=lambda: rospy.init_node('ros_flask_test', disable_signals=True)).start()

@app.route('/')
def root_page():
  return "Hello World"

@app.route('/some_page')
def some_page():
  return render_template("some_page.html")

if __name__ == '__main__':    
  app.run(debug=True, port=11000)

という風に書き換える。つまり、launchファイルを先に用意しておいて、ローカルファイルのtemplatesフォルダをバインド出来るようにするのだ。

そして、実行方法はrosrunではなく、roslaunchを使用して

$ roslaunch ros_flask_test local_html_render.launch

とすることで、きちんと実行されたことを確認した。

Screenshot from 2022-11-25 16-00-59.png

なお、上記のプログラムの場合、もしlocalフォルダを指定しない場合は、

のvalueを"" とすれば良い。
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1