廢話
已經很久沒有用過了,我的合夥人渾河學者最近要做自動駕駛仿真,我建議他使用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.
如果有知道怎麼解決的大佬,歡迎在留言區留下寶貴的經驗,期待與你交流~
讀萬卷書,也要行萬里路!我是羅伯特祥,下次見!