色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用RealSense D455的空間識別操作myCobot

大象機器人科技 ? 來源:大象機器人科技 ? 作者:大象機器人科技 ? 2023-04-12 11:53 ? 次閱讀

1. 簡介

先進技術部門正在研究多模態強化學習,包括相機圖像和觸覺傳感器。除其他外,要實現所謂的Sim2Real,其中模擬器中的強化學習結果也在實際機器上運行,必須協作操作真實機器的機械臂和相機。因此,在這種情況下,我們使用ROS測試了鏈接的6軸機械臂myCobot(由大象機器人制造)和深度攝像頭RealSense D455(由英特爾制造),流程和結果將在下面詳細描述。

操作環境:

PC:Ubuntu 20.04, ROS NoeticPython 3.8.10

機械臂:myCobot280 M5Stack

深度攝像頭:實感D455

這篇博客描述了如何創建和運行一個簡單的程序,但我假設 ROS 和 Python 環境已經設置好了。

poYBAGQ2J6iAJPebAALtq2GNO1k394.png

2. 我的協作機器人基礎知識

首先,準備myCobot,但我有點困惑,因為由于固件更新等原因,某些部件在使用中發生了變化。這項工作是在 2021 年 3 月左右完成的,當時 myStudio 版本是 1.3.<>。我認為不會有任何重大變化,但如果您看到不同之處,請參閱官方說明。

運行myCobot需要以下三個準備工作。

● 更新固件(基本,原子)

● 機械臂關節校準

● 機械臂與PC機之間的串行通信

更新固件

myCobot 280 M5在底座上有一個M5Stack Basic,在機械臂的末端有一個ATOM(Basic,ATOM),用于將固件寫入這兩個模塊。

首先,使用 USB 連接到 PC,并使用 chmod 允許讀取和寫入設備。此外,對于Windows或Mac上的USB串行通信,需要安裝特殊的驅動程序。

$ sudo chmod 666 /dev/ttyUSB*

接下來,下載更新的固件應用程序-myStudio(在撰寫本文時,最新版本是3.1.4,但僅適用于Windows,3.1.3可用于Linux)。

提取源代碼并執行 AppImage 后,它將分別啟動 Basic 和 ATOM。如圖 1 和圖 2 所示。

poYBAGQ2J8-AK45nAADAaEcwGgg152.pngpoYBAGQ2J-CAY_IIAADEU5JERRU574.png

在myStudio 3.1.3中,將出現如圖3和圖4所示的屏幕,然后下載最新版本的Minirobot for Basic和AtomMain for ATOM,選擇Flash,然后寫入固件。使用Basic完成寫入后,迷你機器人的輸出將顯示在面板上。(請注意,如果您不使用Basic和ATOM編寫最新版本,則機器人手臂可能無法正常工作)。

poYBAGQ2J_KAa7tVAAEA0ihYglo800.pngpYYBAGQ2J_KAd711AAChsZu3BAI573.png

更新固件后,下一步是校準接頭角度。

接頭角度校準

首先,在“基本”面板中選擇“校準”,然后按“確定”。

myCobot 的每個接頭都有一個代表原點的凹口,如圖 5 所示,因此凹口是手動相互對齊的。

poYBAGQ2KAeACuVrAAEu_BLd76c865.png

在此狀態下,在“基本”面板中選擇“校準伺服”,然后按“下一步”完成校準。運行測試伺服將允許電機圍繞凹口稍微旋轉以確認正確校準。

機械臂和PC之間的串行通信

最后,當您啟動應答器時,您可以通過串行通信從PC操作myCobot。這很容易做到,只需在“基本”面板中選擇應答器,然后按“確定”。然后顯示屏將顯示如圖6所示,按基本按鈕。

pYYBAGQ2KB2AaUPRAAGuO0k32H0119.png

在“基本”面板的其他菜單中,“基本”中的“主控制”控制 ATOM,“信息”檢查每個關節是否正確連接。當myCobot在PC上無法正常工作時,您可以檢查myCobot本身是否存在問題。

3. 蟒蛇接口

準備完成后,我們可以在PC上操作myCobot。這次,我嘗試了使用 pymycobot 從 python 腳本進行操作的方法,以及使用 mycobot_moveit 庫從 ROS 操作 MoveIt 的方法 。

首先,安裝pymycobot。

$ pip install pymycobot --upgrade

您也可以從 Github 下載安裝源代碼。

從源代碼下載時,示例腳本包含在測試目錄中。但是,它不會按原樣工作,因此請小心。我做了下面的例子,而不是重寫。

# mycobot_control_test.py#!/usr/bin/env pythonimport time from pymycobot.mycobot import MyCobotfrom pymycobot.genre import Angle, Coord if __name__ == "__main__":port = "/dev/ttyUSB0"mycobot = MyCobot(port, baudrate="115200", timeout=0.1, debug=False) #After the baud rate are the default values #Get the operation of the joint angleprint("get angles")print(" degrees: {}n".format(mycobot.get_angles()))time.sleep(0.5) print("get radians")print(" radians: {}n".format(mycobot.get_radians()))time.sleep(0.5) print("send angles: [0, 0, 0, 0, -90, 0]")mycobot.send_angles([0, 0, 0, 0, 0, 0], 80)time.sleep(1.5)mycobot.send_angles([0, 0, 0, 0, -90, 0], 80)print(" Is moving: {}n".format(mycobot.is_moving()))time.sleep(1.5) print("send radians: [0, 0, 0, 0, 1.57, 0]n")mycobot.send_radians([0, 0, 0, 0, 1.57, 0], 80)time.sleep(1.5) print("send angle to joint 4: -90n")mycobot.send_angle(Angle.J4.value, -90, 80)time.sleep(1.5) # Operations to get coordinatesprint("get coordination")print(" coordination {}n".format(mycobot.get_coords()))time.sleep(0.5) print("send coordination: [50, 50, 300, 0, 0, 0] → [50, 50, 300, 90, 90, 0]n")coord_list = [50, 50, 300, 0, 0, 0]mycobot.send_coords(coord_lis, 70, 0)time.sleep(3.0)coord_list = [50, 50, 300, 90, 90, 0]mycobot.send_coords(coord_lis ,70, 0)time.sleep(1.5) # Scenarios using grippers# print("open gripper")# mycobot.set_gripper_state(0,0)# time.sleep(1.0)# print("close gripper")# mycobot.set_gripper_state(1,80)# time.sleep(1.0) time.sleep(1.5)print("release all servos")mycobot.release_all_servos()

運行mycobot_control_test.py文件

$ python3 mycobot_control_test.py

在 mycobot 模塊中創建 MyCobot 類的實例,并使用 getter 和 setter 來檢查和更改狀態。

創建實例

mycobot = MyCobot(port, baudrate="115200", timeout=0.1, debug=False)

設置四個參數。在波特率之后輸入默認值。端口是 USB 串行通信端口。您可以通過在終端中運行ls / dev /來查看連接到PC的設備列表。在Linux中,如果沒有其他用于串行通信的USB端口,它將是/ dev / ttyUSB0。我認為Mac和Windows是不同的,所以相應地檢查。

關于吸氣劑

get_angles ( ) 和 get_radians () 是獲取關節角度(以度和弧度為單位)的函數。返回值是六個關節角度值的列表。

還有一個get_coords( )函數,它獲取以底底中心為原點的坐標系*中手臂尖端的坐標。返回值是一個 6 維列表,其中包含尖端的 x、y、z 坐標 (mm) 和方向 rx、ry、rz(角度)。在沒有 MoveIt 的情況下實現反向運動學真是太好了。

*坐標系:以“基本”面板為背面,每個正方向分別為 x:向前、y:向左和 z:向上。請注意,MoveIt 中的向量略有不同,稍后將對此進行介紹。

關于二傳手

以度和弧度為單位發送關節角的函數是send_angles ( )send_radians ( ),并且具有兩種類型的參數設置。

首先,在指定并發送所有 6 個關節時,第一個參數與 getter 相同,在列表類型中放入 6 個浮點值,第二個參數中輸入關節運動的速度 *(int: 0 ~ 100)。

mycobot .send_angles ( [ 0 , 0 , 0 , 0 , 0 , 0 ] , 80 )

接下來,您取關節的角度并發送它。請將關節角度的代碼放在第一個參數中,角度值放在第二個參數中,速度放在第三個參數中。

mycobot .send_angle ( Angle.J4.value , -90,80 )

也可以通過像getter這樣的坐標來操作。在這種情況下,放置了 6 個元素的列表 [x, y, z, rx, ry, rz],第一個參數是協調的,第二個參數是速度,第三個參數是模式。模式有兩種類型,0:角度和1:線性

mycobot .send_coords ( [ [ 80 , 50 , 300 , 0 , 90 , 0 ] , 70 , 0 )

由于源代碼中沒有詳細說明速度單位,因此我認為您在必要時對其進行測量。

其他接口

一旦機械臂移動,電機將繼續施加扭矩以試圖保持當前狀態,因此如果保持原樣,電機將過載。因此,讓我們在操作完成后使用函數release_all_servos(y)釋放電機扭矩。

如果機器人手臂正在運行,并且您指示它執行另一個操作,則會發生錯誤,它將繼續執行下一個操作。在示例腳本中,python內置函數time.sleep()用于等待每個動作完成,但您可以使用函數is_moving()來獲取電機是否正在運行,以便您可以循環while等。(我認為這個函數是錯誤,并返回一個不斷移動的狀態。

還有一些其他 API 可用于打開和關閉電源、更改 LED 的顏色以及檢查電機狀態,但這次我省略了它們,因為目標是移動手臂。

4. 只讀標準

接下來,在ROS中使用MoveIt來操縱myCobot。

大象機器人實現mycobot的動作它可以安裝并可以安裝

有一個MoveIt的志愿者實現,我決定使用它。安裝是根據上面的 GitHub 自述文件編寫的。

$ cd /src$ git clone https://github.com/Tiryoh/mycobot_ros$ git clone https://github.com/nisshan-x/mycobot_moveit$ rosdep update$ rosdep install -i –from-paths mycobot_moveit$ cd .$ catkin_make #Set up work area$ source devel/setup.bash

完成安裝和設置工作區后

$ roslaunch mycobot_moveit mycobot_moveit_control.launch

MoveIt 和 Rviz GUI 將啟動,如圖 7 所示。通過拖放綠色球,計算出機器人手臂末端位置的姿勢,然后按下左下角的計劃和執行按鈕,Rviz 與實際機器人一起移動。

poYBAGQ2KGuANI26AAEq_Kz09bM257.png

* 當模型和實際機器不能一起工作時

我不知道這是否是所有環境中都會發生的錯誤,并且模型和真實機器并不總是協同工作。這是電機旋轉方向反轉時發生的錯誤,所以有點棘手,但請將模型與真機進行比較,尋找相反方向的關節旋轉。

確認有多少關節沿相反方向旋轉后,重寫描述機器人模型的 URDF 文件。

/ src / mycobot_moveit / urdf / mycobot_urdf_gazebo.urdf

定義的聯合信息的說明如下。

mycobot_urdf_gazebo.urdf ~~                                                  ~~

Arm1 ~ arm6_joint 相同的說明。旋轉軸的方向設置為<軸xyz = “0 0 1”> ,并且設置1→-1反轉關節在相反方向上的旋轉。

在我的環境中,似乎除了第三個關節之外的所有關節都是反轉的。我不知道這是因為機器人舵機的個體差異還是其他原因,如果您知道,請告訴我。

這就是它的全部內容,從myCobot設置到操作基礎。

5. 現實D455基礎知識

這次我用D455進行了測試,但基本上D400系列可以以相同的方式使用。只有D435i和D455內置了IMU傳感器,但本文沒有用到(因為誤差累積的缺點比在固定狀態下使用IMU的優點更明顯)。除了帶有紅外立體攝像頭的D400系列外,還有帶有LiDAR的L515,但用途相同。另外,我認為新的性能最好,所以我會買D455。我認為最好在購買前咨詢一下您想使用的環境,因為有一些零件(以前的型號基本上是向后兼容的,所以在價格和性能之間有一個權衡)。

查看器的軟件安裝和基本操作

安裝庫 librealsense 以運行實感。 沒有這個,后面將描述的realsense_ros將無法工作。有一個關于如何在 Linux 上安裝它的文檔。如果需要,Windows 上的安裝方法也位于同一文檔庫中。

# Server Public Key Registration$ sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE||  Adding a Repository$ sudo add-apt-repository “deb https://librealsense.intel.com/Debian/apt- repo $(lsb_release -cs) main” -u# install lib$ sudo apt install librealsense2-dkms librealsense2- utils# install dev$ sudo apt install librealsense2-dev librealsense2-dbg

安裝完成后,在終端中運行實感查看器進行查看。如果它不起作用,請嘗試拔下并插入實感 USB 連接并重新啟動 PC。如果啟動成功,將顯示查看器,如圖 8 所示。

pYYBAGQ2KIeAfQuFAAGZ0uP2B4Y672.png

您可以使用右上角的 2D | 3D 按鈕在 2D 和 3D 之間切換查看器。此外,您可以通過打開左側的立體模塊和RGB攝像頭來查看深度信息和RGB信息。在 2D 中,您可以在 2D 中查看 RGB 和深度信息。在3D中,由深度估計紅外立體相機估計的點云用深度彩色圖和RGB相機信息著色,可以從各個角度查看。此外,內置 IMU 傳感器的 D435i 和 D455 還可以通過運動模塊獲取姿態信息。接下來,我們來看看使用 ROS 包realsense_ros的 Rviz 點云。這可以使用 apt 安裝。

$ sudo apt install ros-$ROS_DISTRO-realsense2-camera

實感攝像頭在第一個終端啟動,除了每個攝像頭的信息外,還提供彩色點云,在第二個終端上啟動 Rviz 進行可視化。

$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$rviz

為了如圖 9 所示查看點云,我們將使用 GUI 來調整設置。

首先,由于左側顯示面板中的全局選項固定框是地圖,請單擊它并將其更改為camera_link。

然后按顯示面板底部的添加按鈕,將彈出一個新窗口,列出可以在 Rviz 中顯示的 ROS 消息類型。選擇 rviz 組中間的 PointCloud2,然后按 OK 將 PointCloud2 添加到顯示面板。

此外,如果您單擊組中“主題”列右側的空白并選擇出現的 /camera/depth/color/points,則點云將顯示在 Rviz 上。默認情況下,點云大小設置為 0.01 m,這是一個很大的值,因此點云相互重疊顯示,但如果將其設置為 0.001 m 左右,您可以看到點云的獲取非常精細。

此外,如果從“添加”中選擇“TF”并添加它,則可以顯示攝像機位置和方向(軸向)。默認情況下,RGB 相機原點和立體相機原點分別顯示在世界坐標系和光學坐標系中。(camera_link似乎與立體相機起源相同)

poYBAGQ2KKaAabX-AAGBumAgPrg138.png

保存設置,因為很難每次都彈出此按鈕。

在工作區中創建目錄配置以保存設置,在 Rviz 的文件中選擇將配置另存為,命名創建的配置目錄并保存。

$ rviz -d .rviz

如果您更改了某些內容,則可以每次通過保存配置更新相同的文件。如果您只是查看點云和相機位置,您可以使用realsense_viewer輕松做到這一點但您可以使用 ROS 來處理原始數據。從這里開始就像是理解 ROS 消息數據含義的練習。

(但是,就個人而言,這是一個很大的絆腳石)

執行rs_camera.launch過濾器后:=點云

讓我們看一下 從另一個終端發送的 /camera/depth/color/points 主題的原始數據。

$ rostopic echo /camera/depth/color/points

當然這個值數組是點云數據,它應該用 xyz 坐標和位置中的 RGB 值表示,但很難直接讀取。如果您查看數字,您會發現每個值都在 0 到 255 的范圍內,并且類似的值以常規模式定期出現。但是,從這里猜測 x 代表哪里以及紅色代表哪里是不合理的。

因此,首先,找出此消息的類型。

$ rostopic type /camera/depth/color/pointssensor_msgs/PointCloud2

我們現在知道消息類型是 sensor_msgs/PointCloud2。

另外,如果您從 ROS 文檔中查看它,您可以看到如下內容。

Header header # header uint32 height # number of rows of datauint32 width # Number of columns of dataPointField[] fields # 1 point data structurebool is_bigendian # whether the big enduint32 point_step # number of bytes in a point (number of 8-bit numbers)uint32 row_step # number of data in a row (= width * point_step)uint8[] data # raw data (8bit row_step * height data array)bool is_dense # if true, then no invalid data

既然是點云,那么與2D圖像不同,數據的順序有什么意義?正如問題所暗示的那樣,高度和寬度似乎沒有意義。

目前尚不清楚持有可以從其他值計算并且不太可能使用的變量意味著什么,但結構是這樣的。如果要查看每個的實際值,

$ rostopic echo /camera/depth/color/points/

通過執行此操作,您只能在數據中輸出一個變量。例如,顯示回point_step和字段給出。

$ rostopic echo /camera/depth/color/points/point_step–20—$ rostopic echo /camera/depth/color/points/fields–name: “x”offset: 0datatype: 7count: 1–name: “y”offset: 4datatype: 7count: 1–name: “z”offset: 8datatype: 7count: 1–name: “rgb”offset: 16datatype: 7count: 1—

輸出將是 由于 point_step = 20,您可以看到一個點的數據由 20 個字節表示,您可以從字段的內容中看到這 20 個字節是如何組成的。

每個變量的含義是

名稱:要表示的數據的名稱

偏移量:對應的字節

數據類型:所表示數據的類型代碼

計數:包含的數據項數

例如,x 坐標對應于從 0 到 3 的數據,類型代碼為 7(對應于 float32),表示數據。 y 和 z 應該以相同的方式處理,但 RGB 也以相同的方式表示。當我查看與 RGB 對應的第 16 個到第 19 個值時,有 GBRA 順序的十六進制值。到 float32 的轉換似乎很難處理,因此似乎需要單獨處理 xyz 坐標和 RGB。

現在我們知道了如何表示數據,讓我們實際處理它。

(我認為有一個更智能,更快捷的方法來處理下一個腳本,所以如果你有任何建議,請)

將腳本目錄添加到mycobot_test包中,并在其中添加 python 腳本。

$ cd /src/mycobot_test$ mkdir scripts$ cd scripts$ touch red_point_detection.py$ touch object_position_search.py

將依賴項添加到 CMakeLists.txt 并打包.xml。

# CMakeLists.txtfind_package(catkin REQUIRED COMPONENTS # Add rospy and sensor_msgs modules to be able to import     rospy sensor_msgs ) catkin_package( # Add build package     sensor_msgs ) # Add scripts to the executable directory catkin_install_python(PROGRAMS    DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}/scripts )Python    rospy   sensor_msgs     rospy   sensor_msgs

以下red_point_detection.py是一個腳本,它僅從點云中提取紅色并創建新消息。

#!/usr/bin/env python3 import time, os, sys, signal, threading import numpy as np import rospy from sensor_msgs.msg import PointCloud2  class RedPointsDetectionNode(object):     def __init__(self):         super(RedPointsDetectionNode, self).__init__()         self.data = PointCloud2()         self.point_step = 20         self.R_COL = 18         self.G_COL = 17         self.B_COL = 16         rospy.init_node("red_points_detection_node")         rospy.loginfo("red points detection start")      # Subscriber             def sub_pointcloud(self):         def callback(data):             self.sub_data = data         sub = rospy.Subscriber("camera/depth/color/points", PointCloud2, callback = callback)         rospy.spin()      # Publisher     def pub_red_pointcloud(self):         pub = rospy.Publisher("red_point_cloud", PointCloud2, queue_size = 1)         while not rospy.is_shutdown():             pub_data = self.red_point_detection(self.sub_data)             pub.publish(pub_data)                  def red_point_detection(sub_data):             red_point_data = sub_data             red_pointcloud = np.array([d for d in sub_data.data]).reshape(-1, self.point_step)             r_flags = red_pointcloud < 180             g_flags = red_pointcloud > 150             b_flags = red_pointcloud > 150             R_under_threshold_row = np.where(r_flags)[0][np.where(np.where(r_flags)[1]==self.R_COL)]             G_over_threshold_row = np.where(g_flags)[0][np.where(np.where(g_flags)[1]==self.G_COL)]             B_over_threshold_row = np.where(b_flags)[0][np.where(np.where(b_flags)[1]==self.B_COL)]             not_red_row = np.unique(np.concatenate([R_under_threshold_row, G_over_threshold_row, B_over_threshold_row]))              red_pointcloud = np.delete(red_pointcloud, not_red_row, axis=0).ravel().tolist()             red_point_data.width = int(len(red_pointcloud) / self.point_step)             red_point_data.height = 1             red_point_data.row_step = pub_pc2_data.width * self.point_step             red_point_data.data = red_pointcloud             rospy.loginfo("red pointcloud {}".format(int(len(red_pointcloud) / self.point_step)))             return red_point_data          # node start to subscribe and publish     def start_node(self):         sub_pointcloud = threading.Thread(target = self.sub_pointcloud)         pub_red_pointcloud = threading.Thread(target = self.pub_red_pointcloud)          sub_pointcloud.setDaemon(True)         sub_pointcloud.start()         pub_red_pointcloud.setDaemon(True)         pub_red_pointcloud.start()          sub_pointcloud.join()         pub_red_pointcloud.join()  if __name__ == "__main__":     color_points_detector = ColorPointsDetectionNode()     color_points_detector.start_node()     pass

訂閱者讀取相機/深度/顏色/點數據,發布者僅從數據中提取紅點并分發它們。處理紅點以從原始點云中刪除 RGB 值為f R < 180、G > 150 和 B > 150 的點。使用HSV比RGB更好,RGB容易受到照明條件的影響,但是這次在處理PointCloud2數據時很難轉換為HSV,因此被擱置了。如果是C++,使用 PCL 似乎很容易進行 python 轉換,但對于 python 來說毫無用處,因為很難編寫其他過程)。

寫入后,將其移動到工作區,catkin_make并執行它。

$ roslaunch realsense2_camera rs_camera.launch filters:=pointcloud$ rosrun mycobot_test red_point_detection.py$ rviz -d .rviz

如果在 Rviz 中選擇添加到 PointCloud2 消息中的 /red_point_cloud,則可以看到提取的點云,如圖 10 所示。

poYBAGQ2KMeACo0YAACloKJJ-gA740.png

object_position_search.py是一個腳本,用于查找提取的紅點坐標的平均值。

# object_position_search.py#!/usr/bin/env python3 import time, os, sys, signal, threading  import numpy as np  import rospy from sensor_msgs.msg import PointCloud2 import sensor_msgs.point_cloud2 as pc2 from geometry_msgs.msg import Point  class ObjectPositionSearchNode(object):     def __init__(self):         super(ObjectPositionSearchNode, self).__init__()         rospy.init_node("object_position_search_node")         rospy.loginfo("object position search start")         self.object_position = Point()      # Subscriber             def sub_pointcloud(self):         def callback(data):             rospy.loginfo("subscribed pointcloud")             xyz_generator = pc2.read_points(data, field_names = ("x", "y", "z"), skip_nans=True)             xyz_list = [gen for gen in xyz_generator]             list_num = len(xyz_list)             x = np.array([xyz_list[i][0] for i in range(list_num) if (xyz_list[i][2] < 1.0 and xyz_list[i][2] > -1.0)])             y = np.array([xyz_list[i][1] for i in range(list_num) if (xyz_list[i][2] < 1.0 and xyz_list[i][2] > -1.0)])             z = np.array([xyz_list[i][2] for i in range(list_num) if (xyz_list[i][2] < 1.0 and xyz_list[i][2] > -1.0)])                          self.object_position.x = np.average(x)             self.object_position.y = np.average(y)             self.object_position.z = np.average(z)          sub = rospy.Subscriber("red_point_cloud", PointCloud2, callback = callback)         rospy.spin()          # Publisher     def pub_target_position(self):         pub = rospy.Publisher("object_position", Point, queue_size=1)         while not rospy.is_shutdown():             rospy.loginfo("published object position: {:.5f}, {:.5f}, {:.5f}n".format(self.object_position.x, self.object_position.y, self.object_position.z))             pub.publish(self.object_position)             def start_node(self):         sub_pointcloud = threading.Thread(target = self.sub_pointcloud)         pub_target_position = threading.Thread(target = self.pub_target_position)          sub_pointcloud.setDaemon(True)         sub_pointcloud.start()         pub_target_position.setDaemon(True)         pub_target_position.start()          sub_pointcloud.join()         pub_target_position.join()  if __name__ == "__main__":     object_position_searcher = ObjectPositionSearchNode()     object_position_searcher.start_node()     pass

在之前運行red_point_search.py的情況下,啟動一個新終端并運行它。

$ rosrun mycobot_test object_position_search.py

它取red_point_cloud坐標值的平均值 并分布它們,同時記錄這些值。坐標以米為單位,此腳本檢索 1.0 米內的點。由于使用 rospy.loginfo 獲得的坐標被記錄下來,因此坐標被輸出到終端。

sensor_msgs庫中有一個point_cloud2模塊,用于處理和讀取 PointCloud2 數據,將坐標值從 4Byte 轉換為 float32。內容很簡單,但我很難理解這個模塊的存在。如果您有其他復雜的消息數據,最好查看是否有隨附的處理模塊。這是真正意義上的設置和數據處理。關于數據處理,我認為您仍然需要找到更快處理(或改進算法)的方法,具體取決于應用程序。

6. 使用 ROS 將 myCobot 連接到實感 D455

現在實感數據處理已經完成,我想將其與myCobot結合使用。因此,最重要的是從實感相機坐標系到myCobot坐標系的轉換。Rviz 上有一個 TF(變換)顯示相機軸,但您需要了解這一點。顧名思義,它描述了描述一個坐標系與另一個坐標系之間關系的坐標變換。首先,讓我們看看如果未設置此 TF 會發生什么情況。

$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$ roslaunch mycobot_moveit mycobot_moveit_control.launch

然后,您將在 Rviz 顯示面板中看到一條警告,如圖 11 所示。消息是相機的每個坐標系都沒有變換到base_link(myCobot的起源)。

poYBAGQ2KOuABbq1AAJCLNilvWE999.png

因此,讓我們創建一個包,將 TF(坐標變換)從相機廣播到 myCobot。很抱歉在C++和Python之間來回,但這次我將使用roscpp。首先創建一個包。

$ cd /src$ catkin_create_pkg tf_broadcaster roscpp$ cd tf_broadcaster$ touch src/tf_broadcaster.cpp

重寫生成的tf_broadcaster.cpp CMakeLists.txt、package.xml如下所示。請注意,C++文件是一個類,因為它是為了練習在類中創建節點而創建的,但可以更輕松地編寫。

// tf_broadcaster.cpp#include  #include  #include  #include   class TfBroadcaster { public:     TfBroadcaster();     ~TfBroadcaster(); // Broadcast     void BroadcastStaticTfFromCameraToMyCobot();  private:     ros::NodeHandle nh_; // TF Broadcaster     tf2_ros::StaticTransformBroadcaster static_tf_broadcaster_; // constant     double PI_ = 3.1419265; };  TfBroadcaster::TfBroadcaster(){} TfBroadcaster::~TfBroadcaster(){}  void TfMyCobotBroadcaster::BroadcastStaticTfFromCameraToMyCobot() {     geometry_msgs::TransformStamped transformStamped;     transformStamped.header.stamp = ros::Time::now();     transformStamped.header.frame_id = "camera_color_frame"; //link     transformStamped.child_frame_id = "base_link";     // son link   // Parallel movement     transformStamped.transform.translation.x = -0.3;     transformStamped.transform.translation.y = -0.3;     transformStamped.transform.translation.z = -0.3;     // Turning back         tf2::Quaternion q;     q.setEuler(0, 0, 0);     transformStamped.transform.rotation.x = q.x();     transformStamped.transform.rotation.y = q.y();     transformStamped.transform.rotation.z = q.z();     transformStamped.transform.rotation.w = q.w();          static_tf_broadcaster_.sendTransform(transformStamped);     }  int main(int argc, char** argv) {     ros::init(argc, argv, "tf_mycobot_broadcaster");     TfMyCobotBroadcaster tf_mycobot_broadcaster;     tf_mycobot_broadcaster.BroadcastStaticTfFromCameraToMyCobot();      ros::Rate loop_rate(10);     while(ros::ok()){         ros::spinOnce();         loop_rate.sleep();     }     return 0; }# CMakeLists.txtcmake_minimum_required(VERSION 3.0.2) project(tf_broadcaster) find_package(catkin REQUIRED COMPONENTS   roscpp geometry_msgs tf2_geometry_msgs) catkin_package( CATKIN_DEPENDS geometry_msgs tf2_geometry_msgs) include_directories(${catkin_INCLUDE_DIRS}) add_executable(tf_mycobot_broadcaster src/tf_mycobot_broadcaster.cpp) target_link_libraries(tf_mycobot_broadcaster ${catkin_LIBRARIES})      tf_broadcaster    0.0.0   The transform broadcaster package   root   TODO    catkin   tf2_geometry_msgs   geometry_msgs 

如您所見,我們設置 transformStamped 類的實例變量并廣播該實例。廣播變量類型是tf2_ros::StaticTransformBroadcaster,但這次我們使用靜態TF,因為攝像機和機器人的位置是固定的。對于那些感興趣的人,當職位關系隨時間變化時,也可以使用動態 TF。

在這里,位置關系還不知道,所以值是暫時的,但我們可以組成顯示,所以讓我們嘗試一下。此外,父鏈接camera_color_frame而不是camera_link,因為父鏈接的原點與點云坐標系匹配。 catkin_make后,像以前一樣運行 rs_camera.launch 和 mycobot_moveit_control.launch,并在另一個終端中運行tf_broadcaster。

$ rosrun tf_broadcaster tf_broadcaster

這將廣播成像儀和myCobot base_link之間的位置關系,因此TF警告消失。如果在此狀態下添加點云,它將如圖 12 所示。當然,相機和myCobot之間的位置關系是暫時的,因此相機看到的myCobot位置與Rviz中顯示的模型位置不重疊。

poYBAGQ2KQ-AERHLAAFnFwJ3nc0793.png

因此,接下來我們將校準從相機中看到的機器人的相對姿勢和位置。

我認為還有另一種通過將相機固定在特定位置來指定位置關系的方法,但是這次我們標記三個點以確定機器人坐標,我們通過找到單位向量并相對于相機坐標系進行計算來校準位置關系。

你們中的一些人可能已經注意到,之前的照片是在已經連接標記的情況下拍攝的,但標記的放置方式如圖 13 所示。

poYBAGQ2KSCANOXYAACWVLSgMI8100.png

口糧標記

myCobot 的原點(底部中心)位于標記 2 和 3 的中點,標記 1 垂直于該原點的線段 2 和 3。

1.首先,重寫red_point_detection.py并創建blue_point_detection.py以獲得藍色標記的點云。此處省略了該腳本,因為它只是重寫了要提取的 RGB 范圍。之后,我認為有多種方法可以從那里獲得坐標轉換,但這次是通過以下過程獲得的。確定標記坐標 訂閱標記點云

一個。將點云聚類為三個(通過 k 均值方法)

2. 確定原點和單位向量 標記 2 和 3 的中點是原點V_robot

一個。X 和 Y 的單位向量V_X和V_Y分別V_robot →標記 1、V_robot →標記 2。

b.Z 的單位向量是帶有標記的平面和法線向量的叉積

3. 使用歐拉角創建從相機姿勢到機器人姿勢的旋轉 theta_1 = 相機相對于水平面的仰角

a.theta_2 = 朝向相機前方的旋轉角度

b.theta_3 = 相機與機器人前方方向之間的角度

4. 將 V-Z 方向的原點轉換為 myCobot 的固定底座(2.7 厘米)

* 歐拉旋轉開始的軸是任意的,因此結果會因所使用的庫而異。(我認為不是每個人都費心這樣做,所以我想知道您是否傳遞單位向量和兩個坐標系的原點,如果有一些庫將其轉換為 TF。

以下腳本將添加到腳本目錄中。

# mycobot_position_calibration.py#!/usr/bin/env python3 import time, os, sys, signal, threading  import numpy as np  import rospy from sensor_msgs.msg import PointCloud2 from geometry_msgs.msg import Point import sensor_msgs.point_cloud2 as pc2  class MyCobotPositionCalibrationNode(object):     def __init__(self):         super(MyCobotPositionCalibrationNode, self).__init__()         rospy.init_node("mycobot_position_calibration_node")         rospy.loginfo("mycobot position calibration start")      # Subscriber             def sub_pointcloud(self):         def callback(data):             self.data = data             rospy.loginfo("subscribed pointcloud")             xyz_generator = pc2.read_points(self.data, field_names = ("x", "y", "z"), skip_nans=True)             xyz_list = [xyz for xyz in xyz_generator if (abs(xyz[0]) < 0.8 and abs(xyz[1]) < 0.8 and abs(xyz[2]) < 0.8)]             xyz_array = np.array(xyz_list)              if len(xyz_list) > 3:                 marker_centroids = self.kmeans(3, xyz_array)                 rospy.loginfo("n marker positionsn{}".format(marker_centroids))                 translation = self.cal_translation(marker_centroids)                 rospy.loginfo("n translationn{}".format(translation))                          sub = rospy.Subscriber("blue_point_cloud", PointCloud2, callback = callback)         rospy.spin()      # node start     def start_node(self):         sub_pointcloud = threading.Thread(target = self.sub_pointcloud)         sub_pointcloud.setDaemon(True)         sub_pointcloud.start()         sub_pointcloud.join()          # clustering method     def kmeans(self, k, X, max_iter=30): # k: cluster num, X: numpy array         data_size, n_features = X.shape         centroids = X[np.random.choice(data_size, k)]         new_centroids = np.zeros((k, n_features))         cluster = np.zeros(data_size)         for epoch in range(max_iter):             for i in range(data_size):                 distances = np.sum((centroids - X[i]) ** 2, axis=1)                 cluster[i] = np.argsort(distances)[0]             for j in range(k):                 new_centroids[j] = X[cluster==j].mean(axis=0)             if np.sum(new_centroids == centroids) == k:                 break             centroids = new_centroids         max_norm = 0         min_norm = 0         sorted_centroids = []         for centroid in centroids:             norm = centroid[2]             if norm > max_norm:                 sorted_centroids.append(centroid)                 max_norm = norm                 if min_norm == 0:                     min_norm = sorted_centroids[0][2]             else:                 if norm > min_norm and min_norm != 0:                     sorted_centroids.insert(1, centroid)                 else:                     sorted_centroids.insert(0, centroid)                     min_norm = norm         sorted_centroids = np.array(sorted_centroids)          return sorted_centroids      # translation angles calculation     ## calculation     def cal_translation(self, marker_points):         # マーカー1, 2, 3の位置ベクトル         #Position vector of marker 1, 2, 3         a_1, a_2, a_3 = marker_points         # カメラからロボットへのベクトル         #Vector from camera to robot         V_robot = self.cal_robot_position_vector(a_2, a_3)         # ロボットのXYZ単位ベクトル         #XYZ unit vector of the robot         V_X = (a_2 - V_robot) / (np.linalg.norm(a_2 - V_robot))         V_Y = (a_1 - V_robot) / (np.linalg.norm(a_1 - V_robot))         V_Z = self.cal_normal_vector(marker_points)          # カメラの水平面に対する仰角         # Elevation angle of the camera relative to the horizontal plane         theta_1 = - (np.pi/2 - self.cal_subtended_angle(-V_robot, V_Z))         # カメラの正面方向の回転角         #Rotation angle of the camera in the frontal direction        V_Y_camera = np.array([0, 1, 0])         V_Y_camera_rotated = self.cal_rotate_vector_xaxis(V_Y_camera, -theta_1)         theta_2 = - self.cal_subtended_angle(V_Z, -V_Y_camera_rotated)         # カメラとロボットのそれぞれの正面方向とのなす角         #Angle between the camera and the respective frontal direction of the robot         _, V_robot_projected_to_plane = self.cal_vector_projection(V_robot, V_Z)         theta_3 = self.cal_subtended_angle(V_Y, V_robot_projected_to_plane)         # mycobotの位置を土臺の高さ0.027 m, V_Z方向に平行移動         # mycobot position at foundation height 0.027 m, parallel to V_Z direction         V_robot = V_robot + 0.027*V_Z          return V_robot, theta_1, theta_2, theta_3       ## vector and angle caluculation     def cal_robot_position_vector(self, a_2, a_3):         return (a_2 + a_3) / 2      def cal_normal_vector(self, marker_points):         a_1 = marker_points[0]         a_2 = marker_points[1]         a_3 = marker_points[2]         A_12 = a_2 - a_1         A_13 = a_3 - a_1         cross = np.cross(A_13, A_12)         return cross / np.linalg.norm(cross)      def cal_subtended_angle(self, vec_1, vec_2):         dot = np.dot(vec_1, vec_2)         norm_1 = np.linalg.norm(vec_1)         norm_2 = np.linalg.norm(vec_2)         return np.arccos( dot / (norm_1 * norm_2) )          def cal_vector_projection(self, org_vec, normal_vec):         # org_vec: 射影したいベクトル         # org_vec: the vector you want to project                 # normal_vec: 射影したい平面の法線ベクトル          # normal_vec: Normal vector of the plane to be projected                projected_to_vertical = np.dot(org_vec, normal_vec) * normal_vec         projected_to_horizontal = org_vec + projected_to_vertical         return projected_to_vertical, projected_to_horizontal      def cal_rotate_vector_xaxis(self, vec, angle):         rotate_mat = np.array([[1, 0, 0], [0, np.cos(angle), np.sin(angle)], [0, -np.sin(angle), np.cos(angle)]])         return vec.dot(rotate_mat)      def cal_rotate_vector_yaxis(self, vec, angle):         rotate_mat = np.array([[np.cos(angle), 0, -np.sin(angle)], [0, 1, 0], [np.sin(angle), 0, np.cos(angle)]])         return vec.dot(rotate_mat)      def cal_rotate_vector_zaxis(self, vec, angle):         rotate_mat = np.array([[np.cos(angle), np.sin(angle), 0], [-np.sin(angle), np.cos(angle), 0], [0, 0, 1]])         return vec.dot(rotate_mat)  if __name__ == "__main__":     mycobot_position_calibrator = MyCobotPositionCalibrationNode()     mycobot_position_calibrator.start_node()      pass

這次我們從最近的marker_1設置相機和機器人,根據它們的位置關系marker_2和marker_3,但需要注意的是,需要根據相機的位置進行調整。

構建完成后,相機、顏色搜索和校準節點將在三個終端中分別啟動。

$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$ rosrun mycobot_test blue_point_detection.py$ rosrun mycobot_test mycobot_position_calibration.py

這將記錄變換 t_x, y, z (m) 和歐拉角 theta_1, 2, 3 (弧度) 到 mycobot_position_calibration.py 的終端。這些值由于點云數據收集和聚類而波動,因此這些值被多次取平均值。(在此設置中,平行平移和歐拉角都波動約 1%)

獲取值后,在 tf_broadcaster.cpp 中重寫臨時值。

// tf_broadcaster.cpp~~ # それぞれ t_x,y,z と theta_1,_2,_3 に得られた値を入れる # Put the obtained values in t_x,y,z and theta_1,_2,_3 respectively     transformStamped.transform.translation.x = t_z;     transformStamped.transform.translation.y = -t_x;     transformStamped.transform.translation.z = -t_y;          tf2::Quaternion q;     q.setEuler(theta_1, theta_2, theta_3); ~~

我正在尋找從camera_color_frame到base_link的TF,發現點編組坐標系camera_depth_optical_frame,計算后xyz方向不同(我沒有注意到差異,我很困惑)所以 x = t_z,y = - t_x,z = - t_y。

重寫并catkin_make后,啟動節點。

$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$ roslaunch mycobot_moveit mycobot_moveit_control.launch$ rosrun tf_broadcaster tf_broadcaster

然后反射攝像頭和機器人的位置關系,點云上的機器人和Rviz所示的機器人模型可以疊加,如圖14所示。

pYYBAGQ2KTuAVN2eAAHKJWUAQn0700.png

圖 14:將從校準中獲得的值設置為 TF 并廣播它并不完美,但我能夠將偏差保持在可接受的范圍內,以便簡單地到達并拾取物體。

當移動點云和疊加的機器人模型時,您可以看到這一點。

myCobot的關節有一點間隙,這使得很難做出精確的動作。

由于從實感獲得的點云坐標系被轉換為myCobot的坐標系,因此我們嘗試將myCobot的尖端定位為對象。(我試圖使用 MoveIt 訪問它,但它被困在C++,所以我制作了一個可以使用 pymycobot 輕松操作的腳本)

由于坐標位于相機的光學坐標系中,因此請使用先前獲得的平移和旋轉將它們轉換為myCobot坐標系。將以下內容添加到腳本目錄。

# mycobot_reaching.py#!/usr/bin/env python3 import time, os, sys  import numpy as np import quaternion from pymycobot.mycobot import MyCobot  import rospy from geometry_msgs.msg import Point from tf.transformations import quaternion_from_euler  class MyCobotReachingNode(object):     def __init__(self):         super(MyCobotReachingNode, self).__init__()         rospy.init_node("mycobot_reaching_node")         rospy.loginfo("mycobot reaching start")          # メンバ変數         # mycobot インスタンス         # member variable         # mycobot instance         port = "/dev/ttyUSB0"         self.mycobot = MyCobot(port, baudrate="115200", timeout=0.1, debug=False)         # 平行移動と回転         # 光學座標系→mycoboto座標系なので4.2節とXYZ軸が違うことに注意         # Translation and rotation         # Note that the XYZ axes are different from those in section 4.2 because the optical coordinate system is a mycoboto coordinate system                 self.translation_from_camera_to_mycobot = np.array([t_x, t_y, t_z])         q = quaternion_from_euler(-theta_2, -theta_3, theta_1)         self.rotation_from_camera_to_mycobot = quaternion.as_quat_array(q)         # subscriber         self.sub_point()      # Subscriber             def sub_point(self):         def callback(data):             rospy.loginfo("subscribed target point")             self.mycobot_move(data)          sub = rospy.Subscriber("object_position", Point, callback = callback)         rospy.spin()      # move mycobot     def mycobot_move(self, point_data):         # mycobot座標系への変換          # Convert to mycobot coordinate system         target_point = np.array([point_data.x, point_data.y, point_data.z])         target_point -= self.translation_from_camera_to_mycobot         target_point = quaternion.rotate_vectors(self.rotation_from_camera_to_mycobot, target_point)          # mm単位のため*1000、手前中心付近にリーチングするためx-20mm, z+40mm         # *1000 for mm increments, x-20mm, z+40mm for reaching around the center of the front                 coord_list = [target_point[0]*1000-20, -target_point[2]*1000, target_point[1]*1000+40, 0, 90, 0]         self.mycobot.send_coords(coord_list, 70, 0)         time.sleep(1.5)  if __name__ == "__main__":     reaching = MyCobotReachingNode()     pass

這一次,我將調動我使用過的所有庫和我制作的腳本。

您可以在 6 個終端中運行 rs_camera.launch、mycobot_moveit_control.launch、tf_broadcaster、red_point_detection.py、object_position_search.py、mycobot_reaching.py,但每次打開終端時,您都必須對其進行設置......調試會很困難,因此請創建自己的啟動文件。

轉到工作區,創建用于啟動的目錄和文件,并將啟動路徑添加到 CMakeLists.txt。

$ cd /src/mycobot_test$ mkdir launch$ cd launch$ touch mycobot_reaching.launch                                                # CMakeLists.txt~~# Add launch fileinstall(FILES   DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch ) ~~

啟動文件的結構很簡單,只需將要同時運行的節點和啟動文件中的啟動文件排列在啟動選項卡中即可。要執行節點,請在節點標記中寫入任何節點名稱,并像 rosrun 一樣寫入包名稱和可執行文件名稱。添加輸出=“屏幕”,如果您希望輸出顯示在命令行上。

在引導文件中執行啟動時,在包含標記中包含文件路徑。嘗試catkin_make并運行它。

$ roslaunch mycobot_test mycobot_reaching.launch

我能夠移動myCobot來跟蹤RealSense捕獲的紅色物體,就像在電影1中一樣。

pYYBAGQ2KXeAZoPdADCKlF2rN74276.png

跟著項目跟著做之前有很多滯后,總覺得自己在各方面都學得還不夠。

7. 總結

在本文中,我總結了如何使用 ROS 來協調 6 軸機械臂 myCobot 和深度攝像頭實感 D455。我沒有機器人開發的經驗,包括ROS。我認為沒有一個博客總結了我到目前為止從頭開始嘗試的內容,所以如果你買了一個機械臂或深度相機但不知道如何使用它,我希望它對那些想知道如何使用它的人有所幫助。另外,如果具有機器人開發經驗或擅長數據處理的人可以指出最好做這樣的事情,我將不勝感激。

這次我將我在模擬器中學到的強化學習模型應用于myCobot,并進行了拾取實驗,所以我可能會寫另一篇博客作為第2部分。

參考

1. 松林達志, 2022.12.21, 實感D455による空間認識でmyCobotを操作.

2. 阿爾伯特公司

審核編輯黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 傳感器
    +關注

    關注

    2551

    文章

    51197

    瀏覽量

    754436
  • 機器人
    +關注

    關注

    211

    文章

    28479

    瀏覽量

    207424
  • 攝像頭
    +關注

    關注

    60

    文章

    4849

    瀏覽量

    95854
收藏 人收藏

    評論

    相關推薦

    使用myCobot 280 Jeston Nano進行物體精確識別追蹤

    ,以便在實際應用中發揮作用,這個項目涉及到許多技術和算法,包括視覺識別、手眼協同和機械臂控制等方面。 機械臂的介紹 mycobot280-JetsonNano 操作使用的機械臂是myCobot
    的頭像 發表于 05-24 18:20 ?1727次閱讀
    使用<b class='flag-5'>myCobot</b> 280 Jeston Nano進行物體精確<b class='flag-5'>識別</b>追蹤

    試用 Intel RealSense

    Pro) 右上角。我們正在通過 PC 上的 RealSense 開發者工具運行一些樣本數據。與常規網絡攝像頭不同,這款攝像頭模塊可以使用紅外線測量距離。因此它可以識別人類的動作和手勢,還能以 3D
    發表于 09-25 00:21

    如何將D435 realsense連接到intel aero現有的RealSense R200引腳

    大家好,我們需要使用默認情況下使用英特爾Aero Board的R200凸輪進行切換。我們需要將micro u*** 3.0端口用于其他設備。我們如何將D435 RealSense連接到Intel
    發表于 10-11 16:58

    受磁鐵影響的RealSense D415/D435?

    你好,我需要在難以維修的區域安裝一些RealSense攝像頭,并考慮使用磁鐵進行安裝。相機背面或底部附近的強磁釹磁鐵是否會影響其功能?謝謝,擔以上來自于谷歌翻譯以下為原文Hello, I need
    發表于 10-11 16:59

    哪個實際相機在2到5米范圍內具有最佳的深度感知和物體識別平衡?

    大家好,我想弄清楚哪個相機(realsense D415或realsense D435)在陽光下具有最佳性能,可在2到5米范圍內進行深度感知和物體
    發表于 11-20 11:34

    怎么將RealSense D415包文件轉換為PCD

    我10天前收到了我的RealSense D415(我不是開發人員),我正試圖用它進行房間掃描。我通過查看器和Unity包裝器記錄了一個* .bag文件,我正在嘗試將.bag文件轉換為點云;我嘗試
    發表于 11-23 11:37

    Q455C/D/F閥門聯動裝置用戶手冊

    Q455C/Q455D/Q455F 是閥門聯動裝置系列產品,用于連接執行器MY3000 和控制閥。聯動裝置的曲柄機構將執行器的旋轉運動變成往復運對閥門進行開關運行,Q455C 用于小型
    發表于 10-24 11:26 ?7次下載

    英特爾將IMU搭載到RealSense攝像頭D435i系統中

    據麥姆斯咨詢報道,英特爾發布RealSense 3D攝像頭D415和D435時已引起業界巨大轟動。
    的頭像 發表于 11-19 15:32 ?1.8w次閱讀

    RealSense400系列相機介紹和使用實踐資料免費下載

    本文檔的主要內容詳細介紹的是RealSense400系列相機介紹和使用實踐資料免費下載包括了:1.RealSense攝像頭簡介 2.RealSense SDK 2.0下載及安裝 3.RealS
    發表于 07-09 08:00 ?11次下載

    英特爾RealSense D455發布,拍攝范圍對上一代產品增大一倍

    6月17日消息,英特爾剛剛發布了RealSense深度感知攝像頭家族的最新成員,它就是精度和范圍都有大幅提升的D455機型。從外形來看,它會讓我們立即聯想到微軟為 Xbox 游戲主機打造
    的頭像 發表于 06-18 14:49 ?5930次閱讀

    英特爾RealSense ID結合了深度傳感器與人臉識別系統

    英特爾(Intel)本周發布3D攝影機RealSense家族的新款產品RealSense ID,RealSense ID同時結合深度傳感器與人臉識別
    的頭像 發表于 01-10 09:38 ?2441次閱讀

    Intel推出全新3D人臉識別模組,能為智能門鎖等應用場景提供技術支持

    ? 1月7日,英特爾正式推出了一款基于 RealSense ID 傳感器的3D人臉識別解決方案F450/455,能夠為 ATM 和智能門鎖等應用場景提供技術支持。
    的頭像 發表于 01-10 10:33 ?3384次閱讀
    Intel推出全新3<b class='flag-5'>D</b>人臉<b class='flag-5'>識別</b>模組,能為智能門鎖等應用場景提供技術支持

    英特爾發布了RealSense ID 開發了一種面部識別系統

    英 特爾近日發布了RealSense的最新產品——RealSense ID。它將這項技術與神經網絡結合起來,開發了一種面部識別系統,該系統可以一目了然地訪問智能鎖和ATM之類的東西。它是一種設備上
    的頭像 發表于 01-16 09:32 ?2150次閱讀

    英特爾推出基于RealSense技術的3D人臉驗證解決方案

    據麥姆斯咨詢報道,英特爾推出了一款基于RealSense技術的3D人臉驗證解決方案F450和F455。該解決方案將有源深度傳感器與專用神經網絡完美結合,旨在隨時隨地為每位用戶提供安全、準確的人
    的頭像 發表于 01-19 09:46 ?2795次閱讀

    MAX6394US455D3+T PMIC - 監控器

    電子發燒友網為你提供Maxim(Maxim)MAX6394US455D3+T相關產品參數、數據手冊,更有MAX6394US455D3+T的引腳圖、接線圖、封裝手冊、中文資料、英文資料,MAX6394US455D3+T真值表,MA
    發表于 12-26 10:55
    MAX6394US<b class='flag-5'>455D</b>3+T PMIC - 監控器
    主站蜘蛛池模板: 又亲又揉摸下面视频免费看| 天堂so导航| 欧美 日韩 亚洲 在线| 亚洲国产欧美在线看片| 俄罗斯19girl video9| 欧美黑人巨大videos免费| 在线亚洲黄色| 久久国产主播福利在线| 亚洲国产黄色| 国产三级级在线电影| 舔1V1高H糙汉| 国产精品一区二区三区四区五区| 四虎国产精品永久免费入口| 俄罗斯XX性幻女18| 日韩av片无码一区二区不卡电影| caoporn 超碰免费视频| 且试天下芒果免费观看| 北原夏美 快播| 熟妇无码乱子成人精品| 国产普通话精品久久| 亚洲精品视频在线免费| 精品视频中文字幕| 伊人亚洲AV久久无码精品| 麻豆成人啪啪色婷婷久久| 99热这里只有是精品| 热热久久超碰精品中文字幕| 办公室沙发口爆12P| 色狠狠色狠狠综合天天| 国产精品久久久久久AV免费不卡| 羞羞漫画在线播放| 精品欧美小视频在线观看| 最近的2019中文字幕HD| 欧美极品尿交| 国产成人8x视频一区二区| 亚洲黄视频在线观看| 久久久久久久久性潮| 99九九免费热在线精品| 色多多污污在线播放免费| 黑人巨茎大战白人女40CMO| 中文字幕在线视频网站| 日本亚洲精品色婷婷在线影院|