1、前记:

人机交互的方式--键盘开关、鼠标、触摸屏、体感传感器(Kinect、leap motion)语音识别等的使用大大促进人与机器的交互过程。这里记录鼠标事件与MATLAB的结合,为后期机器人仿真控制打下基础---如鼠标直接拖动机器人运动(像很多机器人仿真软件里的作用一样,如Robotstudio、soldworks、proe\core、Adams等)。
这是写在 MATLAB鼠标事件应用(记录)之中的前言部分。如今时间过去了这么久,原本打算在MATLAB中自己造轮子实现一个能拖拽完成机器人运动的交互功能,当然自己足够菜且没有足够的时间所以没能实现。但去年在介绍MATLAB机器人系统工具箱【MATLAB 2020b版本发布,下载试用版并上手使用记录。】的时候发现官网已经使用了interactiveRigidBodyTree对刚体树进行拖拽示教的功能。

lbr = importrobot('iiwa14.urdf');
lbr.Gravity=[0 0 -9.80665];
iviz = interactiveRigidBodyTree(lbr);

                                                      GIF5

关于利用鼠标的轨迹只是简单的完成了一个写字的demo:Robot write words Using Robotics toolbox

而且这个里面使用的是前面链接中的第4个例子,将数据保存后作为机器人逆解的输入,当然这里需要对数据进行scaling确保在机器人的可达空间。

为了方便,在此同样贴出鼠标轨迹的代码:

function  MouseDraw(action)
% MouseDraw 本例展示如何以Handle Graphics来设定滑鼠事件
% (MouseDraw Events)的反应指令(Callbacks)
 
% 本程序在鼠标移动非常快时,不会造成画“断线”
% global不能传矩阵
global InitialX InitialY FigHandle
if nargin == 0, action = 'start';   
end
 
switch(action)
    %%开启图形视窗
    case 'start'
        FigHandle = figure('WindowButtonDownFcn','MouseDraw down');
        axis([-600 600 -600 600]);    % 设定图轴范围
%         axis off;
        grid on;
        box on;     % 将图轴加上图框
        title('手写体输入窗');
% %         fprintf('start');
        %%设定滑鼠按钮被按下时的反应指令为「MouseDraw down」
        % set(gcf, 'WindowButtonDownFcn', 'MouseDraw down');  
        dlmwrite('IXT.txt', 10, 'delimiter', '\t', 'precision', 10);
        dlmwrite('IZT.txt', 10, 'delimiter', '\t', 'precision', 10);
        %%滑鼠按钮被按下时的反应指令
    case 'down'
        if strcmp(get(FigHandle, 'SelectionType'), 'normal')    %如果是左键
            set(FigHandle,'pointer','hand');      
            CurPiont = get(gca, 'CurrentPoint');
            InitialX = CurPiont(1,1);
            InitialY = CurPiont(1,2);
            dlmwrite('IXT.txt', InitialX, '-append', 'delimiter', '\t', 'precision', 10);
            dlmwrite('IZT.txt', InitialY, '-append', 'delimiter', '\t', 'precision', 10);
            % 列印「MouseDraw down!」讯息
% %             fprintf('MouseDraw down!\n');
            % 设定滑鼠移动时的反应指令为「MouseDraw move」
            set(gcf, 'WindowButtonMotionFcn', 'MouseDraw move');
            set(gcf, 'WindowButtonUpFcn', 'MouseDraw up');
        elseif strcmp(get(FigHandle, 'SelectionType'), 'alt')   % 如果是右键
            set(FigHandle, 'Pointer', 'arrow');
            set( FigHandle, 'WindowButtonMotionFcn', '')
            set(FigHandle, 'WindowButtonUpFcn', '')
            fprintf('MouseDraw right button down!\n');
            ImageX = importdata('IXT.txt');
            ImageY = importdata('IZT.txt');
            InputImage = ones(imSize);
            roundX = round(ImageX);
            roundY = round(ImageY);
            for k = 1:size(ImageX,1)
                if 0<roundX(k) && roundX(k)<imSize && 0<roundY(k) && roundY(k)<imSize
                    InputImage(roundX(k)-1:roundX(k)+2, roundY(k)-1:roundY(k)+2) = 0;
                end
            end
            InputImage = imrotate(InputImage,180);       % 图像旋转
            figure(2);
            imshow(InputImage);
        end
    %%滑鼠移动时的反应指令
    case 'move'
        CurPiont = get(gca, 'CurrentPoint');
        X = CurPiont(1,1);
        Y = CurPiont(1,2);
        % 当鼠标移动较快时,不会出现离散点。
        % 利用y=kx+b直线方程实现。
        x_gap = 1;    % 定义x方向增量
        y_gap = 1;    % 定义y方向增量
        if X > InitialX
            step_x = x_gap;
        else
            step_x = -x_gap;
        end
        if Y > InitialY
            step_y = y_gap;
        else
            step_y = -y_gap;
        end  
        % 定义x,y的变化范围和步长
        if abs(X-InitialX) < 0.1        % 线平行于y轴,即斜率不存在时
            iy = InitialY:step_y:Y;
            ix = X.*ones(1,size(iy,2));
        else
            ix = InitialX:step_x:X ;    % 定义x的变化范围和步长
            % 当斜率存在,即k = (Y-InitialY)/(X-InitialX) ~= 0
            iy = (Y-InitialY)/(X-InitialX).*(ix-InitialX)+InitialY;   
        end
        ImageX = [ix, X]; 
        ImageY = cat(2, iy, Y);
        line(ImageX,ImageY, 'marker', '.', 'markerSize',1, ...
            'LineStyle', '-', 'LineWidth', 2, 'Color', 'Blue');
        dlmwrite('IXT.txt', ImageX, '-append', 'delimiter', '\t', 'precision', 10);
        dlmwrite('IZT.txt', ImageY, '-append', 'delimiter', '\t', 'precision',10);
        InitialX = X;       %记住当前点坐标
        InitialY = Y;       %记住当前点坐标
        % 列印「MouseDraw is moving!」及滑鼠现在位置
        % fprintf('MouseDraw is moving! Current location = (%g, %g)\n', ...
          % CurPiont(1,1), CurPiont(1,2));
% %         fprintf('MouseDraw move!\n');
        % 设定滑鼠按钮被释放时的反应指令为「MouseDraw up」
        % set(gcf, 'WindowButtonUpFcn', 'MouseDraw up');
    %%滑鼠按钮被释放时的反应指令
    case 'up'
        % 清除滑鼠移动时的反应指令
        set(gcf, 'WindowButtonMotionFcn', '');
        % 清除滑鼠按钮被释放时的反应指令
        set(gcf, 'WindowButtonUpFcn', '');
        % 列印「MouseDraw up!」
% %         fprintf('MouseDraw up!\n');
end
end

能实现的功能如下展示:【以下的是留下轨迹后,将数据保存下来进行适当scaling,再输入到机器人逆解中,是非即时的。】PUMA仿真的代码链接:https://github.com/xiaosnowqiang/Matlab-for-PUMA-simulation

                                                         

2、如何实时获取鼠标移动数据

好了,前面的回忆差不多打住了。这里主要是记录实时的获取鼠标数据。

代码:

function mouseMove (object, eventdata)
clc
clear
set (gcf, 'WindowButtonMotionFcn', @mouseMove);
C = get (gca, 'CurrentPoint');
        X = C(1,1); 
        Y = C(1,2);
        line(X,Y, 'marker', '.', 'markerSize',5, ...
            'LineStyle', '-', 'LineWidth', 4, 'Color', 'Blue');
title(gca, ['(X,Y) = (', num2str(C(1,1)), ', ',num2str(C(1,2)), ')']);

效果:

                                           

这样有了一个想法就是如何根据这个基础较实时的生成的轨迹并优化后传给机器人末端?或者如何做轨迹的fitting?

先记录到这里................

此处留一个师兄大佬的demo,期望后面也做出这样的效果:

https://www.zhihu.com/zvideo/1360734078346706944

 

 

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐