grbl控制3轴机械臂 原理 实现 (二) 之3D机械臂模拟及实现

2023-11-07

参考文章:https://www.alanzucconi.com/2020/09/14/inverse-kinematics-in-3d/

 

上一篇:grbl控制3轴机械臂 原理 实现 (一) 之2D机械臂模拟及实现

 

3轴机械臂几何分析

    到目前为止,我们知道了如何在XY平面约束的情况下解决正逆运动学问题。从2D到3D的诀窍是重新使用2D解决方案。我们所介绍的这种3轴机械臂,一共3个轴,控制L1臂一个轴,控制L2臂一个轴,底座将L1和L2臂整体旋转为一个轴。很明显我们就多了一个整体旋转的维度。并且底座的旋转不会改变L1和L2臂的角度。

我们可以通过三个步骤解决问题:

  1. 绕Y轴旋转目标点,直到它位于XY平面上
  2. 移动机械臂L1和L2臂,使其到达目标该点,就像在2D模式下一样
  3. 通过沿Y轴的相反方向旋转整个机械臂来“撤消”旋转。

以上三个步骤逆解举例:

假设我们最终要得到的目标点是下图红色点(X^{'} ,Y^{'} , Z^{'} ),那么我们就要求得大臂旋转角度,小臂旋转角度,两臂在Y轴旋转角度

根据步骤一,绕Y轴旋转到X,Y平面上如下图,这样我们就能像处理2D机械臂一样

步骤二,在此平面上处理得到的L1,L2臂角度

步骤三,得到L1,L2臂的角度后,恢复Y轴的旋转,并求得Y轴的旋转角度

根据(X^{'} ,Y^{'} , Z^{'} )的值,求得紫色的线与X轴的夹角,这个夹角就是Y轴的旋转角度

至此,3个角度都求出来了。

 

实际上,旋转Y轴是为了方便理解,实际应用中,我们可以认为(X^{'} ,Y^{'} , Z^{'} )目标点所处于平面(W,Y)上

在这个(W,Y)平面上,直接按2D机械臂方式来算出L1,L2臂的角度即可,Y轴旋转角度计算照旧。

 

3D运动学逆解(Inverse kinematics)

我们把2d机械臂的图画到3d里面,可见原来我们的X边,变成了W边

根据坐标轴得知W边在(X,Z)平面,根据X边,W边,Z边是直角三角形,通过公式 A^2 + B^2 = C^2    求出W的长度

代入值得

Z^2 + X^2 = W^2     得     W = \sqrt{Z^2 + X^2}

再根据W边和Y边求出原点到(X,Y,Z)的距离为A边,W边,Y边,A边是直角三角形,依旧通过公式 A^2 + B^2 = C^2

代入值得

W^2 + Y^2 = A^2     得     A = \sqrt{W^2 + Y^2}   代入上面W得  A = \sqrt{Z^2 + X^2 + Y^2}

接下来就和2d机械臂一样了

\cos(\theta T) = \frac{W}{A}    代入以上公式得    \cos(\theta T) = \frac{\sqrt{Z^2 + X^2}}{\sqrt{Z^2 + X^2 + Y^2}}

 \theta T = \arccos(\frac{\sqrt{Z^2 + X^2}}{\sqrt{Z^2 + X^2 + Y^2}})

余弦定理公式:

A^2 = B^2 + C^2 - 2BC\cos(\alpha ) 

根据余弦定理,将值代入公式得

L2^2 = L1^2 + A^2 - 2L1A\cos(\theta 1-\theta T)

L2^2 = L1^2 + (\sqrt{Z^2 + X^2 + Y^2})^2 - 2L1\sqrt{Z^2 + X^2 + Y^2}\cos(\theta 1-\theta T)

 

2L1\sqrt{Z^2 + X^2 + Y^2} \cos(\theta 1 - \theta T) = L1^2 + Z^2 + X^2 + Y^2 - L2^2

 

\cos (\theta1 - \theta T) = \frac{L1^2 + Z^2 + X^2 + Y^2 - L2^2}{2L1 \sqrt{Z^2 + X^2 + Y^2}}

 

\theta1 = \arccos( \frac{L1^2 + Z^2 + X^2 + Y^2 - L2^2}{2L1 \sqrt{Z^2 + X^2 + Y^2}}) + \theta T


同上根据余弦定理:

A^2 = L1^2 +L2^2 - 2L1L2 \ cos(180-\theta 2)

(\sqrt{Z^2+X^2+Y^2})^2 = L1^2 +L2^2 - 2L1L2 \ cos(180-\theta 2)

 

2L1L2 \ cos(180-\theta 2) = L1^2 +L2^2 - Z^2-X^2-Y^2

 

\cos(180 - \theta2) = - \cos(\theta2) = \frac{L1^2 + L2^2 - Z^2 - X^2 - Y^2}{2L1L2}


有:

\theta2 = \arccos(\frac{Z^2 + X^2 + Y^2 - L1^2 - L2^2}{2L1L2})

 

\theta 3是X轴到W边的角度,我们用三角函数来求\theta 3

Z边,X边,W边组成一个直角三角形,则

 

\tan(\theta 3) = \frac{Z}{X}     得   \theta 3 = \arctan(\frac{Z}{X})

 

这就求出3D机械臂的三个旋转角度了。

 

 

3D运动学正解(Forward kinematics)

对于3D机械臂的运动学正解,依旧可以和2D机械臂的方法。

首先我们已知L1,L2臂的臂长,L1,L2臂的角度和机械臂在Y轴旋转的角度,求坐标(X,Y,Z)

首先和2D机械臂一样,我们先求X,Y的坐标,在这里就是W,Y平面,就是求W和Y的值。

w1,w2,y1,y2分别是浅蓝色线段部分

由于w1和w2是平行的,所以L1和w1所成角度,和L1和w2所成角度相同,所以有

\theta3 = 90 - \theta1

根据三角函数:

w1 = \cos(\theta 1) L1

w2 = \sin(\theta3 + \theta2)L2

y1 = \sin(\theta1)L1

y2 = \cos(\theta3 + \theta2)L2

W =w1 + w2         代入上式得          W = \cos(\theta 1) L1 + \sin(\theta3 + \theta2)L2 

 

Y = y1 + y2          代入上式得          Y = \sin(\theta1)L1 + \cos(\theta3 + \theta2)L2

然后根据W的值,求X和Z的值

\sin(\theta 4) = \frac{Z}{W}       得     Z = \sin(\theta 4 ) W

 \cos(\theta 4) = \frac{X}{W}       得     X = \cos(\theta 4 ) W

至此求得X,Y,Z的值

 

软件模拟实现

这里用的unity进行的模拟,通过unity里面的父子组件关系,L1旋转可以带动其子组件L2一起旋转。所以一个臂是由两部分组成的joint和arm如图

这样把两个臂组装起来,再把他们绑在一个原点方块this上

 它们的父子关系是

  • this
    • joint0
      • arm0
      • joint1
        • arm1

 

组合好后的样子

此脚本放在this方块上,并把joint0,joint1,的transform拖到脚本的公共变量上

代码实现:

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



public class ik : MonoBehaviour {




    //[Header("Joints")]
    public Transform Joint0;
    public Transform Joint1;
    public Transform Hand;

    //[Header("Target")]
    public Transform Target;


    private float length0, L1;
    private float length1, L2;

    private float L1_2, L2_2;

    private int X_AXIS = 0;
    private int Y_AXIS = 1;
    private int Z_AXIS = 2;

    private float SCARA_OFFSET_X = 0;
    private float SCARA_OFFSET_Y = 0.72f;
    private float SCARA_OFFSET_Z = 0;

    public bool angle_mode = false;

    private float[] cartesian = new float[3], f_scara = new float[3];


    void Start()
    {
        length0 = Vector3.Distance(Joint0.position, Joint1.position);
        length1 = Vector3.Distance(Joint1.position, Hand.position);
        L1 = length0;
        L2 = length1;
        L1_2 = sq(L1);
        L2_2 = sq(L2);


    }




    // Update is called once per frame
    void Update() {






        float length2 = Vector3.Distance(Joint0.position, Target.position);

        if (length2 > length0 + length1 - 0.3f)
        {

        }
        else
        {
            cartesian[0] = Target.position.x;
            cartesian[1] = Target.position.y;
            cartesian[2] = Target.position.z;

            inverse_kinematics(cartesian, f_scara);

            float[] cart = new float[3];
            float[] scar = new float[3];

            scar = (float [])f_scara.Clone();

            forward_kinematics_SCARA(scar, cart);
            Debug.Log("x:" + cart[0]);
            Debug.Log("y:" + cart[1]);
            Debug.Log("z:" + cart[2]);
        }

        Joint0.transform.localEulerAngles = new Vector3(0, 0, 0);
        Vector3 Euler0 = Joint0.transform.localEulerAngles;
        Euler0.x = 90f - f_scara[0];
        Joint0.transform.localEulerAngles = Euler0;

        Joint1.transform.localEulerAngles = new Vector3(0, 0, 0);
        Vector3 Euler1 = Joint1.transform.localEulerAngles;
        Euler1.x = f_scara[1];
        Joint1.transform.localEulerAngles = Euler1;

        this.transform.localEulerAngles = new Vector3(0, 0, 0);
        Vector3 Euler2 = this.transform.localEulerAngles;
        Euler2.y = f_scara[2];
        this.transform.localEulerAngles = Euler2;


    }


    float sq(float a)
    {
        return a * a;

    }


    // f_scara是大臂和小臂的角度,cartesian是坐标
    void inverse_kinematics(float[] cartesian, float[] f_scara)
    {
        /***********************robot arm****************************/

        //         y +  /z
        //           | /
        //           |/
        //           +-----+x

        float ROBOTARM_alpha, ROBOTARM_beta, ROBOTARM_cta, ROBOTARM_alphapsi, projectxyLength, X, Y, X_2, Y_2, sqrtx_2ay_2;

        //首先求得目标点 到 原点的距离
        //获取机械臂投射到xy平面的长度
        //length = sqrt(x*x + y*y)
        projectxyLength = Mathf.Sqrt(sq(cartesian[X_AXIS]) + sq(cartesian[Z_AXIS]));//对调yz,坐标系不同
                                                                                    //将3d机械臂变量变为2d机械臂的变量
                                                                                    //	projectxyLength长度为2d机械臂的X
        X = projectxyLength;
        X_2 = sq(X);
        Y = cartesian[Y_AXIS];//对调yz,坐标系不同
        Y_2 = sq(Y);
        sqrtx_2ay_2 = Mathf.Sqrt(X_2 + Y_2);
        //求得机械臂所在yz旋转平面的alphapsi角度
        ROBOTARM_alphapsi = Mathf.Acos(X / sqrtx_2ay_2);
        //如果坐标在平面以下,将alphapsi取反
        if (Y < 0)
        {
            ROBOTARM_alphapsi = -ROBOTARM_alphapsi;
        }

        //求得机械臂所在yz旋转平面的alpha角度,,即大臂到xy平面的角度(实际是弧度)
        ROBOTARM_alpha = Mathf.Acos((L1_2 + X_2 + Y_2 - L2_2) / (2 * L1 * sqrtx_2ay_2)) + ROBOTARM_alphapsi;
        //求得小臂的角度(实际是弧度)
        ROBOTARM_beta = Mathf.Acos((X_2 + Y_2 - L1_2 - L2_2) / (2 * L1 * L2));
        //求得整体机械臂的旋转角度(实际是弧度)
        ROBOTARM_cta = Mathf.Atan2(cartesian[X_AXIS], cartesian[Z_AXIS]);

        //如果不是角度模式
        if (!angle_mode)
        {
            f_scara[X_AXIS] = Mathf.Rad2Deg * ROBOTARM_alpha; //大臂旋转弧度转换为角度
            f_scara[Y_AXIS] = Mathf.Rad2Deg * ROBOTARM_beta;   //小臂旋转弧度转换为角度
            f_scara[Z_AXIS] = Mathf.Rad2Deg * ROBOTARM_cta;
        }
        //否则是角度模式
        else
        {
            f_scara[X_AXIS] = cartesian[X_AXIS];
            f_scara[Y_AXIS] = cartesian[Y_AXIS];
            f_scara[Z_AXIS] = cartesian[Z_AXIS];

        }
    }



    //传入值 f_scara是大臂和小臂的角度,cartesian是最终求得的坐标
    void forward_kinematics_SCARA(float [] f_scara, float [] cartesian)
    {
        /***********************robot arm****************************/
        float X, Y, Z;
        float project3D;
        //f_scara里面的0,1,2代表:大臂角度,小臂角度,旋转角度


        //         y +  /z
        //           | /
        //           |/
        //           +-----+x


        //unity 角度空间转换转换
        //f_scara[X_AXIS] = 90f - f_scara[X_AXIS];

        //2D机械臂朝向的方向,两臂投影到平台平面长度
        //Z = Mathf.Cos(Mathf.Deg2Rad * f_scara[X_AXIS]) * L1 + Mathf.Sin((Mathf.Deg2Rad * f_scara[Y_AXIS]) + (Mathf.Deg2Rad * 90) - (Mathf.Deg2Rad * f_scara[X_AXIS])) * L2;

        //3D 两臂投影到平台平面长度,通过三角函数转化为坐标轴方向长度
        project3D =  Mathf.Cos(Mathf.Deg2Rad * f_scara[X_AXIS]) * L1 + Mathf.Sin((Mathf.Deg2Rad * f_scara[Y_AXIS]) + (Mathf.Deg2Rad * 90) - (Mathf.Deg2Rad * f_scara[X_AXIS])) * L2;
        Z = Mathf.Cos((Mathf.Deg2Rad * f_scara[Z_AXIS])) * project3D;

        //垂直向上的方向
        Y = Mathf.Sin((Mathf.Deg2Rad * f_scara[X_AXIS])) * L1 + Mathf.Cos((Mathf.Deg2Rad * f_scara[Y_AXIS]) + (Mathf.Deg2Rad * 90) - (Mathf.Deg2Rad * f_scara[X_AXIS])) * L2;

        //2D 站机械臂后方看向它,它的右边方向
        //X = Mathf.Sin((Mathf.Deg2Rad * f_scara[Z_AXIS])) * Mathf.Cos((Mathf.Deg2Rad * f_scara[X_AXIS])) * L1 + Mathf.Sin((Mathf.Deg2Rad * f_scara[Y_AXIS]) + (Mathf.Deg2Rad * 90) - (Mathf.Deg2Rad * f_scara[X_AXIS])) * L2;

        //3D 站机械臂后方看向它,它的右边方向
        X = Mathf.Sin((Mathf.Deg2Rad * f_scara[Z_AXIS])) * project3D;




        cartesian[X_AXIS] = X + SCARA_OFFSET_X;  //求得机械手顶点的坐标
        cartesian[Y_AXIS] = Y + SCARA_OFFSET_Y;  //求得机械手顶点的坐标
        cartesian[Z_AXIS] = Z + SCARA_OFFSET_Z;		
		
    /***********************robot arm****************************/	
    }


}

实现效果演示

 

接下来介绍下GRBL,以及如何在GRBL上控制机械臂,以及机械臂控制的硬件细节

 

下一篇:grbl控制3轴机械臂 原理 实现 (三) 之如何通过步进电机控制机械臂、插补算法

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

grbl控制3轴机械臂 原理 实现 (二) 之3D机械臂模拟及实现 的相关文章

  • 【机器视觉系统】基于3DOF机械臂的五子棋机器人(1)

    基于3DOF机械臂的五子棋机器人 文章目录 基于3DOF机械臂的五子棋机器人 1 前言 2 机器视觉系统概述 2 1 机器 2 2 视觉 2 3 系统 3 系统组成概述 3 1 使用工具盘点 3 2 流程图 4 制作步骤建议 5 需要的知识
  • altium designer芯片引脚间距规则过小

    AD中芯片的引脚间距过小 例如stm32这种MCU 引脚又细又密 违反了默认间距规则 如上图所示的16mil 而触发绿色的报错 但是我们又不能因噎废食 而把整个PCB规则间距改大 因此最好的解决方案是 只修改这一个芯片的间距规则 依次点击
  • 一分钟带你快速认识S参数

    S 参数是SI与RF领域工程师必备的基础知识 大家很容易从网络或书本上找到S Y Z参数的说明 但即使如此 在相关领域打滚多年的人 仍然可能还是会被一些问题困扰着 你懂S参数吗 不懂的话 那么请继续往下看 S参数简介 S参数 也就是散射参数
  • ad中封装绿色解决办法

    1是在工具 检查规则中 把一些项取消检查
  • Type C --- 引脚图解

  • 电荷泵

    电荷泵 又称为电容式的开关稳压器 或开关电容DC DC变换器 无感式DC DC变换器 电荷泵采用电容作为开关和储能的元件 如图所示 S1与S3闭合 S2与S4断开 则Vin给电容充电 而后S1与S3断开 S2与S4闭合 则电容放电 此时Vo
  • ODrive踩坑(五)ODrive驱动云台电机、低齿槽转矩电机实现高精度定位

    前几篇介绍了ODrive在Windows下的使用环境搭建 驱动3508 5008无刷电机 TLE5012B AS5047P的ABI编码器配置 AS5047P SPI绝对值编码器配置 ODrive踩坑 一 windows下使用环境的搭建 od
  • arduino uno r3 机械臂

    1 硬件 arduino uno r3 改进板 sg90舵机 180度 x 4 JoyStick Shield PS2游戏摇杆扩展板 或者按键 遥杆模块 3D打印件 M3螺丝螺母 10mm 15mm 25mm 以及M2螺丝螺母 2 接线 开
  • openGL之API学习(二零二)glsl的smooth flat

    采用flat着色时 OpenGL将使用图元中某个顶点的颜色来渲染整个图元 通常情况下会选择图元的第一个或最后一个顶点的颜色作为该图元的颜色 在使用smooth着色时 OpenGL会独立的处理图元中各个顶点的颜色 对于线段图元 线段上各点的颜
  • turtle使用文档

    Turtle简介 Turtle库是Python语言中一个很流行的绘制图像的函数库 想象一个小乌龟 在一个横轴为x 纵轴为y的坐标系原点 0 0 位置开始 它根据一组函数指令的控制 在这个平面坐标系中移动 从而在它爬行的路径上绘制了图形 Tu
  • BOOST升压电路原理详解

    原文来自公众号 工程师看海 BOOST升压电源是利用开关管开通和关断的时间比率 维持稳定输出的一种开关电源 它以小型 轻量和高效率的特点被广泛应用在各行业电子设备找那个 是不可缺少的一种电源架构 公众号后台回复 boost仿真文件 Boos
  • 机械臂颜色识别案例

    大家好 我就是那个走在路上经常捡到宝的铁熊老师 那么今天捡到了啥好玩的东西呢 一台五自由度机械臂 从天而降出现在我面前 这话说出口 我自己都不信 哪有那么好的运气 其实这是朋友送我玩的 你也想要这台机械臂么 什么 你不要机械臂 你想要那个朋
  • 魔方机器人之硬件篇

    待续 点击打开链接 思睿硬件设计博客
  • 空间直角坐标系右手系和左手系的判定方法及绕轴旋转的正方向

    1 判定坐标系 右手大拇指指向z轴方向 其余四指由x轴握向y轴方向 如果成功 那么判定为右手系 左手大拇指指向z轴方向 其余四指由x轴握向y轴方向 如果成功 那么判定为左手系 坐标系的种类判断成功 那么接下来该判断旋转正方向 2 旋转正方向
  • Verilog HDL 语言笔记

    目录 一 基本语法 1 模块的结构 1 模块声明 2 端口定义 3 数据类型说明 4 逻辑功能描述 2 语言要素及数据类型 2 1语言要素 2 2 常量 2 3 变量和数据类型 2 4 参数 2 5 向量 2 6 存储器 2 7 运算符 3
  • [OpenAirInterface实战-15] :OAI 软件无线电USRP B210硬件详解

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 121088307 目录 第1章 通用无
  • 电巢携手武昌工学院工程能力实训顺利开班!

    为深化校企合作 产教融合打造新工科建设 提升学生工程实践能力 电巢工程能力实训班按照不同岗位类别 匹配对应的企业岗位任职能力要求对学生开展分级培养 以产业需求为导向 培养创新型 应用型人才 6月6日下午4时 深圳电巢联合武昌工学院信息工程学
  • 零基础如何入门数学建模?

    小羊简介 博客主页 小羊不会飞 年龄 20 大二在读 爱好 干饭 运动 码代码 看书 旅游 即将更新 1 手把手带你搭建个人博客网站 2 后台管理系统模块更新 感兴趣的朋友 赶紧上车吧 欢迎关注 点赞 收藏 留言 有任何疑问 欢迎留言讨论
  • 机械键盘按键失灵解决办法(亲测有效,不用换不用拆,5分钟搞定)

    机械键盘不灵的小伙伴们 有福音了 不用换不用拆 只需要一根牙签 一把美工刀 或者剪刀 一瓶酒精 或者免洗消毒液 就可以修好上百块钱的东西 5分钟搞定 这两天不知道为啥机械键盘的ctrl键居然失灵了 有时候可以有时候不好用 怎么回事 一个上百
  • ALLEGRO等长时如何将PIN DELAY和VIA长度计算在内

    在PCB设计中 对于时序要求严格的线路 Via和IC pin delay的长度必须得到重视 通过下面的操作 可将Via和Pin delay加入到线路长度的计算中 1st 计算Pin delay 打开Constraint Manager 选择

随机推荐

  • C语言学习打卡第8天

    一 函数第二部分的练习 1 有3 4的矩阵 初始化他并输出 还求出最大值输出 include
  • 计算机视觉算法——目标检测网络总结

    计算机视觉算法 目标检测网络总结 计算机视觉算法 目标检测网络总结 1 RCNN系列 1 1 RCNN 1 1 1 关键知识点 网络结构及特点 1 1 2 关键知识点 RCNN存在的问题 1 1 3 关键知识点 非极大值抑制算法 NMS 1
  • JAVA笔记_(Day04,Day05)函数&数组

    文章目录 函数 定义 练习 误区 重载 overload 重载选择题练习 函数的内存调用问题 数组 定义 数组的内存图解 数组的常见问题 应用 求和 最大值 将数组转成字符串 查表法 转十六进制 查表版 十六进制终极版 十进制转二进制 进制
  • Linux上搭建Jenkins

    Linux上搭建Jenkins 下面给出Linux上搭建Jenkins的环境 教你一步步搭建起来 1 Jenkins下载 Jenkins 下载网址 Download Jenkins Jenkins 最新版本 jenkins 1 514 al
  • ARM平台基于嵌入式Linux使用MIPI CSI-2接口

    标签 ARM Linux MIPI Camera NXP nVidia Toardex Apalis By Toradex 秦海 http www eefocus com toradex blog 16 05 384885 f19b5 ht
  • 最近学到的一些前端知识

    在Vue中使用v for不仅可以遍历数组 还可以遍历对象 当然也可以遍历字符串 还有在Vue中 不可以深度监听数组的变化 比如将数组arr某一项的值改变 在视图上不会发生变化 在网上找了很多方法 包括Vue set 原对象 位置 值 以及v
  • 文件上传漏洞upload-libs pass2

    文件上传漏洞upload libs pass2 首先查看源码 发现是后端PHP过滤 仅允许类型为image jpeg image png image gif的文件上传 将一句话木马的后缀改为jpg 上传图片并抓包 Send to Repea
  • 浅谈CUDA零拷贝内存

    今天看到有小伙伴提出了 零拷贝 的问题 由于本人以前用的也比较少 了解不多 因此打算好好研究一番 现做些总结 零拷贝内存是一种特殊形式的内存映射 它允许你将主机内存直接映射到GPU内存空间 因此 因此对GPU上的内存解引用时 如果是基于GP
  • word2010 数学公式/联立方程/大括号内方程组如何左对齐?

    如何在word中输入的联立方程使其条件左对齐 如输入 实现如下对齐 就是在每个逗号 前输入一个 号就可以了 注意这个逗号一定要是
  • cookie的path值的默认规则

    在项目中有时需要用cookie来保存用户信息 不论是在js代码还是java代码中 很多时候我们都只设置了cookie的name value和maxAge 而没有去管path 例如下面的 代码块1 是当一个用户首次访问网站的时候添加一个coo
  • PCL点云库学习笔记(可视化2)

    PCL点云库学习笔记 可视化 可视化 四 PCLPlotter 五 MFC 开发实例 可视化 四 PCLPlotter 4 1 绘制多项式 PCLPlotter提供了一个非常简单明了的图形绘制界面 可以在库中可视化各种重要的图 从多项式函数
  • 安克创新与亚马逊云科技成立联合创新实验室

    日前 全球化消费电子品牌企业安克创新 Anker 正式同亚马逊云科技成立联合创新实验室 在采用亚马逊云科技服务的基础上 推动安克创新将数据分析 机器学习等服务进行规模化应用 赋能业务创新 目前 双方通过联合创新实验室在智能广告投放等领域展开
  • Java Precondition类

    Public final class Preconditions extends Object 通过Precondition类 你可以声明你期望为真的表达式 就像在JUnit assertTrue调用时的断言 注意 在errorMessag
  • git rebase -i

    git rebase i 是一种交互式的 rebase 方式 其中 i 是 interactive 的简写 这种方式允许你修改一系列的 commit 信息 在 rebase 过程中有选择地选择 编辑或者合并 commit 在执行 git r
  • 剑指Offer—— 最小的K个数

    题目描述 输入n个整数 找出其中最小的K个数 例如输入4 5 1 6 2 7 3 8这8个数字 则最小的4个数字是1 2 3 4 第一种方法是全排序 先把数组进行排序 排序后依次输出最小的4个 时间复杂度为nlogn 第二种方法是的原理和快
  • MES是什么?有什么作用?

    近年来 随着JIT Just In Time BTO 面向订单生产 等新型生产模式的提出 以及客户 市场对产品质量提出更高要求 MES逐渐被发现重视 同时在网络经济泡沫的破碎后 企业开始认识到要从最基础的生产管理上提升竞争力 即只有将数据信
  • php工作量,区块链扫盲篇之使用PHP实现区块链(二) - 工作量证明

    1 前言 上一篇文章我们介绍了区块链的最基本数据结构 区块 而且还构建了一个最原始的区块链 但是现在我们很容易就可以向区块链中添加区块 这样有可能导致大量的区块在同时添加到区块链中 从而导致广播风暴 而且在分布式环境中 如果并发量太大会导致
  • 【测评】PaMu Unique真无线蓝牙耳机,国潮新时尚,年轻人的标配

    本文作者为体验师 喝酸奶舔盖斯基 首发于糖纸众测 目 录 测评信息 外观设计 通话降噪 CD音质 续航持久 佩戴舒适 测评信息 产品名称 神偷奶爸小黄人系列真无线蓝牙耳机 设备型号 T6D 辅测设备 荣耀MagicBook笔记本 小米8手机
  • Unity协程和线程的区别深入理解(附实验展示)

    Unity协程和线程的区别附实验展示 写在前面 协程 进程 线程的概念 进程与线程的区别 协程与线程的区别 实验1 协程中执行普通函数 实验2 协程中开启另一个协程 实验3 协程中开启WWW请求 实验4 一个脚本中多个协程访问临界资源 实验
  • grbl控制3轴机械臂 原理 实现 (二) 之3D机械臂模拟及实现

    参考文章 https www alanzucconi com 2020 09 14 inverse kinematics in 3d 上一篇 grbl控制3轴机械臂 原理 实现 一 之2D机械臂模拟及实现 3轴机械臂几何分析 到目前为止 我