oit-ipbl / robots

0 stars 0 forks source link

Sensor data (1)(2)について #4

Open oitic-nk opened 3 years ago

oitic-nk commented 3 years ago

サンプルを一通り実行しましたが,特に気になる点はありませんでした.

KMiyawaki commented 3 years ago

@oitic-nk ありがとうございます。助かりました。

igaki commented 3 years ago

@KMiyawaki @oitic-nk

https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_01.md

Laser Range Finder

Wheel odometry

Exercise

Run

Question(1)

Question(2)

Challenge(1)

igaki commented 3 years ago

@KMiyawaki @oitic-nk

https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_02.md

Exercise

Run

igaki commented 3 years ago

@oitic-nk 小谷先生は↑の/image_mod 問題ありませんでしたでしょうか?

oitic-nk commented 3 years ago

@igaki 先生 /image_mod の件再度動かしてみました.私の方も同じ症状ですね・・・.色々触っているうちに/depthの表示と誤認していたようです・・・. スミマセンです.

igaki commented 3 years ago

@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)
igaki commented 3 years ago

@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)
oitic-nk commented 3 years ago

@igaki 先生 ありがとうございます.私の方でも動作確認できました.

KMiyawaki commented 3 years ago

@igaki 対応しました。

Laser Range Finder

Wheel odometry

Exercise

Run

Question(1)

Question(2)

Challenge(1)

そうですね。確かにこれは入れる場所が間違ってました。Sensor data 2に移しました。OpenCVの件は削除しました。

Sensor data 2

下記はプログラムを分割して、指示ごとにセクションを作りました。実行時間は1000秒にしました。

igaki commented 3 years ago

@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)として,

igaki commented 3 years ago

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が残ってました

KMiyawaki commented 3 years ago

@igaki 対応しました。

HSVの説明も追加しました。

igaki commented 3 years ago

@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は別の課題で使う感じでしょうか?

KMiyawaki commented 3 years ago

@igaki 対応しました。

LayoutB以降は何も予定していません。SIGVerseの名残です。

igaki commented 3 years ago

@KMiyawaki https://github.com/oit-ipbl/robots/blob/main/sensor_data/sensor_data_01.md 2か所ほどcolorがcolr になってました.

ちなみに本番用のLayoutはまた別なのがある感じでしょうか?何か作らないといけない等あれば手伝いますのでお声がけください.

KMiyawaki commented 3 years ago

@igaki ありがとうございます。修正しました。 特に新たなmapを作成することは考えていません。 今回は事前学習で使い慣れたものをお使いいただくのが良いのではないでしょうか。