UnityVR--机械臂场景12-简单流水线应用4

news2024/11/25 6:59:39

目录

一. 手爪

二. 红外线传感器

三. 工件生成器

四. 总结


  上一篇已经实现了机械臂各种动作的控制,本篇实现一下其余的组成部分,比如手爪、传感器和自动放置工件等。

一. 手爪

  手爪的模型调整就不多说了,需要设置的是Rigidbody、Collider,还需要判断手爪开合的方向和距离等, 详见机械臂场景3-手爪一文。

  实现的主要功能有:

  1. 当手爪上的碰撞器触发时,将工件设为手爪的子物体,跟随手爪一起移动;

  2. 当手爪打开时,将工件的父物体设置为空,并且发送给机械臂回零事件;

  这里直接放一下手爪的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Robot_ClawCtrl : MonoBehaviour
{
    public Transform finger1, finger2;//两个手指
    float MoveDis, OpenDis = 0.1f, CloseDis = 0.02f, curDir;
    //需要移动的距离,打开时的距离,闭合时的距离,当前距离
    public bool isHold = false; //是否抓到物体
    public Transform ClawTarget = null;  //手爪抓到的目标

    void Start()
    {
        EventManager.Instance.AddEvent(EventType.OnClawCtrl,this, OnClawControl);
    }
    public void OnClawControl(EventDataBase data)
    {
        EventDataClaw eventData = data as EventDataClaw;
        EClawType clawType = eventData.clawType;
        Transform target = eventData.target;
        float settime = eventData.waitTime;

        if(clawType==EClawType.Close)
           OnCloseClaw();    //如果闭合的时间有误,可以添加一个定时器

        if (clawType == EClawType.Open)  //添加了定时器的打开命令
        {
            if (timer <= settime)
                timer += Time.deltaTime;
            else
            {
                OnOpenClaw();
                timer = 0;
                return;
            }
        }
    }

    public void OnOpenClaw()
    {//打开手爪
        MoveDis = OpenDis;
        finger1.localPosition = new Vector3(0, 0, -OpenDis);
        finger2.localPosition = new Vector3(0, 0, OpenDis);
        if(ClawTarget!=null||isHold)
        {
            ClawTarget.transform.GetComponent<Rigidbody>().isKinematic = false;
            ClawTarget.transform.SetParent(null);
            isHold = false;
            //发送回零事件
            EventManager.Instance.SendEvent(EventType.OnArmCtrl, new EventDataArm
            {
                armType = EArmMoveType.Home,
                clawType = EClawType.Close,
                target = null,
                waitTime = 0
            });
            ClawTarget = null;
        }
    }

    public void OnCloseClaw()
    {//关闭手爪
        MoveDis = CloseDis;
        finger1.localPosition = new Vector3(0, 0, MoveDis);
        finger2.localPosition = new Vector3(0, 0, -MoveDis);
    }
    private void OnTriggerStay(Collider other)
    {
        ClawTarget = other.transform;
        //如果判断物体是工件
        //这里设置的是layer,判断tag也是可以的
        if (ClawTarget.gameObject.layer == LayerMask.NameToLayer("Load")&& ClawTarget!= null)
        {
            ClawTarget.transform.SetParent(transform);
            ClawTarget.transform.GetComponent<Rigidbody>().isKinematic = true;
            isHold = true;
            EventManager.Instance.SendEvent(EventType.OnArmCtrl, new EventDataArm 
            { armType = EArmMoveType.Put,target=ClawTarget,clawType=EClawType.Close,waitTime=0.1f});
        }
        else return;
    }

  可以将手爪的脚本挂在手爪节点上,和它的刚体放在一起。需要指明两个移动的手指,IsHold和ClawTarget两个参数不需要赋初值,仅用于调试时参看。

二. 红外线传感器

  当有工件经过传感器时发送事件,通知传送带停止和机械臂抓取,可以参照激光门伤害文中的射线检测,其他检测方式也很多。

  1. 建立两个立柱RayEmitter和RayReciever,用于指明发射和接收射线的位置。在这两个节点下再设置两个空节点point1和point2,作为真正的发射和接收位置;

   2. 传感器代码,其中最重要的API是物理系统中的射线检测LineCast。代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//传感器
public class RaySensor : MonoBehaviour
{
    public Transform emitter;
    public Transform receiver;
    void Start()
    {//使用工具包中的划线工具,画一条线段代表红外线
        Tools.DrawLine(transform, emitter.position, receiver.position, Color.cyan);
    }

    void FixedUpdate()
    {
        Physics.Linecast(emitter.position, receiver.position, out RaycastHit hit, 64);//64是Layer号
        if (hit.collider != null)
        {//当检测到工件时,发送传送带停止事件
            EventManager.Instance.SendEvent(EventType.OnConveyerCtrl, new EventDataConveyer
            {
                conveyerType = EConveyerType.Stop  //通知传送带停止
            });
            EventManager.Instance.SendEvent(EventType.OnArmCtrl, new EventDataArm
            {//发送机械臂抓取事件
                armType = EArmMoveType.Get,
                target = hit.transform,    //传输给机械臂抓取命令和目标
                clawType=EClawType.Close,  //发送手爪闭合的数据
                waitTime=0.2f  
            });
        }
        else
        {
            EventManager.Instance.SendEvent(EventType.OnConveyerCtrl, new EventDataConveyer
            {//传送带移动
                conveyerType = EConveyerType.Move
            });
        }
    }
}

三. 工件生成器

  它的作用是源源不断地将工件放在传送带上,使用在ResourceManager--资源管理中写的资源管理工具Resload.cs,将放置在Assets->Recources->BeltLoaders文件夹下的工件生成到传送带上去

   1. 场景中的设置:随便放置一个模型,作为生成器。重点是放置一个空节点(粉色的),所有工件都是从这个空节点中生成出来的。

   2. 工件生成器的代码LoadersManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;

public class LoadersManager : MonoBehaviour
{//Dispenser管理器
 //挂在控制节点上,管理所有生成的传送带负载工件
    public GameObject[] loaders;  //所有的负载工件放入数组
    public float passedTime=0, loaderRate=10; //计时器和间隔放负载的时间
    public bool ifLoad = true;    //是否可以发放工件的标记

    void Update()
    {
        passedTime+= Time.deltaTime;
        if (loaders.Length>0 && passedTime>=loaderRate&&ifLoad)
        {//当数组中有工件物体&时间到&红外线发送信号
            GameObject loader = Resources.Load<GameObject>("BeltLoaders/" + loaders[Random.Range(0,loaders.Length)].name); //随机加载一个工件
            if (loader == null)
                Debug.Log("没有找到物体");
            else
            {
                var go=GameObject.Instantiate(loader); //实例化物体
                go.transform.SetParent(transform);
                go.transform.localPosition = Vector3.zero;
                go.SetActive(true);
                go.AddComponent<Loaders>(); //生成的每一个工件都要挂上Loaders脚本
                passedTime = 0;
            }
        }  
    }
}

  3. 工件的脚本:上面的生成器在每生成一个工件时,除了设置工件的初始位置、父节点外,还要给每一个工件挂上Loaders.cs脚本,脚本中需要给工件加上刚体和碰撞体,代码如下:

public class Loaders : MonoBehaviour
{//挂在每一个被抓取工件上
    private Rigidbody rig;
    void Start()
    {
        rig = gameObject.AddComponent<Rigidbody>();
        rig.useGravity = true;
        gameObject.GetComponent<MeshCollider>().convex = true;
        gameObject.layer = LayerMask.NameToLayer("Load");
    }

  4. 最终效果:

四. 总结

  至此,传送带的场景搭建完毕,这只是一个简单的示例,很多情况都作为最简模型处理,并且在调试过程中还有累计误差和节拍误差等问题仍待解决。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在Visual Studio Code里导出8266固件

1.编辑 .vscode目录下 arduion.json 添加 一个配置项output即输出目录.当然你不设置其它软固件一样会生成,只是就不知道你能不能找到了.我的配置如下 当然这个路径你想写什么 就是什么 . 2. 切换到 arduion的项目文件 xxxx.ino.点击vsc右上的验证 即可在上面设置的目录下找到…

Nginx系列之 一 入门

目录 一、Nginx概述 二、yum安装 三、nginx.conf配置文件详解 3.1 全局块 3.2 events 块 3.3 HTTP 块 四、Nginx 常用命令 五、Nginx代理 4.1 正向代理 4.2 反向代理 六、Nginx的Master-Worker模式 6.1 Master进程的作用是&#xff1f; 6.2 Worker进程的作用是&am…

Layui动态树详解

Layui动态树详解 一、什么是动态树形&#xff1f;二、Layui动态树形基本使用三、动态加载数据4.案列1.实体类2.dao方法3.子实现类4.jsp页面 前言 在前端开发过程中&#xff0c;树形控件是比较常用的控件之一。而Layui框架中&#xff0c;也提供了基于jQuery的树形控件。除了普通…

小程序接口返回errno: 600009 errMsg: “request:fail invalid url “异常问题排查修复记录

小程序封装wxrequest更换域名baseurl后调用接口返回errMsg: "request:fail invalid url "&#xff0c;errno: 600009 控制台输出request的url也是正常的&#xff0c;起初怀疑是没配置域名白名单&#xff0c;但是小程序模拟器勾选了不校验合法域名的&#xff0c;而且…

PWM技术在嵌入式设备运行中的调节应用

PWM&#xff08;脉宽调制&#xff09;是一种通过改变信号的脉冲宽度来控制电压或电流的技术。PWM的等效电压是指将PWM信号转换为相应的直流电压或电流的数值。 在PWM信号中&#xff0c;占空比表示高电平和低电平脉冲宽度的比例。例如&#xff0c;一个占空比为50%的PWM信号意味…

ApiPost - 踩坑指南

1.应用场景 主要用于记录apipost遇到的坑, 以及为遇到的开发者提供参考. 2.学习/操作 1.文档阅读 chatgpt & 其他资料 ApiPost问答-localhost的坑的问题列表 localhost 不能正确解析为本机-ApiPost使用-ApiPost问答 断网了&#xff0c;还能ping通 127.0.0.1 吗&#xff1…

基于STM32的智能花盆系统设计与实现(华为云IOT)

一、设计需求 1.1 设计需求总结 伴随着人们生活水平以及现在科学技术的急速发展,越来越多的人喜欢在家庭栽培一些盆栽植物。可是当代生活节奏过快,导致盆栽大多数都不能得到很好的补充水分和阳光照射,从而导致盆栽的生活周期变短。如何利用现代电子技术设计一种可自动浇水…

Android Java代码与JNI交互 JNI访问Java类方法 (七)

🔥 Android Studio 版本 🔥 🔥 创建包含JNI的类 JNIAccessMethod.java 🔥 package com.cmake.ndk1.jni;import com.cmake.ndk1.model.Animal;public class JNIAccessMethod {static {System.loadLibrary("access-method-lib");}public native void access…

Spring Bean生命周期以及PostProcessor后置处理器

简介 所谓Bean的生命周期&#xff0c;就是一个 Bean 从创建到销毁&#xff0c;所经历的各种方法调用。 一个Bean的生命周期分为四个阶段&#xff1a; 实例化(Instantiation)&#xff1a;Spring容器负责创建Bean的实例&#xff0c;可以通过构造方法或者无参构造方法进行实例化…

电脑应用程序发生异常怎么办?

有时候我们打开电脑上面的某个软件时&#xff0c;会打不开&#xff0c;并且会弹出如下的错误提示“应用程序发生异常 未知的软件异常&#xff08;&#xff58;&#xff58;&#xff58;&#xff09;&#xff0c;位置为&#xff58;&#xff58;”。相信大多数的人在使用电脑的时…

springMVC(三)—— 整合SSM框架

环境 IDEA Mysql 5.7.19 tomcat 8 maven 3.8.4 数据库设计 CREATE DATABASE ssmbuild;USE ssmbuild;DROP TABLE IF EXISTS books;CREATE TABLE books(bookID INT(10) NOT NULL AUTO_INCREMENT COMMENT 书id,bookName VARCHAR(100) NOT NULL COMMENT 书名,bookCounts INT(…

github 最简单的使用步骤(个人学习记录~)

github 使用步骤&#xff1a; (11条消息) github新手用法详解&#xff08;建议收藏&#xff01;&#xff01;&#xff01;&#xff09;_github详解_怪 咖的博客-CSDN博客 1.获取ssh密钥 打开输入&#xff1a;ssh-keygen -t rsa -C “git账号” 输入之后一路Enter&#xff08…

Tomcat之高可用配置

Nginx搭配Tomcat实现负载均衡 传统模型下&#xff0c;一个项目部署在一台tomcat上&#xff0c;这个时候&#xff0c;假如tomcat因为服务器资源不够&#xff0c;突然挂机了&#xff0c;那么整个项目就无法使用。 Nginx就可以避免单台服务如果挂机&#xff0c;依然能保证服务正…

Python实现操作MySQL【增删改查】

闲话少叙,直接上操作! 一、准备工作 1.本地安装MySQL、Python(以3.6为例) 2.MySQL新建数据库【test】,新建表【user】,新建字段【name】【age】 3.建表方式:navicat工具 字段 二、Python操作—插入数据 #!/usr/bin/env # coding=utf-8import pymysql # Python 连…

Matlab+Yalmip求解优化问题(1)-入门学习

博客中所有内容均来源于自己学习过程中积累的经验以及对yalmip官方文档的翻译&#xff1a;YALMIP 1.Yalmip工具箱的下载与安装 1.1下载 Yalmip的作者是Johan Lfberg&#xff0c;是由Matlab平台编程实现的一个免费开源数学优化工具箱&#xff0c;在官网上就可以下载。官方下载…

Spark学习--4、键值对RDD数据分区、累加器、广播变量、SparkCore实战(Top10热门品类)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、键值对RDD数据分区1.1 Hash分区1.2 Ranger分区 二、累加器三、广播变量四、SparkCore实战4.1 数据准备4.2 需求&#xff1a;Top10热门品类4.2.1 需求分析&#…

问题解决:错误: 找不到或无法加载主类 App

问题描述尝试解决 问题描述 昨天刚刚把公司的项目源代码拉下来,结果全是报错,几百条.一看就是环境没配好. 今天刚刚解决配置问题,项目也没有报错了 今天在做项目的时候,我先跑一下看看项目能不能跑起来.结果一跑又报错了 错误:找不到或无法加载主类 xxx.BaasAppApplication原因…

profiles.active多环境开发、测试、部署

1、使用场景 在开始讲profiles.active配置时&#xff0c;我们先来考虑几个场景。 我们在开发过程中&#xff0c;经常会碰到多个环境&#xff0c;特别熟数据库&#xff0c;经常是有开发库&#xff0c;测试库&#xff0c;和生产库。一般我们都是连的开发库进行开发&#xff0c;…

四两拨千斤,训练大模型的PEFT方法

自然语言处理进入大语言模型&#xff08;Large Language Model, LLM&#xff09;时代之后&#xff0c;模型的参数量级越来越庞大&#xff0c;以稍早之前的GPT-3为例&#xff0c;它有175B即1亿7千5百万参数&#xff0c;而ChatGPT及后续模型则更大。一方面大语言模型解决自然语言…

用html+javascript打造公文一键排版系统4:一级标题排版

完成公文标题的排版后&#xff0c;我们要进行对正文中的标题进行处理。 一般正文中的标题分为四级&#xff0c;文中结构层次序数依次可以用“一、”“&#xff08;一&#xff09;”“1.”“&#xff08;1&#xff09;”标注&#xff1b;一般第一层用黑体字、第二层用楷体字加粗…