Open oitic-nk opened 3 years ago
@oitic-nk ありがとうございます。助かりました。
@KMiyawaki @oitic-nk
https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_01.md
It has some errors, and when you drag the robot on the Stage, the position will become meaningless.
ここが理解できなかったんですが,値が不正確ということでしょうか?不正確なのでどうすればよいか等あれば良いのですが...Or, you can use any text editor to open the python file.
Windows環境下でできるような誤解を与える可能性があるので,in the ros melodic containerと付けていただけると良いかもしれません.あるいはこの文章無くても良いかもしれません.@KMiyawaki @oitic-nk
https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_02.md
Or, you can use any text editor to open the python file.
Windows環境下でできるような誤解を与える可能性があるので,in the ros melodic containerと付けていただけると良いかもしれません.あるいはこの文章無くても良いかもしれません.@oitic-nk 小谷先生は↑の/image_mod 問題ありませんでしたでしょうか?
@igaki 先生 /image_mod の件再度動かしてみました.私の方も同じ症状ですね・・・.色々触っているうちに/depthの表示と誤認していたようです・・・. スミマセンです.
@KMiyawaki @oitic-nk 貼り付けていただいた下記コードでいけました!すぐ終了するのも改善してたので,いずれにせよコードの修正がどこか必要だったということかもしれません.ちょっとどこがまちがっていたのか調べてみます.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import rospy
import tf
from sensor_msgs.msg import LaserScan, Image
from nav_msgs.msg import Odometry
import cv2 # add
from cv_bridge import CvBridge # add
class SensorMessageGetter(object):
def __init__(self, topic, msg_type, msg_wait=1):
self.msg_wait = msg_wait
self.topic = topic
self.msg_type = msg_type
def get_msg(self):
message = None
try:
message = rospy.wait_for_message(
self.topic, self.msg_type, self.msg_wait)
except rospy.exceptions.ROSException as e:
rospy.logdebug(e)
return message
class Sensors(object):
def __init__(self):
self.laser = SensorMessageGetter("/base_scan", LaserScan)
self.odom = SensorMessageGetter("/odom", Odometry)
self.img = SensorMessageGetter("/image", Image)
# add
self.cv_bridge = CvBridge()
self.image_pub = rospy.Publisher("/image_mod", Image, queue_size=1)
def get_yaw(self, odom):
q = odom.pose.pose.orientation
(_, _, yaw) = tf.transformations.euler_from_quaternion(
[q.x, q.y, q.z, q.w])
return yaw
def process_laser(self, msg):
if msg:
rospy.loginfo("Recv sensor data. type = %s", type(msg))
# check reference
# http://docs.ros.org/api/sensor_msgs/html/msg/LaserScan.html
# len(msg.ranges) is range senseor's data count.
rospy.loginfo("len(msg.ranges) = %d", len(msg.ranges))
# msg.ranges[i] is distance mesurement of index i.
rospy.loginfo("msg.ranges[0] = %f", msg.ranges[0])
def process_odom(self, msg):
if msg:
rospy.loginfo("Recv sensor data. type = %s", type(msg))
# check reference
# http://docs.ros.org/api/nav_msgs/html/msg/Odometry.html
# msg.pose.pose.position is robot's position
rospy.loginfo("msg.pose.pose.position.x = %f, msg.pose.pose.position.y = %f",
msg.pose.pose.position.x, msg.pose.pose.position.y)
# self.get_yaw returns yaw angle from odometry data
rospy.loginfo("yaw = %f", self.get_yaw(msg))
def process_img(self, msg):
if msg:
rospy.loginfo("Recv sensor data. type = %s", type(msg))
# check reference
# http://docs.ros.org/en/api/sensor_msgs/html/msg/Image.html
rospy.loginfo("msg.width = %d, msg.height = %d",
msg.width, msg.height)
# add
try:
cv_image = self.cv_bridge.imgmsg_to_cv2(msg, "bgr8")
hsv = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)
blue = cv2.inRange(hsv, (100, 200, 200), (140, 255, 255))
send = self.cv_bridge.cv2_to_imgmsg(blue, "mono8")
self.image_pub.publish(send)
except Exception as e:
rospy.logerr("%s:%s", rospy.get_name(), str(e))
def process(self):
rate=rospy.Rate(20)
tm = rospy.Time.now()
while (rospy.Time.now().to_sec() - tm.to_sec()) < 1000:
self.process_laser(self.laser.get_msg())
self.process_odom(self.odom.get_msg())
self.process_img(self.img.get_msg())
rate.sleep()
def main():
script_name=os.path.basename(__file__)
rospy.init_node(os.path.splitext(script_name)[0])
rospy.sleep(0.5) # rospy.Time.now() returns 0, without this sleep.
node=Sensors()
rospy.loginfo("%s:Started", rospy.get_name())
node.process()
rospy.loginfo("%s:Exiting", rospy.get_name())
if __name__ == '__main__':
try:
main()
except Exception as e:
rospy.logerr("%s:%s", rospy.get_name(), str(e))
exit(1)
@KMiyawaki @oitic-nk 下記プログラムで再現できました. @oitic-nk 先生はどうでしょう? まちがってた箇所ですが,Sensorsクラスに定義すべきcv_bridgeをclass SensorMessageGetter(object):のinitでやってしまってました.資料でimportの直後のクラスのinitに追加していたので,そのままコピペしてしまっていたのが原因っぽいです. 現状の資料のままですと同じ間違いをする学生がでそうなので, cv2をimportに追加
Sensorsクラスでcv_bridgeの初期化
process_image関数で青い領域を取得する処理を追加
のように部分ごとに分けて記述するのでいかがでしょうか? あとは今のプログラムは10秒で終了します.process関数の処理を少し変更すると時間をかえられるので試してみましょう.みたいな説明を書いていただければわかりやすくなるかと思いました.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import rospy
import tf
from sensor_msgs.msg import LaserScan, Image
from nav_msgs.msg import Odometry
import cv2 # add
from cv_bridge import CvBridge # add
class SensorMessageGetter(object):
def __init__(self, topic, msg_type, msg_wait=1):
self.msg_wait = msg_wait
self.topic = topic
self.msg_type = msg_type
self.cv_bridge = CvBridge()
self.image_pub = rospy.Publisher("/image_mod", Image, queue_size=1)
def get_msg(self):
message = None
try:
message = rospy.wait_for_message(
self.topic, self.msg_type, self.msg_wait)
except rospy.exceptions.ROSException as e:
rospy.logdebug(e)
return message
class Sensors(object):
def __init__(self):
self.laser = SensorMessageGetter("/base_scan", LaserScan)
self.odom = SensorMessageGetter("/odom", Odometry)
self.img = SensorMessageGetter("/image", Image)
def get_yaw(self, odom):
q = odom.pose.pose.orientation
(_, _, yaw) = tf.transformations.euler_from_quaternion(
[q.x, q.y, q.z, q.w])
return yaw
def process_laser(self, msg):
if msg:
rospy.loginfo("Recv sensor data. type = %s", type(msg))
# check reference
# http://docs.ros.org/api/sensor_msgs/html/msg/LaserScan.html
# len(msg.ranges) is range senseor's data count.
rospy.loginfo("len(msg.ranges) = %d", len(msg.ranges))
# msg.ranges[i] is distance mesurement of index i.
rospy.loginfo("msg.ranges[0] = %f", msg.ranges[0])
def process_odom(self, msg):
if msg:
rospy.loginfo("Recv sensor data. type = %s", type(msg))
# check reference
# http://docs.ros.org/api/nav_msgs/html/msg/Odometry.html
# msg.pose.pose.position is robot's position
rospy.loginfo("msg.pose.pose.position.x = %f, msg.pose.pose.position.y = %f",
msg.pose.pose.position.x, msg.pose.pose.position.y)
# self.get_yaw returns yaw angle from odometry data
rospy.loginfo("yaw = %f", self.get_yaw(msg))
def process_img(self, msg):
if msg:
rospy.loginfo("Recv sensor data. type = %s", type(msg))
# check reference
# http://docs.ros.org/en/api/sensor_msgs/html/msg/Image.html
rospy.loginfo("msg.width = %d, msg.height = %d",
msg.width, msg.height)
try:
cv_image = self.cv_bridge.imgmsg_to_cv2(msg, "bgr8")
hsv = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)
blue = cv2.inRange(hsv, (100, 200, 200), (140, 255, 255))
send = self.cv_bridge.cv2_to_imgmsg(blue, "mono8")
self.image_pub.publish(send)
except Exception as e:
rospy.logerr("%s:%s", rospy.get_name(), str(e))
def process(self):
rate=rospy.Rate(20)
tm = rospy.Time.now()
while (rospy.Time.now().to_sec() - tm.to_sec()) < 100:
self.process_laser(self.laser.get_msg())
self.process_odom(self.odom.get_msg())
self.process_img(self.img.get_msg())
rate.sleep()
def main():
script_name=os.path.basename(__file__)
rospy.init_node(os.path.splitext(script_name)[0])
rospy.sleep(0.5) # rospy.Time.now() returns 0, without this sleep.
node=Sensors()
rospy.loginfo("%s:Started", rospy.get_name())
node.process()
rospy.loginfo("%s:Exiting", rospy.get_name())
if __name__ == '__main__':
try:
main()
except Exception as e:
rospy.logerr("%s:%s", rospy.get_name(), str(e))
exit(1)
@igaki 先生 ありがとうございます.私の方でも動作確認できました.
@igaki 対応しました。
そうですね。確かにこれは入れる場所が間違ってました。Sensor data 2に移しました。OpenCVの件は削除しました。
下記はプログラムを分割して、指示ごとにセクションを作りました。実行時間は1000秒にしました。
@KMiyawaki
https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_01.md
sensors.pyですが,まだ100秒で止まるプログラムな気がしました.1000にかえていただいて,あと,ここにコメントがあっても良いかもしれません.->すみません.2のほうでだけ変更するんですね.失礼しましたm(__)m
while (rospy.Time.now().to_sec() - tm.to_sec()) < 100:
Which value change?のあとに↓のようなのを追記いただくと,値がコロコロ切り替わって見えないという感想もなくなるかと思いました. Modify the program so that you only keep rospy.loginfo() for the values you want to focus on
Challenge(Sensor data1-1:difficult)として,
https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_02.md @KMiyawaki
Challenge (sensor data 2-1) ここなんですが,このページはExerciseがないので,これをExerciseにしていただいて,過去の資料抜粋して説明できませんでしょうか.現状だとさすがにHSVが何かとかの説明がなさすぎる気がしましたので.. https://sites.google.com/site/ipbloit/private/home/image-processing-python
あと,question1が残ってました
@igaki 対応しました。
HSVの説明も追加しました。
@KMiyawaki 紫のblockを置くのを試してみました.worldファイル書き換えるだけで追加されてびっくりしました. 使える色やposeの仕様について書いてあるページがあればと思って今探してるんですが,ご存じないでしょうか? Colorについては見つかりました.これこのままコピペしておいても親切かもしれません.コンテナ内にrgb.txtがあることも確認できました.
These colour names are from the built in X11 colour database rgb.txt. This is built in to Linux -- the file rgb.txt can normally be found at /usr/share/X11/rgb.txt assuming it's properly installed,
poseについても説明がありました. https://player-stage-manual.readthedocs.io/en/stable/WORLDFILES/#3215-ranger-device z軸を0.1とかにすると宙に浮くんですね.サクサク色々とできて楽しい感じでした. 一つ提案なんですが,以下のように課題と説明を変更してはいかがでしょうか.
あと,LayoutB~Dは別の課題で使う感じでしょうか?
@igaki 対応しました。
LayoutB以降は何も予定していません。SIGVerseの名残です。
@KMiyawaki https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_01.md 2か所ほどcolorがcolr になってました.
ちなみに本番用のLayoutはまた別なのがある感じでしょうか?何か作らないといけない等あれば手伝いますのでお声がけください.
@igaki ありがとうございます。修正しました。 特に新たなmapを作成することは考えていません。 今回は事前学習で使い慣れたものをお使いいただくのが良いのではないでしょうか。
サンプルを一通り実行しましたが,特に気になる点はありませんでした.