0
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心
发布
  • 发文章

  • 发资料

  • 发帖

  • 提问

  • 发视频

创作活动

完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>

3天内不再提示

使用RealSense D455的空间识别操作myCobot

大象机器人科技 来源:大象机器人科技 作者:大象机器人科技 2023-04-12 11:53 次阅读

1. 简介

先进技术部门正在研究多模态强化学习,包括相机图像和触觉传感器。除其他外,要实现所谓的Sim2Real,其中模拟器中的强化学习结果也在实际机器上运行,必须协作操作真实机器的机械臂和相机。因此,在这种情况下,我们使用ROS测试了链接的6轴机械臂myCobot(由大象机器人制造)和深度摄像头RealSense D455(由英特尔制造),流程和结果将在下面详细描述。

操作环境:

PC:Ubuntu 20.04, ROS Noetic, Python 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. 阿尔伯特公司

审核编辑黄宇

  • 传感器
    +关注

    关注

    2410

    文章

    38550

    浏览量

    706505
  • 机器人
    +关注

    关注

    201

    文章

    23534

    浏览量

    196844
  • 摄像头
    +关注

    关注

    57

    文章

    4005

    浏览量

    91471
收藏 人收藏

    评论

    相关推荐

    CH455g长按和偶尔上电无反应怎么解决?

    1、CH455g能实现长按功能吗?是不是要做什么初始化设定,然后我单片机自己检测持续的外部中断?2、上电无反应,这情况是指,上电后,单片机有给CH455g一些指令(初始化),并且后续我立马给出命令让
    发表于 09-30 07:52

    CH455发烫怎么解决?

    使用CH455做按键扫描,同时使用15个CH455,有个别使用会出现发烫,很烫手,在DIGx引脚串的有电阻4.7K,难道这是假货吗
    发表于 10-11 08:22

    ch455如何在STM32使用代码?

    ch455在STM32使用代码
    发表于 10-11 08:38

    识别图片中的文字使用什么软件进行操作

    `  我们不管在生活还是在工作中都会使用到图片格式,而图片格式文件中有些使我们需要的资料,那么如何识别图片中的文字呢,将其提取出来怎么操作?接下来就让我们一起来看下如何操作的吧!  首先在这里我要给
    发表于 09-01 13:46

    试用 Intel RealSense

    Pro) 右上角。我们正在通过 PC 上的 RealSense 开发者工具运行一些样本数据。与常规网络摄像头不同,这款摄像头模块可以使用红外线测量距离。因此它可以识别人类的动作和手势,还能以 3D
    发表于 09-25 00:21

    MRF455销售

    `MRF455硅双极晶体管产品介绍MRF455报价MRF455代理MRF455咨询热线MRF455现货,王先生15989509955 深圳市首质诚科技有限公司MRF455为功率放大器应用于工业,商业
    发表于 01-10 17:31

    如何将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

    在一个区域内多次使用RealSense对精确度有什么影响

    您好,我们正在寻找可与同一传感器重叠的区域使用的深度传感器。创建大型互动表的主要思路。RealSense设备基于红外投影仪和红外接收器。当多个IR投影仪突出显示相同区域时,它可能无法正常工作。在我们
    发表于 10-15 11:30

    D435无色流

    嗨,出于某种原因,我的Realsense D435在RealSense Viewer中被读作D430,并没有给我一个颜色流选项。我通过Viewer尝试了硬件重置,并尝试更新固件,但没有运气。关于
    发表于 10-22 11:35

    使用D43无法尝试任何实际的sdk示例

    已进入我当前网络摄像头视图的新对象。我也提取了x,y坐标,希望D435能提供z坐标。有没有用opencv实现realsense sdk这样它会给我我正在跟踪的对象的z深度?此外,无论如何设置我可以跟踪
    发表于 10-22 11:31

    固件和realsense-viewer升级后的错误

    大家好!,我一直在使用带有D415和D435相机的realsense-viewer进行一些测试。一切进展顺利,但在升级到固件版本5.10.3和整个SDK的最后一个版本后,它开始显示不良的3D重建,如
    发表于 10-23 10:45

    电脑可能同时连接两台D435相机吗

    亲爱的大家,我是3D RealSense社区的新手。我想用我的电脑同时连接两台D435相机。如果有可能,请告诉我?如果可能,请指导我如何查看监视器上两个不同RealSense摄像头的输出。请帮助亲切
    发表于 10-23 10:44

    请问从intel realsense viewer获取彩色图像的时候数字不匹配为什么?

    嗨,我可以从intel realsense viewer中获取彩色图像和深度。但有三个问题:首先,.bag文件包含彩色图像和深度图像,但它们的数字不匹配。为什么?第二,我想将深度图像转换
    发表于 10-31 12:56

    怎么通过WiFi访问D415

    这里有人有通过WiFi访问D415(或其他RealSense相机)的经验吗?在我必须使用2个或更多深度相机一起工作的场景中,UpBoard是唯一(或者最佳......)方式吗?感谢您的任何想法,评论
    发表于 11-09 11:30

    英特尔实感D4视觉处理器可作为协处理器吗?

    我想在我的Realsense D415模块中使用英特尔实感D4视觉处理器作为协处理器。那就是我有一对从一对相机中捕获的立体声图像(我之前使用Opencv和2个相机系统的棋盘进行了校准)。是否可以将
    发表于 11-14 11:44

    D435能通过电缆将摄像机连接到深度模块吗

    你好,我有一个需要立体成像的项目。 realSense d435似乎是完美的,但不幸的是这个设备太宽了。是否有可能从深度模块中撕掉两个摄像头并再次用电缆连接到该板?我知道,我必须再次校准d
    发表于 11-16 11:31

    哪个实际相机在2到5米范围内具有最佳的深度感知和物体识别平衡?

    大家好,我想弄清楚哪个相机(realsense D415或realsense D435)在阳光下具有最佳性能,可在2到5米范围内进行深度感知和物体识别。我已经阅读了规格,但似乎intel D
    发表于 11-20 11:34

    怎么将RealSense D415包文件转换为PCD

    我10天前收到了我的RealSense D415(我不是开发人员),我正试图用它进行房间扫描。我通过查看器和Unity包装器记录了一个* .bag文件,我正在尝试将.bag文件转换为点云;我尝试
    发表于 11-23 11:37

    英特尔Realsense SR300会自动切掉任何黑色的东西

    为什么真实相机会自动切掉任何黑色的东西......这是一个可以关闭的设置吗?以上来自于谷歌翻译以下为原文Why is it that the realsense camera cuts out
    发表于 11-26 14:18

    RealSense D435访问冲突

    :Windows 10专业版1703API版本2.15.0固件版本5.10.3非常感谢你!以上来自于谷歌翻译以下为原文Hi,I want to use the Intel RealSense D
    发表于 11-26 14:19

    如何从D435获取16位深度图像?

    我从realsense查看器中获取d435深度相机的数据,当我保存深度图像的快照时,我在规格中得到8位(1-256)灰度图像,据说相机给出了16位深度图片。你知道我怎么能得到16位图像?以上
    发表于 11-27 14:11

    基于DSP和CPLD的空间瞬态光辐射信号实时识别处理

    ,可实现对瞬态信号的实时识别和处理。其中用cpld实现a/d变速率采样,解决了嵌入式系统线路板面积有限与实时处理需要大容量存储空间的矛盾。实时处理我国现役空间瞬态光辐射信号探测系统中,老型号较多
    发表于 06-25 06:26

    realsense D435插入电脑后viewer识别不到型号

    如图,一开始的时候是正常的,由于数据线不够长我将其拔下插入另一个USB接口之后便出现了这种“D4XX”的显示,并且右边的预览窗口看不到深度成像。系统是Windows10最新版,CPU使用的是AMD5900x,主板是微星迫击炮b550m,摄像头插入的是USB3.0接口。
    发表于 10-12 17:06

    STM32 USART串口的识别操作步骤是怎样的?

    STM32 USART串口的识别操作步骤是怎样的?
    发表于 12-10 07:04

    一种适用于空间观测任务的实时多目标识别算法分享

    基于嵌入式图像处理平台的实时多目标识别算法人工智能技术与咨询 昨天本文来自《科学技术与工程》,作者王旭辉等摘 要提出了一种适用于空间观测任务的实时多目标识别算法,它基于DSP和FPGA组合的图像处理
    发表于 12-21 07:02

    如何对RAM空间分配操作

    在代码编译过程中,编译器会根据配置和代码进行空间分配,包括对内存RAM的空间分配,对RAM空间分配操作,可以理解如下:分配全局变量区分配栈区,栈区的大小在编译器或者配置文件中定义,用于存放函数调用
    发表于 01-20 08:05

    STM32与CH455g通信测试键盘的方法

    1、概述  CH455是数码管显示驱动和键盘扫描控制芯片。CH455内置时钟振荡电路,可以动态驱动4位数码管或者32只LED;同时还可以进行28键的键盘扫描;CH455通过SCL和SDA组成的2线
    发表于 02-08 07:14

    详解STM32 USART串口的识别操作

    怎样去使用STM32 USART串口的识别操作呢?有哪些使用步骤?
    发表于 02-18 07:05

    基于样本正交子空间的SAR目标识别方法

    利用合成孔径雷达(Synthetic Aperture Radar, SAR)获取的目标像进行识别时,基于子空间的自动目标识别(Automatic Target Recognition, ATR)方法通常是对样本数据的值空间进行操作。当识别相似目
    发表于 02-10 14:00 19次下载

    基于子空间分析的人脸识别方法研究

    人脸识别技术是模式识别和机器视觉领域的一个重要研究方向,基于子空间分析的特征提取方法是人脸识别中特征提取的主流方法之一。本文对目前应用较多的子空间分析方法进
    发表于 08-11 14:04 30次下载

    联想电脑G455型使用说明书

    联想电脑G455型使用说明书 使用说明 操作注意事项
    发表于 12-16 17:55 55次下载

    基于FM 455控制器模块布线及工作原理

    FM 455 功能模块是用于 S7-400 自动化系统的控制器模块。FM 455 中执行了两种不同的控制技术。对于这两种控制技术,均有用于优化控制的支持,为了操作热电偶,FM 455 具有附加的模拟
    发表于 09-29 15:33 3次下载
    基于FM <b>455</b>控制器模块布线及工作原理

    Q455C/D/F阀门联动装置用户手册

    Q455C/Q455D/Q455F 是阀门联动装置系列产品,用于连接执行器MY3000 和控制阀。联动装置的曲柄机构将执行器的旋转运动变成往复运对阀门进行开关运行,Q455C 用于小型或中型阀门
    发表于 10-24 11:26 7次下载

    3D卷积神经网络的手势识别

    图像进行卷积操作,提取目标的时间和空间特征捕捉运动信息。为避免因单组3D CNN特征提取不充分而导致的误分类,训练多组具有较强分类能力的3D CNN结构组成多列深度3D CNN,该结构通过对多组3D CNN的输出结果进行权衡,将权重最大的类别判定为最终的
    发表于 01-30 13:59 2次下载
    3<b>D</b>卷积神经网络的手势<b>识别</b>

    RealSense400系列相机介绍和使用实践资料免费下载

    本文档的主要内容详细介绍的是RealSense400系列相机介绍和使用实践资料免费下载包括了:1.RealSense摄像头简介 2.RealSense SDK 2.0下载及安装 3.RealSense常用工具 4.技术支持平台 5.文档及其他相关资料 6.T265+D435 Demo
    发表于 07-09 08:00 9次下载

    HMC455 Gerber Files

    HMC455 Gerber Files
    发表于 02-22 10:02 0次下载
    HMC<b>455</b> Gerber Files

    DC455A-设计文件

    DC455A-设计文件
    发表于 04-11 15:18 0次下载
    DC<b>455</b>A-设计文件

    HMC455数据表

    HMC455数据表
    发表于 04-24 13:26 3次下载
    HMC<b>455</b>数据表

    FM455-PID控制功能模板手册

    FM455-PID控制功能模板手册资料免费下载。
    发表于 04-30 09:38 6次下载

    DC455A-演示手册

    DC455A-演示手册
    发表于 05-22 18:23 1次下载
    DC<b>455</b>A-演示手册

    HMC455 Gerber文件

    HMC455 Gerber文件
    发表于 05-29 17:59 5次下载
    HMC<b>455</b> Gerber文件

    HMC455 S参数

    HMC455 S参数
    发表于 06-04 19:13 0次下载
    HMC<b>455</b> S参数

    DC455A DC455A评估板

    电子发烧友网为你提供ADI(ti)DC455A相关产品参数、数据手册,更有DC455A的引脚图、接线图、封装手册、中文资料、英文资料,DC455A真值表,DC455A管脚等资料,希望可以帮助到广大的电子工程师们。
    发表于 07-30 22:00

    联想G455板号:LA-5971PBIOSBIN

    联想G455板号:LA-5971PBIOSBIN
    发表于 06-15 14:29 1次下载

    使用myCobot280 M5Stack控制器

    电子发烧友网站提供《使用myCobot280 M5Stack控制器.zip》资料免费下载
    发表于 10-18 17:28 0次下载
    使用<b>myCobot</b>280 M5Stack控制器

    N32G455系列芯片

    N32G455系列芯片
    发表于 11-10 19:50 1次下载
    N32G<b>455</b>系列芯片

    N32G455系列芯片关键特性

    N32G455系列芯片关键特性,总线架构,功能描述,引脚定义,电气特性与封装信息
    发表于 11-10 19:50 0次下载
    N32G<b>455</b>系列芯片关键特性

    N32G455系列GCC开发环境应用笔记

    N32G455系列GCC开发环境应用笔记
    发表于 11-10 19:51 0次下载
    N32G<b>455</b>系列GCC开发环境应用笔记

    N32G455系列触控设计指南

    N32G455系列触控设计指南
    发表于 11-10 19:51 0次下载
    N32G<b>455</b>系列触控设计指南

    N32G455系列低功耗应用笔记

    N32G455系列低功耗应用笔记
    发表于 11-10 19:51 0次下载
    N32G<b>455</b>系列低功耗应用笔记

    N32G455系列BOOT跳转应用笔记

    N32G455系列BOOT跳转应用笔记
    发表于 11-10 19:51 0次下载
    N32G<b>455</b>系列BOOT跳转应用笔记

    N32G455系列BOOT接口指令使用指南

    N32G455系列BOOT接口指令使用指南
    发表于 11-11 21:50 0次下载
    N32G<b>455</b>系列BOOT接口指令使用指南

    N32G455系列硬件设计指南

    N32G455系列硬件设计指南
    发表于 11-11 21:50 0次下载
    N32G<b>455</b>系列硬件设计指南

    N32G455系列TSC触控SDK使用指南

    N32G455系列TSC触控SDK使用指南
    发表于 11-11 21:50 2次下载
    N32G<b>455</b>系列TSC触控SDK使用指南

    N32G455系列勘误手册

    N32G455系列勘误手册
    发表于 11-11 21:50 0次下载
    N32G<b>455</b>系列勘误手册

    MAX6394US455D3+T PMIC - 监控器

    电子发烧友网为你提供Maxim(Maxim)MAX6394US455D3+T相关产品参数、数据手册,更有MAX6394US455D3+T的引脚图、接线图、封装手册、中文资料、英文资料,MAX6394US455D3+T真值表,MAX6394US455D3+T管脚等资料,希望可以帮助到广大的电子工程师们。
    发表于 12-26 10:55
    MAX6394US<b>455D</b>3+T PMIC - 监控器

    DS1086LU-455+ 时钟/定时 - 时钟发生器,PLL,频率合成器

    电子发烧友网为你提供Maxim(Maxim)DS1086LU-455+相关产品参数、数据手册,更有DS1086LU-455+的引脚图、接线图、封装手册、中文资料、英文资料,DS1086LU-455+真值表,DS1086LU-455+管脚等资料,希望可以帮助到广大的电子工程师们。
    发表于 02-03 18:23
    DS1086LU-<b>455</b>+ 时钟/定时 - 时钟发生器,PLL,频率合成器

    MAX455CWP+ 线性器件 - 放大器 - 视频放大器和模块

    电子发烧友网为你提供Maxim(Maxim)MAX455CWP+相关产品参数、数据手册,更有MAX455CWP+的引脚图、接线图、封装手册、中文资料、英文资料,MAX455CWP+真值表,MAX455CWP+管脚等资料,希望可以帮助到广大的电子工程师们。
    发表于 02-08 20:10
    MAX<b>455</b>CWP+ 线性器件 - 放大器 - 视频放大器和模块

    MAX455CPP+ 线性器件 - 放大器 - 视频放大器和模块

    电子发烧友网为你提供Maxim(Maxim)MAX455CPP+相关产品参数、数据手册,更有MAX455CPP+的引脚图、接线图、封装手册、中文资料、英文资料,MAX455CPP+真值表,MAX455CPP+管脚等资料,希望可以帮助到广大的电子工程师们。
    发表于 02-09 18:02
    MAX<b>455</b>CPP+ 线性器件 - 放大器 - 视频放大器和模块

    455KHz FM解调器

    455KHz FM解调器
    发表于 09-15 11:04 858次阅读
    <b>455</b>KHz FM解调器

    455KHz窄带中频滤波器

    455KHz窄带中频滤波器 该
    发表于 09-17 15:04 3126次阅读
    <b>455</b>KHz窄带中频滤波器

    455KHz的调制器

    455KHz的调制器   本电路示出了怎么用以NE555
    发表于 09-26 11:35 727次阅读
    <b>455</b>KHz的调制器

    455KHz简易中频放大器

    455KHz简易中频放大器 ZN416E可构成一台455KHz的简易中频
    发表于 10-06 15:34 1426次阅读
    <b>455</b>KHz简易中频放大器

    455KHz的中频放大器

    455KHz的中频放大器 利用MC1350P可在455KHz频段上得到高达60dB的增益,RES
    发表于 10-06 15:44 5168次阅读
    <b>455</b>KHz的中频放大器

    455KHZ IF放大器

    455KHZ IF放大器 ZN416E可构成一个简易的455KHz中频
    发表于 10-06 15:55 903次阅读
    <b>455</b>KHZ IF放大器

    3D人脸识别研究探索

    2D人脸识别技术虽已成熟,但由于单一的2D图像不能提供识别所需的完整信息,故其识别精度很难进一步提高。在人脸识别过程中,特征提取是影响识别效果的一个重要环节,在分析了传
    发表于 09-08 17:15 1638次阅读
    3<b>D</b>人脸<b>识别</b>研究探索

    英特尔RealSense 3D摄像头内部硬件设计拆解

    加拿大的逆向工程服务公司Chipworks最近拆解了一台从联想(Lenovo)Yoga15超轻薄笔记本电脑拆卸下来的英特尔(Intel)的RealSense 3D摄像头。
    的头像 发表于 08-11 09:58 2.6w次阅读

    电机:空间矢量调制与交流感应电机的操作介绍

    赋予旧的电机新的技巧3.7:空间矢量调制,磁场弱化,d-q轴去耦和交流感应电机的操作
    的头像 发表于 08-21 01:30 2089次阅读

    TCL发布最新产品BCD-455WBEPFC2冰箱,拥有455升的超大容量

    其中TCL日前发布的新品BCD-455WBEPFC2格雅金便是使用这种配色的集大成者。
    发表于 08-22 14:55 2426次阅读

    Fallout 4与Intel RealSense技术的本机集成展示

    本演示展示了Fallout 4与Intel RealSense技术的本机集成,使用其EEZ3D创建面部扫描,并使用Uraniom将玩家的面部集成到化身中。
    的头像 发表于 05-31 17:28 2597次阅读

    英特尔将IMU搭载到RealSense摄像头D435i系统中

    据麦姆斯咨询报道,英特尔发布RealSense 3D摄像头D415和D435时已引起业界巨大轰动。
    的头像 发表于 11-19 15:32 1.6w次阅读

    dfrobotIntel®RealSense™ 开发者套件 (SR300)简介

    Intel® RealSense™ SR300 系列实感摄像头,采用英特尔RealSense™ F200技术,这是世界上第一个,也是最小的一个集成3D景深和2D相机的模组:将景深感测与1080p
    的头像 发表于 01-03 09:45 2224次阅读
    dfrobotIntel®<b>RealSense</b>™ 开发者套件 (SR300)简介

    英特尔RealSense D455发布,拍摄范围对上一代产品增大一倍

    6月17日消息,英特尔刚刚发布了RealSense深度感知摄像头家族的最新成员,它就是精度和范围都有大幅提升的D455机型。从外形来看,它会让我们立即联想到微软为 Xbox 游戏主机打造
    的头像 发表于 06-18 14:49 5083次阅读

    英特尔RealSense ID结合了深度传感器与人脸识别系统

    英特尔(Intel)本周发布3D摄影机RealSense家族的新款产品RealSense ID,RealSense ID同时结合深度传感器与人脸识别系统,可应用在智能锁、访问控制或ATM服务上。
    的头像 发表于 01-10 09:38 1964次阅读

    Intel推出全新3D人脸识别模组,能为智能门锁等应用场景提供技术支持

      1月7日,英特尔正式推出了一款基于 RealSense ID 传感器的3D人脸识别解决方案F450/455,能够为 ATM 和智能门锁等应用场景提供技术支持。 RealSense ID F450
    的头像 发表于 01-10 10:33 2660次阅读
    Intel推出全新3<b>D</b>人脸<b>识别</b>模组,能为智能门锁等应用场景提供技术支持

    基于SLAM的空间及3D结构语

    同时,深度学习已极大地提高了识别性能,但是这种识别大部分限于图像平面中的输出,或者在最佳情况下使用 3D 边界框完成一定意义上的语义空间结构表示,但这会使机器人或者准确数字信息叠加很难根据这些略显粗糙的输出进行操作
    的头像 发表于 01-15 15:58 1316次阅读

    英特尔发布了RealSense ID 开发了一种面部识别系统

    英 特尔近日发布了RealSense的最新产品——RealSense ID。它将这项技术与神经网络结合起来,开发了一种面部识别系统,该系统可以一目了然地访问智能锁和ATM之类的东西。它是一种设备上
    的头像 发表于 01-16 09:32 1673次阅读

    英特尔推出基于RealSense技术的3D人脸验证解决方案

    据麦姆斯咨询报道,英特尔推出了一款基于RealSense技术的3D人脸验证解决方案F450和F455。该解决方案将有源深度传感器与专用神经网络完美结合,旨在随时随地为每位用户提供安全、准确的人
    的头像 发表于 01-19 09:46 2041次阅读

    3d人脸识别和2d人脸识别的区别

    首先是3d人脸识别和2d人脸识别图像数据获取不同。3D人脸识别是以3D摄像头立体成像,而2D是以2D图像获取为基础的。
    发表于 02-05 16:00 1.6w次阅读

    RealSense复活,大厂打算继续发展深度摄像头?

    从去年宣布调整并缩减RealSense部门以来,不少人都不再看好英特尔这个曾经吸睛满满的业务,觉得RealSense步上了谷歌Tango和微软Kinect的后尘,然而近日RealSense却意外
    的头像 发表于 04-08 06:53 9174次阅读

    商汤二代3D面部识别智能门锁解决方案通过(BCTC)认证

    相较于其他解锁方式,3D面部识别在安全性和便捷性方面均更胜一筹。目前,3D面部识别智能门锁在智能门锁市场中占比仍不到15%,增量空间巨大。商汤将持续深入与各大智能门锁品牌合作,推动3D面部识别智能门锁进入千家万户。
    的头像 发表于 04-15 14:29 1565次阅读

    如何构建一个具有3D面部识别功能的智能开门器

    2021 年初,英特尔通过发布 RealSense ID F455 摄像头采纳了这一原则,并为制造商提供了一款有趣的产品,可集成到自制解决方案中。该相机通过大量文档、适用于 Linux、Windows 和 Android 的开源 SDK 以及 C、C++、C# 和 Python 语言来评分。
    的头像 发表于 04-18 14:29 646次阅读

    MyCobot六轴机械臂开箱及开发前的准备工作(一)

    MyCobot机械臂是一款入门级的六自由度机械臂,目前是国产机械臂中价格和性能十分优良的机械臂,本讲主要以MyCobot 280pi机臂的开箱搭建和开发前的准备工作为起点为小伙伴们详细的介绍这款机械
    的头像 发表于 09-30 10:00 663次阅读
    <b>MyCobot</b>六轴机械臂开箱及开发前的准备工作(一)

    MyCobot六轴机械臂的基本操作(二)

    可以在windows平台通过vnc远程操作我们的机械臂,这样你就可以在自己的工作台上自由编程和上网查资料,然后MyCobot他不会占用你的显示器。当然了,你也可以直接拿这个树莓派当做开发机器使用,也是没有问题了。 在这里我们使用pycharm的社区版(Community)就可
    的头像 发表于 09-30 10:01 428次阅读
    <b>MyCobot</b>六轴机械臂的基本<b>操作</b>(二)

    Mycobot机械臂各关节的运动(三)

    这一节我们开始第一个程序,就是机械臂各关节的运动。让我们首先打开Mycobot,然后登入一个终端,我们输入“python”进入python环境。   我们采用一边实验一边介绍MyCobot机械臂
    的头像 发表于 09-30 18:08 473次阅读
    <b>Mycobot</b>机械臂各关节的运动(三)

    大象机器人myCobot 280 2023版全新功能展示

    大象机器人mycobot 280 2023版全新功能
    的头像 发表于 03-10 18:46 80次阅读
    大象机器人<b>myCobot</b> 280 2023版全新功能展示

    使用Isaac Gym 来强化学习mycobot 抓取任务

    使用Isaac Gym来强化学习mycobot抓取任务
    的头像 发表于 04-11 14:57 536次阅读
    使用Isaac Gym 来强化学习<b>mycobot</b> 抓取任务

    下载硬声App