webots与Matlab联合仿真中的错误记录(1)

废话

已经很久没有用过了,我的合伙人浑河学者最近要做自动驾驶仿真,我建议他使用webots来进行仿真,但是他想用matlab来写controller,这不,遇到问题了……

使用环境

  • win10系统
  • webots R2020a rev1 (官方发行版)
  • Matlab R2016a

问题叙述


要开始,请键入以下项之一: helpwin、helpdesk 或 demo。 有关产品信息,请访问 www.mathworks.com。 错误: 文件:D:\Program Files\Webots\lib\controller\matlab\launcher.m 行:29 列:50 输入字符不是 MATLAB 语句或表达式中的有效字符。


在这里插入图片描述

问题分析

先来看一下为什么会报launcher.m这个文件错误呢?在webots中,matlab调用的webotsAPI实际上是通过c API来实现的,这个调用操作实际上就是通过launcher.m来进行的,并且其中还自动配置了环境变量,省去了我们配环境的繁琐操作。在使用matlab写控制器之前,需要给matlab安装MinGW GCC,因为需要matlab与c的交互。对于安装过程这里不再赘述,但是此处有个坑需要强调一下:

MATLAB官网的安装包在安装的时候需要访问第三方MinGW网站来下载,但是实际上在安装的时候,matlab获取附加功能无法连接第三方网站(不知是否是我的matlab的问题),所以我们需要手动为matlab安装MinGW.

在目录D:\Program Files\Webots\lib\controller\matlab找到launcher.m,发现第29行语法使用双引号"",由于Matlab R2016不支持双引号字符串变量,当然会报错,Matlab R2019中不存在该问题。

在这里插入图片描述

手动安装MinGW,程序在附加功能管理里面找不到MinGW列表,所以我们直接屏蔽第28-32行代码即可。

在这里插入图片描述

等等,好像哪里不对劲!

在这里插入图片描述

这些脚本文件都是在lib\controller\matlab下,为啥launcher.m写的是'/lib/matlab'?此处必有猫腻!!!!

在这里插入图片描述

Ctrl+F全部把/lib/matlab替换成/lib/controller/matlab,完美!

注意第15行代码字符串需要改成../../..

在这里插入图片描述
在这里插入图片描述

save一下,你以为这就结束了?NO,还有一个文件需要修改:allincludes.h

同样的问题,路径对应错误:

在这里插入图片描述
在这里插入图片描述
继续Ctrl+F替换,保存!OK!!!

在这里插入图片描述

测试

在这里插入图片描述
在这里插入图片描述
相当完美!!!

继续废话

正当我准备去GitHub提交我修改的BUG时,发现已经有大佬在15day前修改过了,我哭了……

链接在这:https://github.com/cyberbotics/webots/pull/1378/files

所以我猜,下一个版本应该会修复这个BUG

贴上代码

launcher.m

% Launcher script for MATLAB Webots controllers

% useful env variables supplied by webots
WEBOTS_HOME = getenv('WEBOTS_HOME');
WEBOTS_CONTROLLER_NAME = getenv('WEBOTS_CONTROLLER_NAME');
WEBOTS_VERSION = getenv('WEBOTS_VERSION');

if isempty(WEBOTS_CONTROLLER_NAME)
  disp('Entering test mode (normally launcher.m should be called by Webots, not from the MATLAB command line)');
  disp(['Using MATLAB R' version('-release')]);
  cd('../../..');
  WEBOTS_HOME = pwd;
  [status, cmdout] = system('msys64/mingw64/bin/webots.exe --version');
  WEBOTS_VERSION = strrep(cmdout(17:end-1),'.','_');
  cd('lib/controller/matlab');
  disp(['Using Webots ' strrep(WEBOTS_VERSION,'_','.') ' from ' pwd ])
  test_mode = true;
else
  test_mode = false;
end

% add path to Webots API m-files
addpath([WEBOTS_HOME '/lib/controller/matlab']);

if ispc
  setenv('MINGWROOT', strcat(WEBOTS_HOME,'\\msys64\\mingw64'));
  libname = 'Controller';
%  installed_addons = matlab.addons.installedAddons;
%  installed = sum(installed_addons.Identifier == "ML_MINGW");
%  if installed <= 0 || matlab.addons.isAddonEnabled('ML_MINGW') <= 0
%    disp('The MATLAB "MinGW-w64 C/C++ Compiler" addon is not installed, please install it from: https://fr.mathworks.com/matlabcentral/fileexchange/52848-matlab-support-for-mingw-w64-c-c-compiler');
%  end
  addpath([WEBOTS_HOME '/msys64/mingw64/bin']);
else
  libname = 'libController';
  % add path to libController
  addpath([WEBOTS_HOME '/lib/controller']);
end

try
  % work in the system's temp dir so we have write access
  cd(tempdir); % that supports non-ASCII character since MATLAB 2016a

  % creates the base name of the protofile (without .m extension)
  % we make the name dependant on matlab and webots versions, so a new file will be generated for any version change
  % we need to replace the dots by underscores, because dots cause problems in the protofile
  protofile = strrep(strrep(['protofile_matlab_' version('-release') '_webots_' WEBOTS_VERSION], '.', '_'), ' ', '_');

  % another controller is currently generating the proto file: need to wait
  lockfile = 'webots_matlab_lock';
  counter = 1;
  while exist(lockfile, 'file')
    if (counter == 1)
      disp(['Waiting up to 5 seconds for ' tempdir lockfile ' to be deleted by another MATLAB instance.']);
    end
    pause(1);
    if (counter == 5)
      disp(['Deleting ' tempdir lockfile '...'])
      delete(lockfile);
    end
    counter = counter + 1;
  end

  libcontrollerloaded = false;

  if ~exist([protofile '.m'], 'file')

    % create a lock to prevent any other matlab controller from generating the proto file simultaneously
    fid = fopen(lockfile, 'w');
    fclose(fid);

    disp(['Creating: ' tempdir protofile '.m']);
    try
      loadlibrary( ...
        libname,'allincludes.h', ...
        'mfilename',protofile, ...
        'alias','libController', ...
        'addheader','accelerometer.h', ...
        'addheader','brake.h', ...
        'addheader','camera.h', ...
        'addheader','compass.h', ...
        'addheader','connector.h', ...
        'addheader','console.h', ...
        'addheader','device.h', ...
        'addheader','differential_wheels.h', ...
        'addheader','display.h', ...
        'addheader','distance_sensor.h', ...
        'addheader','emitter.h', ...
        'addheader','gps.h', ...
        'addheader','gyro.h', ...
        'addheader','inertial_unit.h', ...
        'addheader','joystick.h', ...
        'addheader','keyboard.h', ...
        'addheader','led.h', ...
        'addheader','lidar.h', ...
        'addheader','light_sensor.h', ...
        'addheader','motor.h', ...
        'addheader','mouse.h', ...
        'addheader','pen.h', ...
        'addheader','position_sensor.h', ...
        'addheader','radar.h', ...
        'addheader','range_finder.h', ...
        'addheader','receiver.h', ...
        'addheader','robot.h', ...
        'addheader','skin.h', ...
        'addheader','speaker.h', ...
        'addheader','supervisor.h', ...
        'addheader','touch_sensor.h', ...
        'addheader',['utils' filesep 'motion.h'], ...
        'addheader',['utils' filesep 'system.h']);
      disp('Load Library successful');
      libcontrollerloaded = true;
    catch ME % this happens with MATLAB R2015a only but seems to be harmless
      if (version('-release') == '2015a')
        loadlibrary(libname,protofile,'alias','libController');
        libcontrollerloaded = true;
      else
        disp('Load Library failed.');
        rethrow(ME);
        loadlibrary = false;
      end
    end
    delete(lockfile);
  else
    disp(['Using prototype file: ' tempdir protofile '.m']);
    loadlibrary(libname,protofile,'alias','libController');
    libcontrollerloaded = true;
  end

  if test_mode == true
    unloadlibrary('libController');
    cd([WEBOTS_HOME '/lib/controller/matlab']);
    disp('Test successful.');
    return
  end

  % initialize libController and redirect stdout/stderr
  try
    calllib('libController', 'wb_robot_init');
  catch
    calllib('libController', 'wb_robot_init_msvc');
  end

  % start controller
  WEBOTS_PROJECT_UTF8 = wbu_system_getenv('WEBOTS_PROJECT');
  WEBOTS_PROJECT = wbu_system_short_path(WEBOTS_PROJECT_UTF8);

  cd([WEBOTS_PROJECT '/controllers/' WEBOTS_CONTROLLER_NAME]);
  eval(WEBOTS_CONTROLLER_NAME);

catch ME
  % display error message in Webots console
  % use stderr to display message in red (this does not work on Windows)
  err = getReport(ME, 'extended');
  fprintf(2,'%s\n\n',err);
  if ispc
    if libcontrollerloaded
      % only try to put the error on the console if the library has been loaded
      calllib('libController', 'wb_console_print', err, 1);
      exit(-1);
    end
    % on Windows, exiting systematically would imply to lose the error message
  else
    exit(-1);
  end
end


allincludes.h

/*
    This file is used by the loadlibrary() function in the launcher.m (MATLAB) file.
    It contains all the headers files of Webots C-API.
*/

#define WB_MATLAB_LOADLIBRARY

#include "../../../include/controller/c/webots/accelerometer.h"
#include "../../../include/controller/c/webots/brake.h"
#include "../../../include/controller/c/webots/camera.h"
#include "../../../include/controller/c/webots/compass.h"
#include "../../../include/controller/c/webots/connector.h"
#include "../../../include/controller/c/webots/console.h"
#include "../../../include/controller/c/webots/device.h"
#include "../../../include/controller/c/webots/differential_wheels.h"
#include "../../../include/controller/c/webots/display.h"
#include "../../../include/controller/c/webots/distance_sensor.h"
#include "../../../include/controller/c/webots/emitter.h"
#include "../../../include/controller/c/webots/gps.h"
#include "../../../include/controller/c/webots/gyro.h"
#include "../../../include/controller/c/webots/inertial_unit.h"
#include "../../../include/controller/c/webots/joystick.h"
#include "../../../include/controller/c/webots/keyboard.h"
#include "../../../include/controller/c/webots/led.h"
#include "../../../include/controller/c/webots/lidar.h"
#include "../../../include/controller/c/webots/light_sensor.h"
#include "../../../include/controller/c/webots/motor.h"
#include "../../../include/controller/c/webots/mouse.h"
#include "../../../include/controller/c/webots/pen.h"
#include "../../../include/controller/c/webots/position_sensor.h"
#include "../../../include/controller/c/webots/radar.h"
#include "../../../include/controller/c/webots/range_finder.h"
#include "../../../include/controller/c/webots/receiver.h"
#include "../../../include/controller/c/webots/robot.h"
#include "../../../include/controller/c/webots/skin.h"
#include "../../../include/controller/c/webots/speaker.h"
#include "../../../include/controller/c/webots/supervisor.h"
#include "../../../include/controller/c/webots/touch_sensor.h"
#include "../../../include/controller/c/webots/utils/motion.h"
#include "../../../include/controller/c/webots/utils/system.h"

help me~

博主还遇到一个问题,就是matlab R2019b,安装目录为D:\Program Files\Polyspace\R2019b,而不是D:\Program Files\MATLAB\R2019b,环境变量Path也没问题,在DOS下键入matlab也可以启动matlab 2019,但是webots还是默认启动matlab 2016,如果删除matlab 2016的环境变量,则会报如下警告:

WARNING: To run Matlab controllers, you need to install Matlab 64-bit and ensure it is available from the DOS CMD.EXE console.

如果有知道怎么解决的大佬,欢迎在留言区留下宝贵的经验,期待与你交流~


读万卷书,也要行万里路!我是罗伯特祥,下次见!

发布了97 篇原创文章 · 获赞 83 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43455581/article/details/104686998