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.

如果有知道怎麼解決的大佬,歡迎在留言區留下寶貴的經驗,期待與你交流~


讀萬卷書,也要行萬里路!我是羅伯特祥,下次見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章