WEB - CONSTRUCTOR OF SCALABLE ROBOTIC SYSTEMS FOR SIMULATION OF COMPLEX SURFACES FOR DYNAMIC TESTING

Cover Page

Cite item

Full Text

Abstract

This article describes the process of designing a distributed SaaS system that implements the functions of a WEB constructor using the Django framework in the Python programming language. PostgreSQL is used as a database management system (DBMS). The main functions of interaction with the database are analyzed: creation (create), reading (read), editing (update), deletion (delete) - CRUD. The REST API is used to interact with the system services. The user interface is implemented as a client using html templates using bootstrapcdn styles. To simplify debugging, logging methods are used. Coordination of the work of developers is provided using the Git version control system and the GitHub version control server.

Full Text

Введение. В настоящее время все чаще используются WEB-приложения, так как в отличии от стандартных приложений, данные программы способны полноценно работать без установки на компьютер. WEB - конструктор проектируется с учетом возможности построения динамической системы, позволяющей моделировать сложные поверхности, которые формируются с помощью множества Stewart – платформ (рис. 1). Параметр каждой платформы (базового модуля системы) можно задать через конфигуратор соответствующего устройства. Количество устройств может меняться динамически, конфигурация динамической системы задается в конструкторе.

Рис. 1. Stewart-платформа

Проектируемая роевая система роботов состоит из Stewart – платформ и может использоваться как испытательный стенд. WEB-конструктор с распределенной системой SааS позволяет в режиме онлайн изменять систему (менять количество, расположение и характеристики), для моделирования сложных поверхностей под конкретную задачу с помощью конфигуратора.

SaaS (software as a service - программное обеспечение как услуга) - одна из форм облачных вычислений, модель обслуживания, при которой подписчикам предоставляется готовое прикладное программное обеспечение, полностью обслуживаемое провайдером. Поставщик в этой модели самостоятельно управляет приложением, предоставляя заказчикам доступ к функциям с клиентских устройств через веб-браузер [1].

Конструктор отвечает за хранение, загрузку и выгрузку законов движения – закон, по которому будет изменяться положение в пространстве базового модуля. Каждый базовый модуль изменяет свое положение согласно заданного закона движения. В совокупности базовые модули Stewart – платформ образуют систему Stewart – платформ, а законы движения каждого отдельного модуля вместе – закон движения системы.

Проектирование базы данных проекта. Анализируя предметную область, можно выделить следующие сущности – «Система Stewart платформ», «Stewart платформа» (базовый модуль), «Закон движения платформы». Система и базовый модуль имеют связь «один ко многим», так как в одной системе может быть много базовых модулей, но конкретный базовый модуль может быть только в одной системе. Базовый модуль и закон движения платформы имеют связь один ко многим, так как у закона может быть много базовых модулей, но базовый модуль может работать только по одному закону движения. Разработаем ER – модель базы данных (рис.2).

Рис. 2. ER - модель базы данных

Параметры закона движения хранятся в базе данных в виде JSON поля:

{"time start": 0, "step": 1, "repeat": 5, "coordinates": {"x": {"0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0}, "y": {"0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0}, "z": {"0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0}, "a": {"0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0}, "b": {"0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0}, "g": {"0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0}}}, где

"time start": время начала движения базового модуля,

"step": шаг, частота дискретизации от времени начала движения,

"repeat": количество повторений шага,

"coordinates": {“x”, “y”, “z”, “a”, “b”, “g”,}: координаты относительно осей в пространстве, где каждому моменту времени соответствует координата.

Программная реализация базы данных проекта. На первом этапе необходимо установить PostgreSQL локально на компьютер. Затем создать базу данных в PostgreSQL и учетную запись Admin [2].

Чтобы подключить созданную базу данных к Django необходимо установить модуль psycopg2. В файле settings.py/DATABASE необходимо прописать следующие настройки:

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'BD_system_stewart_platform',
'USER': 'Admin',
'PASSWORD': 'adminadmin',
'HOST': 'localhost',
'PORT': '',}}

Чтобы создать таблицы в базе данных необходимо прописать следующий код в файле models.py:

from django.db import models

from django.urls import reverse

from django.contrib.auth.models import User

class system_stewart_platform(models.Model):

title_system = models.CharField('Наименование системы', max_length=50)

discription_system = models.CharField('Описание системы', max_length=500)

LAW_TYPE=(

('Волна', 'Волна'),

('Колебания', 'Колебания'),)

law_type_system = models.CharField(verbose_name='Закон движения системы', max_length=50, choices=LAW_TYPE, null=False, blank=True, default='Волна', help_text='Выбрать из списка')

x_max_matrix = models.IntegerField('Размер матрицы по оси x')

y_max_matrix = models.IntegerField('Размер матрицы по оси y')

author = models.ForeignKey(User,related_name='system_stewart_platform_user_created', verbose_name='Пользователь', on_delete=models.CASCADE, null=True,blank=True, default=None)

time_create = models.DateTimeField(auto_now_add=True, verbose_name="Добавлено")

time_update = models.DateTimeField(auto_now=True, verbose_name="Изменено")

def _str_(self):

return self.title_system

def get_absolute_url(self):

return reverse('systemDetailView', args=[str(self.id)])

class Meta:

verbose_name = 'Система Stewart Platform'

verbose_name_plural = 'Системы Stewart Platform'

class law_for_platform(models.Model):

law_type_plat = models.CharField('Наименование типа закона', max_length=50)

amplitude = models.IntegerField('Амплитуда закона от 0 до 100')

coordinates_t = models.JSONField('Координаты и параметры для платформы')

author = models.ForeignKey(User, related_name='law_for_platform_wave_user_created',

verbose_name='Пользователь', on_delete=models.CASCADE, null=True,

blank=True, default=None)

time_create = models.DateTimeField(auto_now_add=True, verbose_name="Добавлено") 

time_update = models.DateTimeField(auto_now=True, verbose_name="Изменено")

def _str_(self):

return self.law_type_plat

def get_absolute_url(self):

return reverse('LawDetailView', args=[str(self.id)])

class Meta:

verbose_name = 'Закон движения для базового модуля'

verbose_name_plural = 'Законы движения для базового модуля'

class stewart_platform(models.Model):

system_stewart_platform = models.ForeignKey(system_stewart_platform, verbose_name='Система', on_delete=models.CASCADE)

law_type = models.ForeignKey(law_for_platform, verbose_name='Закон движения платформы', on_delete=models.CASCADE)

title_platform = models.CharField('Наименование базового модуля', max_length=50)

discription_platform = models.CharField('Описание базового модуля', max_length=500)

ip_adress = models.GenericIPAddressField('IP адрес', protocol='both', unpack_ipv4=False)

port_platform = models.PositiveSmallIntegerField('Порт подключения', default=0)

position_x_in_matrix = models.IntegerField('Позиция базового модуля по оси х')

position_y_in_matrix = models.IntegerField('Позиция базового модуля по оси у')

author = models.ForeignKey(User, related_name='stewart_platform_user_created',

verbose_name=u'Пользователь', on_delete=models.CASCADE, null=True,blank=True, default=None)

time_create = models.DateTimeField(auto_now_add=True, verbose_name="Добавлено")

time_update = models.DateTimeField(auto_now=True, verbose_name="Изменено")

def _str_(self):

return self.title_platform

def get_absolute_url(self):

return reverse('platformDetailView', args=[str(self.id)])

class Meta:

verbose_name = 'Базовый модуль'

verbose_name_plural = 'Базовые модули'

С помощью команды в терминале «python manage.py createsuperuser» создаем учетную запись администратора, назначаем логин и пароль. Проводим миграции с помощью команд в терминале: «python manage.py makemigrations» и «python manage.py migrate» и регистрируем ее в панели администратора в файле admin.py:

from django.contrib import admin
from .models import system_stewart_platform, stewart_platform, law_for_platform

admin.site.register(system_stewart_platform)
admin.site.register(stewart_platform)
admin.site.register(law_for_platform)

Наполним базу данных информацией, заполнив таблицы система Stewart platform, базовый модуль Stewart platform и закон движения, например, через панель администратора или используя команды в терминале. Проверим корректность наполнения базы данных в PostgreSQL, сделав SELECT запрос (рис.3) [3].

Рис. 3. Проверка базы данных в PostgreSQL

Реализация CRUD в проекте. CRUDакроним, обозначающий четыре базовые функции, используемые при работе с базами данных: создание (create), чтение (read), модификация (update), удаление (delete). В данном проекте реализована возможность добавления, редактирования, удаления и просмотра систем Stewart platform, базового модуля Stewart platform и закона движения Stewart platform. Реализованы формы для добавления и редактирования, а также возможности удаления экземпляров. Пользователь видит на сайте все объекты, а также отдельные страницы каждого экземпляра. Для реализации CRUD в проекте принято решение воспользоваться встроенными в Django модулями ListView, DetailView, CreateView, UpdateView, DeleteView. На первом этапе необходимо импортировать модули в файл views.py. Используем классовый подход создания views, а не функционально – ориентированный. Модуль reverse_lazy нужен для переадресации на нужную нам страницу после добавления экземпляра в базу данных.

Для того, чтобы просматривать, добавлять, изменять и удалять данные из базы данных могли только авторизованные пользователи создадим класс LoginRequiredMixin и воспользуемся методом декоратором @method_decorator(login_required). Таким образом код во view.py будет выглядеть следующим образом:

from .models import *

from django.views.generic import ListView, DetailView

from django.views.generic.edit import CreateView, UpdateView, DeleteView

from django.urls import reverse_lazy

from django.contrib.auth.decorators import login_required

from django.utils.decorators import method_decorator

class LoginRequiredMixin(object):

@method_decorator(login_required)

def dispatch(self, *args, **kwargs):

return super(LoginRequiredMixin, self).dispatch(*args, **kwargs)

class systemListView(LoginRequiredMixin, ListView):

model = system_stewart_platform

template_name = "systemStewartPlatform/system/systemListView.html"

class systemDetailView(LoginRequiredMixin, DetailView):

model = system_stewart_platform

template_name = "systemStewartPlatform/system/systemDetailView.html"

class systemCreateView(LoginRequiredMixin, CreateView):

model = system_stewart_platform

template_name = 'systemStewartPlatform/system/systemCreateView.html'

fields = ['title_system', 'discription_system', 'law_type_system', 'x_max_matrix', 'y_max_matrix', 'author']

class systemEditView(LoginRequiredMixin, UpdateView):

model = system_stewart_platform

template_name = 'systemStewartPlatform/system/systemEditView.html'

fields = ['title_system', 'discription_system', 'law_type_system', 'x_max_matrix', 'y_max_matrix', 'author']

class systemDeleteView(LoginRequiredMixin, DeleteView):

model = system_stewart_platform

template_name = 'systemStewartPlatform/system/systemDeleteView.html'

success_url = reverse_lazy('home')

class platformListView(LoginRequiredMixin, ListView):

model = stewart_platform

template_name = "systemStewartPlatform/platform/platformListView.html"

class platformDetailView(LoginRequiredMixin, DetailView):

model = stewart_platform

template_name = "systemStewartPlatform/platform/platformDetailView.html"

class platformCreateView(LoginRequiredMixin, CreateView):

model = stewart_platform

template_name = 'systemStewartPlatform/platform/platformCreateView.html'

fields = ['system_stewart_platform', 'law_type', 'title_platform', 'discription_platform', 'ip_adress', 'port_platform', 'position_x_in_matrix',

'position_y_in_matrix', 'author']

class platformEditView(LoginRequiredMixin, UpdateView):

model = stewart_platform

template_name = 'systemStewartPlatform/platform/platformEditView.html'

fields = ['system_stewart_platform', 'law_type', 'title_platform', 'discription_platform', 'ip_adress', 'port_platform', 'position_x_in_matrix',

'position_y_in_matrix', 'author']

class platformDeleteView(LoginRequiredMixin, DeleteView):

model = stewart_platform

template_name = 'systemStewartPlatform/platform/platformDeleteView.html'

success_url = reverse_lazy('home')

class LawListView(LoginRequiredMixin, ListView):

model = law_for_platform

template_name = "systemStewartPlatform/law/LawListView.html"

class LawDetailView(LoginRequiredMixin, DetailView):

model = law_for_platform

template_name = "systemStewartPlatform/law/LawDetailView.html"

class LawCreateView(LoginRequiredMixin, CreateView):

model = law_for_platform

template_name = 'systemStewartPlatform/law/LawCreateView.html'

fields = ['law_type_plat', 'amplitude', 'coordinates_t', 'author']

class LawEditView(LoginRequiredMixin, UpdateView):

model = law_for_platform

template_name = 'systemStewartPlatform/law/LawEditView.html'

fields = ['law_type_plat', 'amplitude', 'coordinates_t', 'author']

class LawDeleteView(LoginRequiredMixin, DeleteView):

model = law_for_platform

template_name = 'systemStewartPlatform/law/LawDeleteView.html'

success_url = reverse_lazy('home')

Затем для каждого созданного нами нового представления необходимо прописать маршруты в urls.py:

from django.urls import path

from .views import *

urlpatterns = [

path('systemListView', systemListView.as_view(), name='systemListView'),

path('systemDetailView/<int:pk>/', systemDetailView.as_view(), name='systemDetailView'),

path('systemNewView', systemCreateView.as_view(), name='systemCreateView'),

path('systemDetailView/<int:pk>/edit/', systemEditView.as_view(), name='systemEditView'),

path('systemDeleteView/<int:pk>/delete/', systemDeleteView.as_view(), name='systemDeleteView'),

path('platformListView', platformListView.as_view(), name='platformListView'),

path('platformDetailView/<int:pk>/', platformDetailView.as_view(), name='platformDetailView'),

path('platformNewView', platformCreateView.as_view(), name='platformCreateView'),

path('platformDetailView/<int:pk>/edit/', platformEditView.as_view(), name='platformEditView'),

path('platformDeleteView/<int:pk>/delete/', platformDeleteView.as_view(), name='platformDeleteView'),

path('LawListView', LawListView.as_view(), name='LawListView'),

path('LawDetailView/<int:pk>/', LawDetailView.as_view(), name='LawDetailView'),

path('LawNewView', LawCreateView.as_view(), name='LawCreateView'),

path('LawDetailView/<int:pk>/edit/', LawEditView.as_view(), name='LawEditView'),

path('LawDeleteView/<int:pk>/delete/', LawDeleteView.as_view(), name='LawDeleteView'),]

Также для каждого созданного маршрута и представления необходимо создать шаблон html, который будет отображаться на сайте при переходе по адресу страницы.

Для проверки работы CRUD запустим тестовый сервер (рис.4).

Рис. 4. Интерфейс WEB-конструктора с реализованными функциями CRUD

Реализация REST API в проекте. В системах, реализующих доступ к базе данных через API в стиле REST, функции CRUD реализуются зачастую через HTTP-методы PUT, POST, GET, PATCH, DELETE.

API (Application Programming Interface) – это программный интерфейс. Он обеспечивает взаимодействие двух программ между собой и позволяет встраивать контент с любого сайта. Основной задачей API является создание связи между двумя приложениями. API позволяет отправлять запросы на передачу или получение информации. Взаимодействие осуществляется через JSON, а данные получаем в приложениях с помощью API - запросов. API - запрос включает в себя 4 компонента: endpoint (точка приема запроса), header (заголовок), method (метод) и data (данные). После вызова всех компонентов мы можем построить API - запрос [4].

Для реализации REST API в проекте необходимо установить модуль djangorestframework. Затем создать новое отдельное приложение в нашем проекте используя команду «python manage.py startapp LawAPI».

В файл setting.py в INSTALLED_APPS необходимо добавить созданное нами новое приложение, а также «rest_framework». Создадим новый словарь в файле настроек для задания необходимых нам параметров djangorestframework:

REST_FRAMEWORK = {

'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',

'PAGE_SIZE': 2,

'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated']}

Создадим файл serialazers.py, в котором создадим сериалайзер для наших моделей:

from rest_framework import serializers

from systemStewartPlatform.models import *

class systemSerializer(serializers.ModelSerializer):

author = serializers.HiddenField(default = serializers.CurrentUserDefault())

class Meta:

model = system_stewart_platform

fields = '__all__'

class platformSerializer(serializers.ModelSerializer):

author = serializers.HiddenField(default = serializers.CurrentUserDefault())

class Meta:

model = stewart_platform

fields = '__all__'

class lawSerializer(serializers.ModelSerializer):

author = serializers.HiddenField(default = serializers.CurrentUserDefault())

class Meta:

model = law_for_platform

fields = '__all__'

Затем создадим представления в файле views.py, где укажем queryset и serializer_class:

from rest_framework.permissions import IsAuthenticated

from rest_framework.viewsets import ModelViewSet

from lawAPI.serializers import *

from systemStewartPlatform.models import *

class systemViewSet(ModelViewSet):

queryset = system_stewart_platform.objects.all()

serializer_class = systemSerializer

class platformViewSet(ModelViewSet):

queryset = stewart_platform.objects.all()

serializer_class = platformSerializer

class lawViewSet(ModelViewSet):

queryset = law_for_platform.objects.all()

serializer_class = lawSerializer

В файле urls.py пропишем маршруты используя модуль djangorestframework routers:

from rest_framework import routers

from lawAPI.views import *

router = routers.SimpleRouter()

router.register(r'system', systemViewSet)

router.register(r'platform', platformViewSet)

router.register(r'law', lawViewSet)

Реализованный функционал REST API продемонстрирован на рисунке 5.

Рис. 5. REST API

Заключение. В работе разработан проект WEB-конструктора для построения динамической системы, позволяющей моделировать сложные поверхности, которые формируются с помощью множества Stewart – платформ. Настроен Фреймворк Django, спроектирована база данных. Для реализации возможности добавления, редактирования, удаления и просмотра базы данных с сайта реализован CRUD с использованием форм и REST API. Экспериментальная проверка, запущенного локально сервера сайта в отладочном режиме демонстрирует правильную работу разработанного функционала.

×

About the authors

Aleksey Viktorovich Grafkin

Email: lvg_alex@mail.ru

Associate professor, department of information systems security

Russian Federation

Evgeniy Nikolaevich Mylnikov

Author for correspondence.
Email: mylnikov.yevgeniy@gmail.com
Russian Federation

Denis Ivanovich Ponamarenko

Email: maestrodark@icloud.com
Russian Federation

References

  1. SaaS. URL: https://ru.wikipedia.org/wiki/Программное_обеспечение_как_услуга (дата обращения: 10.08.2022).
  2. What is PostgreSQL. URL: http://www.sai.msu.su/~megera/postgres/talks/what_is_postgresql.html (дата обращения: 10.08.2022).
  3. Васильев, А. Ю. Работа с PostgreSQL настройка и масштабирование: учебное пособие/ А. Ю. Васильев. – California: Creative Commons, 2017. — 203 с.
  4. Django Rest Framework URL: https://www.django-rest-framework.org/ (дата обращения: 11.08.2022).

Supplementary files

Supplementary Files
Action
1. JATS XML

Copyright (c) 2023 Proceedings of young scientists and specialists of the Samara University

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

This website uses cookies

You consent to our cookies if you continue to use our website.

About Cookies