Результаты робототехнического исследования должны быть сведены в удобно читаемые формы записи, одной из которых являются графики.
Программный комплекс CoppeliaSim позволяет строить разнообразные графики.
Начиная с версии 4.2.0 разработчики исключили из программы "графопостроитель" – графический интерфейс для построения графиков. Теперь все графики строятся скриптингом. Обосновывая это тем, что это позволяет гораздо более гибко и точно управлять графиками.
Построим график траектории движения мобильного робота pioneer p3dx. Для этого на панели меню выберем Add --> Graph. Доступ к его основным свойствам и их настройка осуществляются в диалоговом окне графика. Про объект Graph можно почитать ТУТ.
Добавим на сцену модель робота pioneer p3dx. Для этого в обзорщике моделей в дереве robots выберем mobile и перетащим робота pioneer p3dx на сцену.
Если сейчас нажать на кнопку Play (Старт сцены), то робот поедет в прямом направлении, логика его работы содержится в прикреплённом скрипте.
Отредактируем скрипт таким образом, чтобы вместо прямолинейного движения робот осуществлял круговое. Для этого в функции sysCall_actuation()
скорость правого колеса увеличим в два раза.
vRight=v0*2
Убедимся в круговой траектории движения мобильного робота запустив симуляцию.
Далее в скрипте содержащего логику работы мобильного робота в функции sysCall_init()
добавим следующий код:
graph=sim.getObjectHandle('Graph')
objectHandle=sim.getObjectHandle('Pioneer_p3dx')
objectPosX=sim.addGraphStream(graph,'x','m',1)
objectPosY=sim.addGraphStream(graph,'y','m',1)
sim.addGraphCurve(graph,'object pos x/y',2,{objectPosX,objectPosY},{0,0},'m by m')
Где 'Graph' и 'Pioneer_p3dx' это имена объектов из иерархии сцены.
В теле скрипта добавим функцию sysCall_sensing()
.
function sysCall_sensing()
end
В функции sysCall_sensing()
добавим следующий код:
pos=sim.getObjectPosition(objectHandle,-1)
sim.setGraphStreamValue(graph,objectPosX,pos[1])
sim.setGraphStreamValue(graph,objectPosY,pos[2])
Очистим график после окончания процесса симулирования. Для этого в функции sysCall_cleanup()
добавим следующую строку:
sim.resetGraph(graph)
И запустим процесс симулирования.
Точность позиционирования обусловлена влиянием физики на нашего мобильного робота.
Одним из самых интересных графиков – пространственная кривая движения механизма.
Приведем скрипт к первоначальному виду, оставив лишь увеличенную в два раза скорость правого колеса.
Далее в скрипте содержащую логику работы мобильного робота в функции sysCall_init()
добавим следующий код:
graph=sim.getObjectHandle('Graph')
base=sim.getObjectHandle('Pioneer_p3dx')
x=sim.addGraphStream(graph, 'x', 'm')
Строить будем зависимость x от времени t.
Добавим функцию sysCall_sensing()
.
function sysCall_sensing()
end
В функции sysCall_sensing()
добавим следующий код:
p=sim.getObjectPosition(base,-1)
sim.setGraphStreamValue(graph, x, p[1])
Очистим график после окончания процесса симулирования. Для этого в функцию очистки sysCall_cleanup()
добавим следующую строку:
sim.resetGraph(graph)
И запустим процесс симулирования.
Добавим вторую зависимость у от времени t.
Для этого в функции инициализации sysCall_init()
добавим следующую строку:
y=sim.addGraphStream(graph, 'y', 'm')
В функции sysCall_sensing()
добавим следующую строку:
sim.setGraphStreamValue(graph, y, p[2])
p[3] - это соответственно координата z.
Запустим процесс симулирования. Получим график изображенный на рисунке 4.
Из-за того что кривые одного цвета из графика сложно понять где какая переменная. Поэтому введем следующие изменения в описании переменных в функции sysCall_init()
:
x=sim.addGraphStream(graph, 'x', 'm', 0, {1,0,0})
y=sim.addGraphStream(graph, 'y', 'm', 0, {0,1,0})
Где {1,0,0} и {0,1,0} это значение цвета в RGB формате.
Запустим процесс симулирования. Получим график изображенный на рисунке 5.
Для построения графика зависимости скорости от времени создадим пользовательский интерфейс.
CoppeliaSim предлагает создание настраиваемого пользовательского интерфейса (сustom user interfaces) с помощью встроенного плагина Qt. При создании пользовательского интерфейса используется специальный XML синтаксис. Начиная с версии 4.2.0 разработчики полностью исключили возможность создания пользовательского интерфейса с помощью "OpenGl-based custom UI".
Пример синтаксиса плагина Qt наиболее хорошо отображен в учебной сцене customUI.ttt находящейся в корне папки scenes в месте установки программы.
В общем удалим и снова добавим на сцену модель робота pioneer p3dx.
Нам потребуется написать немного кода.
В функции sysCall_init()
значение переменой v0=2
изменим на ноль:
v0=0
В конце функции sysCall_init()
добавим следующий код:
xml = '<ui title="Speed" closeable="false" resizeable="false" activate="false">'..[[
<hslider minimum="0" maximum="1000" on-change="speedChange_callback" id="1"/>
</ui>
]]
ui=simUI.create(xml)
В функции sysCall_cleanup()
добавим следующую строку:
simUI.destroy(ui)
В теле скрипта вставим следующую функцию:
function speedChange_callback(ui,id,newVal)
v0=newVal*2/1000
end
Запустим симулирование. Теперь скоростью робота можно управлять.
Реализуем управление роботом с помощью двух ползунков, чтобы один из них управлял скоростью левого колеса, а другой – правого.
Приведем скрипт к первоначальному виду.
Далее в функции sysCall_init()
удалим переменную v0=2
и инициализируем следующие переменные:
vl=0
vr=0
В конце тела функции sysCall_init()
вставим следующий код:
xml = '<ui title="Speed" closeable="false" resizeable="false" activate="false">'..[[
<hslider minimum="0" maximum="1000" on-change="speedChange_callbackL" id="1"/>
<hslider minimum="0" maximum="1000" on-change="speedChange_callbackR" id="2"/>
</ui>
]]
ui=simUI.create(xml)
В теле скрипта добавим следующие функции:
function speedChange_callbackL(ui,id,newVal)
vl=newVal*2/1000
end
function speedChange_callbackR(ui,id,newVal)
vr=newVal*2/1000
end
В функции sysCall_cleanup()
добавим следующую строку:
simUI.destroy(ui)
В функции sysCall_actuation()
переменной vLeft
и переменной vRight
присвоим vl
и vr
соответственно вместо v0
.
vLeft=vl
vRight=vr
Запустим процесс симулирования.
В итоге мобильный двухколесный робот научится поворачивать, и им можно будет управлять.
Построим график зависимости скорости от времени.
В функции sysCall_init()
добавим следующий код:
graph=sim.getObjectHandle('Graph')
joint1Vel=sim.addGraphStream(graph,'joint 1 velocity','deg/s',0,{1,0,0})
joint2Vel=sim.addGraphStream(graph,'joint 2 velocity','deg/s',0,{0,1,0})
Добавим функцию sysCall_sensing()
.
function sysCall_sensing()
end
В функции sysCall_sensing()
добавим следующий код:
sim.setGraphStreamValue(graph,joint1Vel,180*sim.getJointVelocity(motorLeft)/math.pi)
sim.setGraphStreamValue(graph,joint2Vel,180*sim.getJointVelocity(motorRight)/math.pi)
Очистим график после окончания процесса симулирования. Для этого в функцию sysCall_cleanup()
добавим следующую строчку.
sim.resetGraph(graph)
Запустим процесс симулирования, поерзаем ползунками. Получим график изображенный на рисунке 7.
Таким образом, результаты имитационного моделирования робототехнических систем в программном комплексе CoppeliaSim могут быть с легкостью сведены в виде графиков.