精华内容
下载资源
问答
  • 带有两个离轴系留拖车的移动机器人后退的运动控制方法
  • 机器人前进后退左转右转的c语音代码,PWM控制直流电机正反转
  • 小车基础定时器控制电机的代,有详细注释,深入理解pwm控制电机,总共连个文件,main。c和motor。c两个,方便理解与学习pwm与电机控制原理
  • 安川机器人 前进后退一般操作

     

     

     

    展开全文
  • 机器人小优本身没有直接控制功能,此文件是反编译了机器人本身的声控程序得到的,直接输入数字,就可以前进后退转弯,还能读出电池,和中断数据,压缩包里有编译好的apk,源码,截图
  • 80C51单片机的水下机器人主要由电气和机械两大部分组成,电气部分由8052单片机模块、无线遥控模块、输入驱动模块、输出驱动模块、等组成。机械部分由浮力桶、主甲板、下壳体、潜浮电机、前进左右电机等组成。其基本...
  • 这里给大家分享一个机器人控制程序(舵机型)。
  • 存在这样一种情况,即机器人运行程序中途被暂停了(不是中止),在再次启动之前,如何保证其仍在暂停之前等待的位置?
  • 最近做一个项目,要求使用虚拟摇杆控制机器人设备前进后退转弯,整个过程的思路不算复杂,写篇文章记录下大致思路 (1)黄色圆不动时候 小车速度为0 (2)拖动摇杆 拖动距离越大 小车速度越大 距离最大为灰色圆环...

    项目需求

    最近做一个项目,要求使用虚拟摇杆控制机器人设备前进后退转弯,整个过程的思路不算复杂,写篇文章记录下大致思路
    (1)黄色圆不动时候 小车速度为0
    (2)拖动摇杆 拖动距离越大 小车速度越大 距离最大为灰色圆环半径
    (3)向正上方拖动时候要求左右轮速度相同 小车前进
    (4)向正下方拖动时候要求左右轮速度相同 小车后退
    (5)向斜方向拖动时候要求小车向对应方向转弯
    (6)速度范围1200~1800

    一、360虚拟摇杆的实现

    中间黄色圆可以360度移动,最大运动距离为外部灰色圆环半径
    在这里插入图片描述

    思路

    以圆心为坐标系原点 分为四个象限 取两个速度 d/R y/R 为左右轮速度
    在第一象限运动 手指由左到右运动 小车则向右转弯 右轮速度减小 即此时右轮速度为小的那个y/R 左轮速度为大的那个 d/R
    其他象限同理
    R为灰色圆环半径,即运动最大距离
    在这里插入图片描述

    代码实现:

    package com.light.robotproject.views;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.PixelFormat;
    import android.graphics.Point;
    import android.graphics.PorterDuff.Mode;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceHolder.Callback;
    import android.view.SurfaceView;
    
    import com.light.robotproject.R;
    import com.light.robotproject.utils.MiscUtil;
    
    public class MySurfaceView2 extends SurfaceView implements Callback {
    
        private SurfaceHolder sfh;
        private Canvas canvas;
        private Paint paint;
        private Context mContext;
        private int coordinate;
        // 固定摇杆背景圆形的半径
        private int RockerCircleR, SmallRockerCircleR;
        // 摇杆的X,Y坐标以及摇杆的半径
        private float SmallRockerCircleX, SmallRockerCircleY;
    
        private RudderListener listener = null; // 事件回调接口
    
        public MySurfaceView2(Context context) {
            super(context);
        }
    
        public MySurfaceView2(Context context, AttributeSet as) {
            super(context, as);
            this.setKeepScreenOn(true);
            this.mContext = context;
            sfh = getHolder();
            sfh.addCallback(this);
            paint = new Paint();
            paint.setColor(Color.GREEN);
            paint.setAntiAlias(true);// 抗锯齿
            setFocusable(true);
            setFocusableInTouchMode(true);
            setZOrderOnTop(true);
            sfh.setFormat(PixelFormat.TRANSPARENT);// 设置背景透明
    
        }
    
        public void surfaceCreated(SurfaceHolder holder) {
    
            // 获得控件最小值
            int little = this.getWidth() < this.getHeight() ? this.getWidth()
                    : this.getHeight();
            // 根据屏幕大小绘制
            SmallRockerCircleX = SmallRockerCircleY = coordinate = little / 2;
            // 固定摇杆背景圆形的半径
            RockerCircleR = (int) (little * 0.35) - 20;
            // 摇杆的半径
            SmallRockerCircleR = (int) (little * 0.15);
            draw();
        }
    
        /***
         * 得到两点之间的弧度
         */
        public double getRad(float px1, float py1, float px2, float py2) {
            // 得到两点X的距离
            float x = px2 - px1;
            // 得到两点Y的距离
            float y = py1 - py2;
            // 算出斜边长
            float xie = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
            // 得到这个角度的余弦值(通过三角函数中的定理 :邻边/斜边=角度余弦值)
            float cosAngle = x / xie;
            // 通过反余弦定理获取到其角度的弧度
            float rad = (float) Math.acos(cosAngle);
            // 注意:当触屏的位置Y坐标<摇杆的Y坐标我们要取反值-0~-180
            if (py2 < py1) {
                rad = -rad;
            }
            return rad;
        }
    
        public double getAngle(float px1, float py1, float px2, float py2) {
            double angle = Math.toDegrees(Math.atan2(py2 - py1, px2 - px1));
            Log.i("tempRad角度==", angle + "");
            return angle;
    
        }
    
        public double getDistance(float px1, float py1, float px2, float py2) {
            // 计算两点间距离公式
            double juli = Math.sqrt(Math.abs((px2 - px1) * (px2 - px1)) + (py2 - py1) * (py2 - py1));
            System.out.println("两点间的距离是:" + juli);
            if (juli < 0) {
                juli = -juli;
            }
            return juli;
        }
    
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // 得到摇杆与触屏点所形成的角度
            double tempRad = getRad(coordinate, coordinate, event.getX(),
                    event.getY());
            getAngle(coordinate, coordinate, event.getX(),
                    event.getY());
            if (event.getAction() == MotionEvent.ACTION_DOWN
                    || event.getAction() == MotionEvent.ACTION_MOVE) {
                // 当触屏区域不在活动范围内
                if (Math.sqrt(Math.pow((coordinate - (int) event.getX()), 2)
                        + Math.pow((coordinate - (int) event.getY()), 2)) >= RockerCircleR) {
                    // 保证内部小圆运动的长度限制
                    getXY(coordinate, coordinate, RockerCircleR, tempRad);
                } else {// 如果小球中心点小于活动区域则随着用户触屏点移动即可
                    SmallRockerCircleX = (int) event.getX();
                    SmallRockerCircleY = (int) event.getY();
                }
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                // 当释放按键时摇杆要恢复摇杆的位置为初始位置
                SmallRockerCircleX = coordinate;
                SmallRockerCircleY = coordinate;
            }
            draw();
            //摇杆移动半径=圆环半径
            double roundRate = RockerCircleR;//85+15
    
            //触摸点到圆点的比例
            double ratio = getDistance(coordinate, coordinate, SmallRockerCircleX,
                    SmallRockerCircleX) / roundRate;
            //将坐标系旋转
    //        Point nowSmall=calcNewPoint(new Point((int) SmallRockerCircleX,(int) SmallRockerCircleY),new Point(coordinate,coordinate),-45);
            Point oldSmall = new Point((int) SmallRockerCircleX, (int) SmallRockerCircleY);
            //将圆点坐标从(150,150)移到中心点(0,0)
    //        double x = Math.abs(oldSmall.x) - coordinate;
    //        double y = Math.abs(oldSmall.y) - coordinate;
            /**
             * 获得两个速度
             * 一个根据圆心到摇杆半径距离比例来算d/r--为大速度
             * 一个根据y/r来算--为小速度
             */
            double distanceR=getDistance(SmallRockerCircleX,SmallRockerCircleY,coordinate,coordinate)/roundRate;
            double distanceY=Math.abs(coordinate-SmallRockerCircleY)/roundRate;
            Log.i("MySurfaceView2==", "dR==" + getDistance(SmallRockerCircleX,SmallRockerCircleY,coordinate,coordinate) + "   dY==" + (coordinate-SmallRockerCircleY) + "\r\ndistanceR==" + distanceR + "distanceY==" + distanceY);
    
            if (listener != null) {
                listener.onSteeringWheelChanged(SmallRockerCircleX,
                        SmallRockerCircleY, distanceR, distanceY);
            }
    
            return true;
        }
    
        /**
         * @param R       圆周运动的旋转点
         * @param centerX 旋转点X
         * @param centerY 旋转点Y
         * @param rad     旋转的弧度
         */
        public void getXY(float centerX, float centerY, float R, double rad) {
            // 获取圆周运动的X坐标
            SmallRockerCircleX = (float) (R * Math.cos(rad)) + centerX;
            // 获取圆周运动的Y坐标
            SmallRockerCircleY = (float) (R * Math.sin(rad)) + centerY;
            Log.i("MySurfaceView2==getXY", "x==" + SmallRockerCircleX + "y==" + SmallRockerCircleY);
        }
    
        public void draw() {
            try {
                canvas = sfh.lockCanvas();
                // canvas.drawColor(Color.WHITE);
                canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);// 清除屏幕
                drawCircle();
                drawRomot();
            } catch (Exception e) {
                // TODO: handle exception
            } finally {
                try {
                    if (canvas != null)
                        sfh.unlockCanvasAndPost(canvas);
                } catch (Exception e2) {
    
                }
            }
        }
    
        /**
         * 绘制圆环
         */
        public void drawCircle() {
            //绘制圆弧的边界
            RectF mRectF = new RectF();
            mRectF.left = coordinate - RockerCircleR /*- 20*/;
            mRectF.top = coordinate - RockerCircleR /*- 20*/;
            mRectF.right = coordinate + RockerCircleR /*+ 20*/;
            mRectF.bottom = coordinate + RockerCircleR /*+ 20*/;
            Paint ringNormalPaint = new Paint(paint);
            ringNormalPaint.setStyle(Paint.Style.STROKE);
            ringNormalPaint.setStrokeWidth(15);
            ringNormalPaint.setColor(mContext.getResources().getColor(R.color.Color_584832));
            canvas.drawArc(mRectF, 360, 360, false, ringNormalPaint);
        }
    
        /**
         * 绘制摇杆
         */
        public void drawRomot() {
            paint.setColor(mContext.getResources().getColor(R.color.Color_88FFFF00));
            // 绘制摇杆
            canvas.drawCircle(SmallRockerCircleX, SmallRockerCircleY,
                    SmallRockerCircleR + 10, paint);
            paint.setColor(Color.YELLOW);
            // 绘制摇杆
            canvas.drawCircle(SmallRockerCircleX, SmallRockerCircleY,
                    SmallRockerCircleR - 5, paint);
    
        }
    
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                   int height) {
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    
        // 设置回调接口
        public void setRudderListener(RudderListener rockerListener) {
            listener = rockerListener;
        }
    
        // 回调接口
        public interface RudderListener {
            void onSteeringWheelChanged(double x, double y, double distanceR, double distanceY);
    //        void onSteeringWheelChanged(double angle, double distanceRatio);
        }
    
        /**
         * 将点围绕圆点旋转45度  使得x=y点为最北点
         * 这样当拉到最上面时候  左右轮速度一样
         *
         * @param p
         * @param pCenter
         * @param angle
         * @return
         */
        private static Point calcNewPoint(Point p, Point pCenter, float angle) {
            // calc arc
            float l = (float) ((angle * Math.PI) / 180);
    
            //sin/cos value
            float cosv = (float) Math.cos(l);
            float sinv = (float) Math.sin(l);
    
            // calc new point
            float newX = (float) ((p.x - pCenter.x) * cosv - (p.y - pCenter.y) * sinv + pCenter.x);
            float newY = (float) ((p.x - pCenter.x) * sinv + (p.y - pCenter.y) * cosv + pCenter.y);
            return new Point((int) newX, (int) newY);
        }
    }
    
    
       <com.light.robotproject.views.MySurfaceView2
                android:id="@+id/remote1"
                android:layout_width="150dp"
                android:layout_height="150dp" />
    

    回调

     remote1.setRudderListener(object : MySurfaceView2.RudderListener {
                override fun onSteeringWheelChanged(
                    x: Double,
                    y: Double,
                    distanceR: Double,
                    distanceY: Double
                ) {
                    /**
                     * 手指触摸地  x,y
                     * distanceR  触摸点距离圆心distance/灰色圆环半径R
                     * distanceY  触摸点坐标y/灰色圆环半径R
                     * 在最北边时候distanceR=distanceY  即左右轮速度相同  设备向前运动
                     * 根据坐标分为四个象限  根据  x,y和坐标原点的大小  来判断左右转 
                     *  distanceR和distanceY   分别为左右轮速度    具体为哪个速度要根据象限来判断左转右转
                     * 例如左转时候 右轮速度>左轮速度
                     */
                    Log.i(
                        "RudderListener==",
                        "x==" + x + "y==" + y + "distanceR==" + distanceR + "distanceY==" + distanceY
                    )
                    //根据灵敏度算速度
                    getSpeed(x, y, distanceR, distanceY)
                }
    
            })
    
    

    获取速度

     /**
         * 根据象限区域判断左右轮速度归属
         * 圆心为(150,150)
         */
         var minSpeed=1200
         var maxSpeed=1800
        fun setSpeed(
            x: Double,
            y: Double,
            distanceR: Double,
            distanceY: Double,
            minSpeed: Int,
            maxSpeed: Int
        ) {
            var center = 150  //摇杆中心坐标(150,150)
            var speedBig = getRealSpeed(distanceR, minSpeed, maxSpeed)
            var speedSmall = getRealSpeed(distanceY, minSpeed, maxSpeed)
            if ((x > center && y < center) || (x > center && y > center)) { //第一、四象限方向  右转、右退  左轮>右轮
                ch1Speed = speedBig
                ch2Speed = speedSmall
            } else if ((x < center && y < center) || (x < center && y > center)) {//第二、三象限方向 左前、左退  右轮>左轮
                ch1Speed = speedSmall
                ch2Speed = speedBig
            }
            if (x == 150.0 && y == 150.0) {
                ch1Speed = 0.0
                ch2Speed = 0.0
            }
            Log.i("获取转速==", "左轮ch1Speed==" + ch1Speed + "右轮ch2Speed==" + ch2Speed)
        }
    

    中间踩的坑

    刚开始思考这个算法时候觉得很难,我把方向对准在圆上,发现要找规律对我自己这个数学水平来说很难很难,后来在同事的提醒下,将方向转为线性,突然发现茅塞顿开,由此可见处理问题的时候还是不能让自己钻牛角尖,集思广益,自己想不通的东西,别人一句话就搞定了。

    展开全文
  • 当前方具有障碍物,障碍物会反射红外线讯号,再确认接收的讯号是否与发出的编码相同,就可以探查前方是否具有障碍物,如果有障碍物就令机器人后退,避免撞上。 另外2路PWM用来控制LED以及蜂鸣器。藉由控制PWM的...
  • 本代码是当时水下机器人做的一个项目,实测代码可以用。如有不足之处,请与作者联系。
  • 上篇文章搞定了虚拟摇杆以及左右轮速度算法,接下来就是连接硬件以及向硬件提交信息 获得串口通信串儿 (1)串口通讯 (2)通讯规则: 1、协议格式:(8字节) [startbyte] [data1][data2]…[data22][flags][endbyte...

    上篇文章搞定了虚拟摇杆以及左右轮速度算法,接下来就是连接硬件以及向硬件提交信息

    获得串口通信串儿

    (1)串口通讯
    (2)通讯规则:
    1、协议格式:(8字节)
    [startbyte] [data1][data2]…[data22][flags][endbyte]
    startbyte=0x0f;
    endbyte=0x00;
    flags标志位我没有用到;
    data1…data22:对应16个通道(ch1-ch16),每个通道11bit

    2、需要的是data数据 22*8位
    [startbyte] [data1] [data2] … [data22] [flags][endbyte]
    startbyte = 11110000 b (0xF0)

    //228==1611
    [data1] [data2] … [data22] = [ch1,11bit] [ch2,11bit] … [ch16,11bit](ch#= 0 bis )

    需要16个通道 规定ch1=左轮速度,ch2=右轮速度,ch5=武器速度
    [ch1,11bit] [ch2,11bit] … [ch16,11bit](ch#= 0 bis )
    通道为11位二进制数据
    例如1200对应的二进制通道数据为10010110000

    获取对应的data串儿代码

    public static void main(code1Int:Int,code2Int:Int,code5Int:Int) throws IOException {
    		String code = "00000000000";
    		String code1 = Integer.toBinaryString(code1Int); //通道1--二进制
    		String code2 = Integer.toBinaryString(code2Int); //通道2
    		String code5 = Integer.toBinaryString(code5Int); //通道5
    		System.out.println(code1);
    		System.out.println(code2);
    		System.out.println(code5);
    		Integer i = 0;
    		String io = code1 + code2;
    		while(i < 14){
    			i++;
    			if(i.equals(2)){
    				io += code5;
    				continue;
    			}
    			io += code;
    		}
    		System.out.println(io);
    		i = 0;
    		Integer beginIndex = 0;
    		String[] str = new String[22];
    		while(i < 22){
    			Integer endIndex = beginIndex + 8;
    			str[i] = io.substring(beginIndex, endIndex);
    			beginIndex = endIndex;
    			i++;
    		}
    		System.out.println(Arrays.toString(str));
    		String endString = "";
    		for(String c : str){
    			Integer six = Integer.parseInt(c, 2);
    			String ipi = Integer.toHexString(six);
    			if(ipi.equals("0")){
    				ipi = "00";
    			}
    			endString += ipi;
    			System.out.println(ipi);
    			
    		}
    		endString = "0f" + endString + "0000";
    		System.out.println(endString);
    		Log.i("App_Tcp==", "endString=" + endString);
    	
    	}
    

    == endString==
    0fa95fcea80035f424000003f310f0540000000000000000000000000000000000

    通信

    由于项目要求实时性比较高,所以采取App直接连接硬件的方案
    采用Socket直接连接IP和端口号
    实现方法:
    安卓Socket的使用

    展开全文
  • 路径规划是移动机器人的应用程序S的关键问题之一。在未知动态环境中进行路径规划的传统方法通常只规划一个步骤,而不是多个控制步骤。本文提出了一种具有多个控制步骤的方法,该方法集成了用于移动机器人路径规划的...
  • 3 前进/后退操作  4 SVSPOTMOV(间隙动作)命令  5 空打命令  6 焊钳更换  7 焊钳轴动作  8 焊接结束解除  根据示教位置的数值输入进行编辑(NC 定位装置)  10 作业原点信号输出设定  ...
  • 该运动控制器由STC12C5A60S2单片机和舵机组成,采用多舵机分时控制的方法,机器人能实现按所设计的步态规划进行前进、后退、左转、右转等动作;同时添加了语音模块,机器人能在预定程序下随音乐进行舞蹈动作。
  • 另一方面,为了使机器人在首次探索未知环境时也能顺利抵达目标点,提出3种不同情况下的子目标搜索策略,包括无障碍环境下的直达策略、扫到边界点时的最短距离策略和扫不到边界点时的后退策略,这3种策略使机器人能够完成...
  • 由于某些绳索或杆工作的位置处于高空,而且需要定期检测和维护,用人力进行检测十分不方便并且容易发生事故。基于这个目的本文设计了一...机器人采用AT89c52单片机进行控制,通过遥控可以实现启停、前进、后退等功能。
  • 机器人运动控制程序

    热门讨论 2011-11-03 21:36:38
    利用MFC框架编写程序控制机器人的运动,包括前进后退左转右转
  • VJC案例-沿墙走

    千次阅读 2019-11-28 19:21:24
    项目内容:机器人沿着墙壁行走(采用左手规则或者右手规则)。 相关模块:启动电机、延时等待、停止电机、红外测障、碰撞检测、直行、转向、永远循环。 程序分析 沿墙走,顾名思义,即机器人靠近墙壁行走。采用...

    沿墙走

    项目内容:机器人沿着墙壁行走(采用左手规则或者右手规则)。
    相关模块:启动电机、延时等待、停止电机、红外测障、碰撞检测、直行、转向、永远循环。

    程序分析
    沿墙走,顾名思义,即机器人靠近墙壁行走。采用左手规则时,墙壁在机器人的左边;而采用右手规则时,墙壁在机器人的右边。下面以左手规则为例加以说明。
    在这里插入图片描述

    如图所示,要实现沿墙走,机器人可以采取划弧线的方法,边前进边检测墙壁。机器人如果发现前方有障碍物,说明正对着墙壁了,就右转约90度;如果发现左方有障碍物,说明机器人左侧对着墙壁了,就右转约60度;否则就划弧线前进。有时候机器人会撞上墙壁,为此机器人还需具有处理碰撞的功能。在程序中,我们让机器人一旦检测到碰撞,就后退一点,并右转约60度。沿墙走的例程如下图所示。
    在这里插入图片描述

    参数设置
    “红外测障”模块:检测完成后,进行条件判断,条件表达式为
    红外变量一 == 左
    “条件判断”模块:条件表达式为
    红外变量一 == 前
    “启动电机”模块:左电机功率20,右电机功率30。
    “延时等待”模块:时间0.05秒。
    “碰撞检测”模块:条件表达式为
    碰撞变量!=无
    其余模块的参数自行设置,并需反复调整,直至满意为止。
    仿真运行
    仿真运行时,加载单房间场地、标准灭火场地、走迷宫场地均可。读者也可以自己创建一个场地,让机器人在其中运行。

    展开全文
  • 这是现代控制理论番外篇的第一篇:主要围绕机器人系统的状态空间模型展开介绍。 建立机器人系统的数学模型是使用计算机控制机器人的第一步。主要分为如下五个部分: 为了使内容尽可能形象,这里不介绍具体推导...
  • 移动机器人拖车后退路径跟踪控制研究 非常详细
  • 实现汽车智能化的技术非常多, 本文利用目前比较热门的技术语音控制技术, 实现小车自动前进、后退、左拐、右拐等, 当然所设计的小车只是智能汽车的微模型, 还处于模拟演示阶段, 要真正实现智能汽车为人服务还有...
  • 这是一个通过 Node-RED 控制机器人或汽车的应用程序。 它内置于 Intel XDK,您可以导入和构建 APK。 用法: 输入 MQTT 服务器的 IP 地址和端口,然后按连接。 例如 192.168.123.4:8080 MQTT 主题应称为“测试”...
  • 可以前进后退,左右转弯和全自由度摆动手臂,能作弯腰和转身的动作,头部也可转动. 有完整的舞蹈程序,能随音乐翩翩起舞,动作协调、灵活 、准确。 舞蹈机器人系统设计框图 舞蹈机器人实物图展示: : 附件内容截图...
  • Android实现智能聊天机器人

    千次阅读 多人点赞 2020-06-11 14:40:20
    为了更好地调节心情提高生活质量,我们开发了一款基于Android系统的智能聊天机器人,它能够与用户智能对话。如此智能的效果,涉及到对用户语义理解,以及对海量信息的精准搜索和分析,这点我们短时间无法做到,但是...
  • 机器人建模与仿真

    千次阅读 2019-12-29 11:06:50
    urdf描述机器人模型问题所在? 模型冗长,重复多 修改参数麻烦,不便于二次开发 没有参数计算功能 等等… urdf模型的进化版本——xacro模型文件 精简模型代码 创建宏定义 文件包含 ...
  • 实验结果表明,本文所研制的控制系统能够很好地完成机器人的前进、后退、停止、转弯和变结构等控制任务,且控制系统工作可靠,性能稳定,直流无刷电机动态响应状态良好,步进电机运行平滑,能够很好地满足机器人的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,878
精华内容 1,151
关键字:

机器人后退