Darknet+ros+realsenseD435i+yolo(ubuntu20.04)

一、下载Darknet_ros

mkidr -p yolo_ws/src
cd yolo_ws/src
git clone --recursive https://github.com/leggedrobotics/darknet_ros.git
#因为这样克隆的darknet文件夹是空的,将darknet_ros中的darknet的文件替换成如下
cd darknet_ros
git clone https://github.com/arnoldfychen/darknet.git
#进入darknet目录下进行make
cd darknet
make

修改darknet文件夹下的Makefile文件

修改 darknet_ros/darknet_ros/CMakeLists.txt

将这算力改成自己电脑的算力

make可能会报如下错误:

一、

fatal error:cudnn_ros_infer.h:没有那个文件或目录

解决办法:

根据官方链接cuDNN Archive | NVIDIA Developer,选择与cuda版本相匹配的cudnn下载tar文件。在这里,我下载的是v8.9.6,可与cuda 12.x等版本适配。

解压cudnn-linux-x86_64-8.9.7.29_cuda11-archive.tar.xz后,进入该目录,将lib内的文件都复制到目录/usr/local/cuda-11.6/lib64/中,将include内的文件都复制到目录/usr/local/cuda-11.6/include/中

cd ./cudnn-linux-x86_64-8.9.6.50_cuda11-archive
sudo cp ./lib/* /usr/local/cuda-12.2/lib64/
sudo cp ./include/* /usr/local/cuda-12.2/include/

二、

 fatal error:opencv2/opencvhpp:没有那个文件或目录

解决办法:修改修改darknet文件夹下的Makefile文件

三、

 error: ‘IplImage’ does not name a type    12 | IplImage *image_to_ipl(image im)

home/darknet/src/imageopencv.cpp 修改如下:

#ifdef OPENCV

#include "stdio.h"
#include "stdlib.h"
#include "opencv2/opencv.hpp"
#include "image.h"

using namespace cv;

extern "C" {

/*IplImage *image_to_ipl(image im)
{
    int x,y,c;
    IplImage *disp = cvCreateImage(cvSize(im.w,im.h), IPL_DEPTH_8U, im.c);
    int step = disp->widthStep;
    for(y = 0; y < im.h; ++y){
        for(x = 0; x < im.w; ++x){
            for(c= 0; c < im.c; ++c){
                float val = im.data[c*im.h*im.w + y*im.w + x];
                disp->imageData[y*step + x*im.c + c] = (unsigned char)(val*255);
            }
        }
    }
    return disp;
}

image ipl_to_image(IplImage* src)
{
    int h = src->height;
    int w = src->width;
    int c = src->nChannels;
    image im = make_image(w, h, c);
    unsigned char *data = (unsigned char *)src->imageData;
    int step = src->widthStep;
    int i, j, k;

    for(i = 0; i < h; ++i){
        for(k= 0; k < c; ++k){
            for(j = 0; j < w; ++j){
                im.data[k*w*h + i*w + j] = data[i*step + j*c + k]/255.;
            }
        }
    }
    return im;
}*/

/*Mat image_to_mat(image im)
{
    image copy = copy_image(im);
    constrain_image(copy);
    if(im.c == 3) rgbgr_image(copy);

    IplImage *ipl = image_to_ipl(copy);
    Mat m = cvarrToMat(ipl, true);
    cvReleaseImage(&ipl);
    free_image(copy);
    return m;
}

image mat_to_image(Mat m)
{
    IplImage ipl = m;
    image im = ipl_to_image(&ipl);
    rgbgr_image(im);
    return im;
}*/

Mat image_to_mat(image im)
{
    image copy = copy_image(im);
    constrain_image(copy);
    if(im.c == 3) rgbgr_image(copy);

    Mat m(cv::Size(im.w,im.h), CV_8UC(im.c));
    int x,y,c;

    int step = m.step;
    for(y = 0; y < im.h; ++y){
        for(x = 0; x < im.w; ++x){
            for(c= 0; c < im.c; ++c){
                float val = im.data[c*im.h*im.w + y*im.w + x];
                m.data[y*step + x*im.c + c] = (unsigned char)(val*255);
            }
        }
    }

    free_image(copy);
    return m;

// free_image(copy);
// return m;
//     IplImage *ipl = image_to_ipl(copy);
//     Mat m = cvarrToMat(ipl, true);
//     cvReleaseImage(&ipl);
//     free_image(copy);
//     return m;
}

image mat_to_image(Mat m)
{
    int h = m.rows;
    int w = m.cols;
    int c = m.channels();
    image im = make_image(w, h, c);
    unsigned char *data = (unsigned char *)m.data;
    int step = m.step;
    int i, j, k;

    for(i = 0; i < h; ++i){
        for(k= 0; k < c; ++k){
            for(j = 0; j < w; ++j){
                im.data[k*w*h + i*w + j] = data[i*step + j*c + k]/255.;
            }
        }
    }
    rgbgr_image(im);
    return im;
    // IplImage ipl = m;
    // image im = ipl_to_image(&ipl);
    // rgbgr_image(im);
    // return im;
}

void *open_video_stream(const char *f, int c, int w, int h, int fps)
{
    VideoCapture *cap;
    if(f) cap = new VideoCapture(f);
    else cap = new VideoCapture(c);
    if(!cap->isOpened()) return 0;
    //if(w) cap->set(CV_CAP_PROP_FRAME_WIDTH, w);
    //if(h) cap->set(CV_CAP_PROP_FRAME_HEIGHT, w);
    //if(fps) cap->set(CV_CAP_PROP_FPS, w);
    if(w) cap->set(CAP_PROP_FRAME_WIDTH, w);
    if(h) cap->set(CAP_PROP_FRAME_HEIGHT, w);
    if(fps) cap->set(CAP_PROP_FPS, w);
    return (void *) cap;
}

image get_image_from_stream(void *p)
{
    VideoCapture *cap = (VideoCapture *)p;
    Mat m;
    *cap >> m;
    if(m.empty()) return make_empty_image(0,0,0);
    return mat_to_image(m);
}

image load_image_cv(char *filename, int channels)
{
    int flag = -1;
    if (channels == 0) flag = -1;
    else if (channels == 1) flag = 0;
    else if (channels == 3) flag = 1;
    else {
        fprintf(stderr, "OpenCV can't force load with %d channels\n", channels);
    }
    Mat m;
    m = imread(filename, flag);
    if(!m.data){
        fprintf(stderr, "Cannot load image \"%s\"\n", filename);
        char buff[256];
        sprintf(buff, "echo %s >> bad.list", filename);
        system(buff);
        return make_image(10,10,3);
        //exit(0);
    }
    image im = mat_to_image(m);
    return im;
}

int show_image_cv(image im, const char* name, int ms)
{
    Mat m = image_to_mat(im);
    imshow(name, m);
    int c = waitKey(ms);
    if (c != -1) c = c%256;
    return c;
}

void make_window(char *name, int w, int h, int fullscreen)
{
    namedWindow(name, WINDOW_NORMAL); 
    if (fullscreen) {
        //setWindowProperty(name, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
        setWindowProperty(name, WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
    } else {
        resizeWindow(name, w, h);
        if(strcmp(name, "Demo") == 0) moveWindow(name, 0, 0);
    }
}

}

#endif

将之前在darknet文件进行make出错的文件删除,再重新编译

sudo make clean
make

在工作空间中安装realsense_ros与机械臂启动包

cd yolo_ws
cd src
#安装realsense_ros
git clone https://github.com/IntelRealSense/realsense-ros.git
git clone https://github.com/UniversalRobots/Universal_Robots_ROS_Driver.git Universal_Robots_ROS_Driver
git clone -b calibration_devel https://github.com/fmauch/universal_robot.git fmauch_universal_robot

cd ..
catkin_make -DCMAKE_BUILD_TYPE=Release

使用VScode 在工作空间的src目录下创建新的文件夹std_msg,并添加相关的依赖:rospy roscpp std_msgs

在std_msg文件中创建scripts文件夹,创建两个py文件

一个为yolo目标检测文件及机械臂运动程序

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy
from darknet_ros_msgs.msg import BoundingBoxes, BoundingBox
from sensor_msgs.msg import Image, CameraInfo
from cv_bridge import CvBridge
import numpy as np
import tf2_ros
import tf2_geometry_msgs
from geometry_msgs.msg import Point


class Readyolo:
    def __init__(self):
        rospy.init_node('grasping_node', anonymous=True)

        self.bridge = CvBridge()

        self.tf_buffer = tf2_ros.Buffer()
        self.tf_listener = tf2_ros.TransformListener(self.tf_buffer)

        self.rgb_image_sub = rospy.Subscriber('/camera/color/image_raw', Image, self.rgb_image_callback)
        self.depth_image_sub = rospy.Subscriber('/camera/depth/image_rect_raw', Image, self.depth_image_callback)
        self.camera_info_sub = rospy.Subscriber('/camera/depth/camera_info', CameraInfo, self.camera_info_callback)

        self.object_detection = rospy.Subscriber('/darknet_ros/bounding_boxes', BoundingBoxes, self.yolo)
        self.pub = rospy.Publisher('/object_camera_coordinates', Point, queue_size=10)

        self.depth_intrinsics = None
        self.rgb_image = None
        self.depth_image = None

    def camera_info_callback(self, msg):
        self.depth_intrinsics = msg
        print(self.depth_intrinsics.K[0])
        print(self.depth_intrinsics.K[4])
        print()

    def rgb_image_callback(self, msg):
        self.rgb_image = self.bridge.imgmsg_to_cv2(msg, desired_encoding="passthrough")

    def depth_image_callback(self, msg):
        self.depth_image = self.bridge.imgmsg_to_cv2(msg, desired_encoding="passthrough")
        self.process_yolo_results()

    def process_yolo_results(self):
        if self.depth_intrinsics is None or self.rgb_image is None or self.depth_image is None:
            return

        for box in self.bounding_boxes:
            if box.Class == "bottle":
                yolo_center_point_x = (box.xmin + box.xmax) / 2
                yolo_center_point_y = (box.ymin + box.ymax) / 2

                depth = self.depth_image[int(yolo_center_point_y)][int(yolo_center_point_x)]

                camera_point = self.convert_pixel_to_camera_coordinates(yolo_center_point_x, yolo_center_point_y, depth)

                print("OI:",yolo_center_point_x,yolo_center_point_y)
                point_msg = Point(x=camera_point[0], y=camera_point[1], z=camera_point[2])
                self.pub.publish(point_msg)


                # self.pub.publish(box)

    def convert_pixel_to_camera_coordinates(self, u, v, depth):
        if self.depth_intrinsics is None:
            return None

        fx = self.depth_intrinsics.K[0]
        fy = self.depth_intrinsics.K[4]
        cx = self.depth_intrinsics.K[2]
        cy = self.depth_intrinsics.K[5]

        camera_x = (u - cx) * depth / fx/1000
        camera_y = (v - cy) * depth / fy/1000
        camera_z = float(depth)/1000
        print("camera_link:",camera_x,camera_y,camera_z)

        return [camera_x, camera_y, camera_z]

    def yolo(self, msg):
        self.bounding_boxes = msg.bounding_boxes
        self.process_yolo_results()

def main():
    readyolo = Readyolo()
    rospy.spin()

if __name__ == '__main__':
    main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy, sys
import moveit_commander
from geometry_msgs.msg import PoseStamped, Pose
import tf2_geometry_msgs
import tf2_ros
from geometry_msgs.msg import Point

class MoveItIkDemo:

    def __init__(self):

        # 初始化move_group的API
        moveit_commander.roscpp_initialize(sys.argv)

        # 初始化ROS节点
        rospy.init_node('moveit_it_demo')

        # 初始化需要使用move group控制的机械臂中的arm group
        self.arm = moveit_commander.MoveGroupCommander('manipulator')

        # 获取终端link的名称,这个在setup assistant中设置过了
        end_effector_link = self.arm.get_end_effector_link()

        # 设置目标位置所使用的参考坐标系
        reference_frame = "base"
        self.arm.set_pose_reference_frame(reference_frame)

        # 当运动规划失败后,允许重新规划
        self.arm.allow_replanning(True)

        # 设置位置(单位: 米)和姿态(单位:弧度)的允许误差
        # self.arm.set_goal_position_tolerance(0.001)
        # self.arm.set_goal_orientation_tolerance(0.01)

        self.arm.set_goal_position_tolerance(0.001000)
        self.arm.set_goal_orientation_tolerance(0.01000)

        # 设置允许的最大速度和加速度
        self.arm.set_max_acceleration_scaling_factor(0.5)
        self.arm.set_max_velocity_scaling_factor(0.5)

        # 控制机械臂先回到初始位置
        # self.arm.set_named_target('home')
        # self.arm.go(wait=True)
        # rospy.sleep(1)

        # 设置机械臂工作空间中的目标位姿,位置使用x y z坐标描述
        # 姿态使用四元数描述,基于base_link坐标系
        # target_pose = PoseStamped()
        # # 参考坐标系,前面设置了
        # target_pose.header.frame_id = reference_frame
        # target_pose.header.stamp = rospy.Time.now()
        # # 末端位置
        # target_pose.pose.position.x = 0.359300
        # target_pose.pose.position.y = 0.163600
        # target_pose.pose.position.z = 0.278700
        # # 末端姿态,四元数
        # target_pose.pose.orientation.x = 0.433680
        # target_pose.pose.orientation.y = 0.651417
        # target_pose.pose.orientation.z = 0.508190
        # target_pose.pose.orientation.w = 0.359611

        # # 设置机械臂当前的状态作为运动初始状态
        # self.arm.set_start_state_to_current_state()
        # # 设置机械臂终端运动的目标位姿
        # self.arm.set_pose_target(target_pose)
        # # 规划运动路径,返回虚影的效果
        # plan_success,traj,planning_time,error_code = self.arm.plan()
        # # traj = self.arm.plan()

        # # 按照规划的运动路径控制机械臂运动
        # self.arm.execute(traj)
        # # 执行完休息一秒
        # rospy.sleep(1)

        # 新建一个接收方用来接受话题并处理
        self.pose_sub = rospy.Subscriber("/object_camera_coordinates", Point, self.callback) 
    

    def transform_pose(self, input_pose, from_frame, to_frame):
        try:
            tf_buffer = tf2_ros.Buffer()
            listener = tf2_ros.TransformListener(tf_buffer)
            transform = tf_buffer.lookup_transform(to_frame, from_frame, rospy.Time(0), rospy.Duration(1.0))
            transformed_pose = tf2_geometry_msgs.do_transform_pose(input_pose, transform)
            return transformed_pose
        except(tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationoException) as ex:
            rospy.logerr("TF2 error:%s",str(ex))
            return None
        

    def callback(self, p):
        global object_position, grasp_pose
        object_position = p
        temp_pose = PoseStamped()
        temp_pose.header.frame_id = "camera_link"
        temp_pose.pose.position = p
        temp_pose.pose.orientation.w = 1.0
        transformed_pose = self.transform_pose(temp_pose, "camera_link", "base")
        if transformed_pose is not None:
            grasp_pose = transformed_pose
            self.arm.set_start_state_to_current_state()
            self.arm.set_pose_target(grasp_pose)
            plan_success,traj,planning_time,error_code = self.arm.plan()
            self.arm.execute(traj)
            rospy.sleep(1)


def main():
    moveitikdemo = MoveItIkDemo()
    rospy.spin()


if __name__ == '__main__':
    main()

修改py文件权限,并在CMakeLists.txt进行相对应的修改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/630394.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自定义注解

例如写一个注解PrintTime 如下&#xff1a; import java.lang.annotation.*;//下面的注解属于元注解 Target({ElementType.PARAMETER,ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Inherited Documented public interface PrintTime {/*** 注解的属性*/public S…

JavaScript 进阶(二)

一、深入对象 1. 创建对象的三种方式 利用 new Object 创建对象 2. 构造函数 【注意事项】 【例】 这样子写好之后&#xff0c;想要添加一个新的结构类似的对象&#xff0c;直接照着红圈中写&#xff0c;最后改相应的数据就好了 注意&#xff1a;红色是第一步&#xff0c;黄…

springboot004网页时装购物系统

springboot004网页时装购物系统 亲测完美运行带论文&#xff1a;获取源码&#xff0c;私信评论或者v:niliuapp 运行视频 包含的文件列表&#xff08;含论文&#xff09; 数据库脚本&#xff1a;db.sql其他文件&#xff1a;ppt.pptx论文/文档&#xff1a;开题报告.docx论文&…

如何利用命令提示符列出文件?这里提供了几个实例供你参考

序言 什么命令可以用来列出目录中的文件&#xff1f;如何在命令提示符Windows 10/11中列出文件&#xff1f;很多人对这些问题感到困惑。在这篇文章中&#xff0c;我们详细解释了命令提示符列出文件的主题。 CMD&#xff08;命令提示符&#xff09;是一个功能强大的Windows内置…

河南广电与LiblibAI签署战略合作协议

5月15日&#xff0c;河南广电科技与LiblibAI战略签约仪式在郑州中原福塔新闻发布厅隆重举行。双方将本着“共商、共享、共建、共赢”原则&#xff0c;基于全面、可持续的战略合作伙伴关系&#xff0c;发挥各自优势&#xff0c;共同聚焦生成式AI领域&#xff0c;围绕内容创作、商…

【永洪BI】管理系统

管理系统模块包括系统设置、认证授权、日志管理、监控预警、资源部署、VooltDB管理、数据库管理、企业应用配置、系统检查、应用管理模块。 系统设置界面&#xff1a; 可以进行清除系统缓存、配置系统主题、配置系统邮箱、配置门户主页、配置权限管理系统、配置密码策略、配置…

音乐的力量

常听音乐的好处可以让人消除工作紧张、减轻生活压力、避免各类慢性疾病等等&#xff0c;其实这些都是有医学根据的。‍ 在医学研究中发现&#xff0c;经常的接触音乐节 奏、旋律会对人体的脑波、心跳、肠胃蠕动、神经感应等等&#xff0c;产生某些作用&#xff0c;进而促进身心…

【MySQl】MySQL概述 | 数据库的操作 | MySQL的编码问题 | 连接器的工作流程

文章目录 一、MySQL概述1.数据库的概念MySQLMySQL中支持的数据类型&#xff1a; 2.数据库的操作1.创建数据库2.查看数据库3.选中数据库4.删除数据库 3.数据表的操作1.创建表2.查看当前数据库中的所有表3.查看指定表的结构4.删除表 二、MySQL的编码问题常见的编码类型 连接器的工…

Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)

Linux文件&#xff1a;重定向底层实现原理&#xff08;输入重定向、输出重定向、追加重定向&#xff09; 前言一、文件描述符fd的分配规则二、输出重定向&#xff08;>&#xff09;三、输出重定向底层实现原理四、追加重定向&#xff08;>>&#xff09;五、输入重定向…

邦注科技 工业冷水机的风冷和水冷的区别介绍

工业冷水机在工业生产中扮演着重要角色&#xff0c;特别是在需要精确控制温度的应用中。风冷式冷水机和水冷式冷水机是两种常见的类型&#xff0c;它们之间存在一些显著的区别。 热交换的来源不同&#xff1a; 风冷式冷水机&#xff1a;热交换的来源是气体。它采用空气冷却方…

java技术:nacos

目录 一、docker安装 1、创建一个nacos 2、复制配置信息出来&#xff08;方便修改配置文件&#xff09; 3、删除nacos 4、修改配置文件&#xff08;主要是一下几个&#xff09; 6、创建数据库 nacos 7、重启nacos mysql 一、docker安装 1、创建一个nacos docker run …

随笔:棋友们

我是在小学二年级学会中国象棋的&#xff0c;准确说&#xff0c;是学会象棋的下棋规则的&#xff0c;师傅是二舅。我最早的对手就是同学波仔。波仔比我略早学会象棋&#xff0c;总用连珠炮欺负我&#xff0c;开局几步棋就把我将死。我不知道怎么破解。轮到我先走时&#xff0c;…

几个排序器的verilog及其资源占用、延时分析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 因为课题需要&#xff0c;调研了几个快速排序方法&#xff0c;并手写或者改进了若干待测试对象&#xff0c;包括记分板型冒泡排序&#xff08;这个是别人的&#xff09…

Spring Security实现用户认证二:前后端分离时自定义返回Json内容

Spring Security实现用户认证二&#xff1a;前后端分离时自定义返回Json内容 1 前后端分离2 准备工作依赖WebSecurityConfig配置类 2 自定义登录页面2.1 Spring Security的默认登录页面2.2 自定义配置formLogin 3 自定义登录成功处理器4 自定义登录失败处理器5 自定义登出处理器…

如何快速找出文件夹里的全部带有中文纯中文的文件

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 步骤 1、打开工具&#xff0c;切换到批量复制文件 2、鼠标移到右侧&#xff0c;点击搜索添加 3、设定查找范围、指定为文件、勾选 包含全部子文件夹&#x…

254 基于matlab的钢筋混凝土非线性分析

基于matlab的钢筋混凝土非线性分析&#xff0c;根据梁本构关系&#xff0c;然后进行非线性分析&#xff0c;绘制弯矩-曲率曲线。可设置梁的截面尺寸、混凝土本构&#xff0c;钢筋截面面积等相关参数&#xff0c;程序已调通&#xff0c;可直接运行。 254 钢筋混凝土非线性分析 弯…

回文数[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个整数x&#xff0c;如果x是一个回文整数&#xff0c;返回true&#xff1b;否则返回false。回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。例如&#xff0c;121是…

单位个人如何向期刊投稿发表文章?

在单位担任信息宣传员一职以来,我深感肩上的责任重大。每月的对外信息宣传投稿不仅是工作的核心,更是衡量我们部门成效的重要指标。起初,我满腔热血,以为只要勤勉努力,将精心撰写的稿件投至各大报社、报纸期刊的官方邮箱,就能顺利登上版面,赢得读者的青睐。然而,现实远比理想骨…

最小覆盖子串 ---- 滑动窗口

题目链接 题目: 分析: 当我们找到一组符合的子字符串时, 找下一组让left, 那么剩余的子字符串要么还符合条件, 要么少了一种字符, right一定不用回退, 所以可以使用滑动窗口因为题目中说字符串中自包含英文字母, 所以我们可以使用hash数组 定义left 0;right 0;进窗口进窗口…

如何为没有域名的IP地址申请SSL证书

为没有域名的IP地址申请SSL证书的流程相对直接&#xff0c;但需要确保满足一些特定条件。以下是简化的步骤&#xff1a; 1、确保IP地址是公网IP&#xff1a;你必须拥有一个固定的公网IP地址&#xff0c;因为私有IP地址无法用于申请SSL证书。 2、选择证书颁发机构&#xff08;…