Skip to main content

Biblioteca de simulação gráfica 3D de ambientes para estudo de controle de sistema.

Project description

LabVirtual

Compartilhamos aqui alguns conteúdos que estamos desenvolvendo buscando formatar um laboratório virtual para sistemas dinâmicos e controle na Faculdade de Engenharia Elétrica da UFPA-Tucuruí.

Documentação

Para ter acesso a documentação da biblioteca acesse: Documentação.


Ferramentas do nosso interesse:

  • Python : Junto com os pacotes Numpy, SciPy e Matplotlib formam nossa base para programação.

  • VScode : A nossa IDE de programação e interface entre o computador e o GitHub.

  • vPython : Simulação 3D;

Contribuintes ✨

Javier Anton
Raphael Bayma

Raphael
Raphael Teixeira

Oséias Farias
Oséias Farias

Oséias Farias
Yuri Cota

Instalação da Biblioteca

Como Instalar?

Para instalar o LabVirtual você pode usar o pip, conda ou o poetry.

A biblioteca está disponível para ser instalada via o gerenciador de pacotes do python, para instalar basta digitar o comando abaixo em seu terminal.

Instalação com o pip

pip install labvirtual

Instalação com o conda

conda install labvirtual

Instalação com o poetry

poetry add labvirtual

Conteúdo em desenvolvimento:

Simulação de sistema dinâmico com python


Sistemas de interesse:

Sistemas possíveis:

Exemplo de uso:

Para testar a biblioteca, você pode instala-lá e criar um arquivo chamado main.py e copie um dos exemplos abaixo.

Exemplo Maglev

# -----------------------------------------------------
# Universidade Federal do Pará
# Campus Universitário de Tucuruí
# Faculdade de Engenharia Elétrica
# -----------------------------------------------------
#
# Laboratório Virtual Sistemas Dinâmicos e Controle
# Simulador: Maglev
# Autor: Yuri Cota
# Orientadores: Prof. Dr: Raphael Teixeira,
#               Prof. Dr: Rafael Bayma
#
# Data: 2023
#  ----------------------------------------------------
#
# Bibliotecas
import time

import numpy as np
from scipy.integrate import solve_ivp
import vpython as vp

# Importando o Modelo Matemático do Maglev
from labvirtual.simulador_maglev import Maglev

# Importando o Compensador
from labvirtual.simulador_maglev import Compensador

# Importando Simulador e Gráfico
from labvirtual.simulador_maglev import Simulacao
from labvirtual.simulador_maglev import Grafico


def run_maglev():
    # Criação dos objetos da planta e controlador para simular
    mag = Maglev(m=29e-3, k=9.55e-6, mu=2.19e-3, I0=1)
    comp = Compensador(mag, [-3*mag.lamda]*3, [-8*mag.lamda]*2)

    # Criando um Objeto Simulacao
    sim = Simulacao(mag_x0=mag.x0)

    grafico = Grafico()

    # Definindo os sinais de referência para rastreamento
    def ref_seno(t):
        return (mag.x0*np.sin(2*vp.pi*t))

    def ref_quad(t):
        return (mag.x0)*(np.sin(2*vp.pi*t) >= 0)

    # Função para ajustar coordenadas do modelo às coordenadas do VPython
    def converte_posicao(y_maglev):
        return (sim.bobina_3.pos + vp.vec(0, -y_maglev, 0))*4

    # Função para implementar ruído gaussiano
    def ruido(amp):
        return amp*np.random.normal(loc=0, scale=amp)

    # LOOP -------------------------------------------------------------------
    # Criando o loop da simulação
    while True:
        vp.rate(sim.fps)
        # Verificação da posição do cilindro antes de executar o programa
        if sim.cil.pos == vp.vector(12e-2, -3.5e-2, 0):
            grafico.legenda_1.text = "<b>O cilindro está na posição inicial!</b>"
            grafico.legenda_1.color = vp.color.green
        elif sim.cil.pos == vp.vector(0, 0, 0):
            grafico.legenda_1.text = "<b>Cilindo grudado!</b>"
            grafico.legenda_1.color = vp.color.red
        elif sim.cil.pos.y <= 0 and sim.cil.pos.y >= -0.08 and sim.cil.pos.x == 0:
            grafico.legenda_1.text = "<b>O cilindro está na região de equilíbrio!</b>"
            grafico.legenda_1.color = vp.color.cyan
        else:
            grafico.legenda_1.text = "<b>O cilindro está fora da região de equilíbrio!</b>"
            grafico.legenda_1.color = vp.color.purple

        # Acionando o botão executar
        if sim.executar:
            # O primeiro caso: se o cilindro está na posição inicial o
            # programa não vai sair da tela inicial.
            if sim.cil.pos == vp.vector(12e-2, -3.5e-2, 0):
                sim.cil.pos = vp.vector(12e-2, -3.5e-2, 0)
                grafico.yplot.delete()
                grafico.rplot.delete()
                sim.t = 0
                # time.sleep(2)
                sim.executar = not sim.executar
                sim.bt1_exe.text = "Executar"

            #  O segundo caso: o cilindro está grudado no eletroimã,
            # tem que aguardar o programa voltar pra tela inicial.
            elif sim.cil.pos == vp.vector(0, 0, 0):
                time.sleep(3)
                sim.executar = not sim.executar
                sim.bt1_exe.text = "Executar"
                sim.cil.pos = vp.vector(12e-2, -3.5e-2, 0)

            # O terceiro caso: o cilindro está na região 
            # de equilíbrio, logo o programa irá rodar normalmente.
            elif sim.cil.pos.y <= 0 and sim.cil.pos.y >= -0.08 and sim.cil.pos.x == 0:

                # Atualiza o sinal de referência para enviar para o solver
                match sim.M.index:
                    case 0 | None:
                        def sinal(t):
                            return ref_seno(sim.sl.value*sim.t)*(sim.sl2.value)
                    case 1:
                        def sinal(t):
                            return ref_quad(sim.sl.value*sim.t)*(sim.sl2.value)

                # Chama o solver para atualizar os estados do maglev
                sol = solve_ivp(Maglev.estadosmf, t_span=[
                                sim.t, sim.t+sim.dt], y0=sim.y,
                                args=(sinal, mag, comp))

                # Recupera os resultados da simulação
                sim.y = sol.y[:, -1]+ruido(1e-6)

                # Atualiza os gráficos
                grafico.yplot.plot(sim.t, sim.y[0])
                grafico.rplot.plot(sim.t, sinal(sim.t)+mag.x0)
                # print(y[0])

                # Atualiza a posição do cilindro
                sim.cil.pos = converte_posicao(sim.y[0])

                # Atualiza o tempo
                sim.t += sim.dt
    # O quarto caso: o cilindro está fora da região de equilíbrio, logo ele irá cair na mesa e retornar a posição inicial.
            else:
                while sim.cil.pos.y >= -3.5e-2:
                    vp.rate(sim.fps)
                    sim.cil.v = sim.cil.v+sim.g*sim.dt
                    sim.cil.pos = sim.cil.pos+sim.cil.v*sim.dt
                    sim.t = sim.t+sim.dt
                grafico.legenda_1.text = "<b>Aguarde o cilindro retonar a posição incial!</b>"
                grafico.legenda_1.color = vp.color.red
                time.sleep(4)
                sim.cil.pos = vp.vector(12e-2, -3.5e-2, 0)
                print(sim.t)


if __name__ == "__main__":
    run_maglev()

Exemplo Aeropêndulo

# -----------------------------------------------------
# Universidade Federal do Pará
# Campus Universitário de Tucuruí
# Faculdade de Engenharia Elétrica
# -----------------------------------------------------
#
# Laboratório Virtual Sistemas Dinâmicos e Controle
# Simulador: Aeropêndulo
# Autor: Oséias Farias
# Orientadores: Prof. Dr: Raphael Teixeira,
#               Prof. Dr: Rafael Bayma
#
# Data: 2023
#  ----------------------------------------------------
#

import vpython as vp
import numpy as np
from labvirtual.simulador_aeropendulo import (Graficos, AnimacaoAeropendulo,
                                              Interface, ModeloMatAeropendulo,
                                              ControladorDiscreto)


def run_aeropendulo():
    # Instanciando um objeto AeropenduloAaeropendulo()
    animacao_aeropendulo = AnimacaoAeropendulo()

    # Instanciando um objeto para plotagem dos gráficos dinâmicos dos
    # estados do Aeropêndulo
    g = Graficos()
    graf, plot1, plot2, plot3, plot4 = g.graficos()

    # Instânciando um objeto para solução matemática do sistema Aeropêndulo.
    Km = 0.0296
    m = 0.36
    d = 0.03
    J = 0.0106
    c = 0.0076
    mma = ModeloMatAeropendulo(K_m=Km, m=m, d=d, J=J, c=c)

    # Instânciando um objeto ControladorDiscreto
    controlador = ControladorDiscreto(referencia=0.01)
    u = 0  # Sinal de controle inicial

    # Instanciando um objeto Interface
    interface = Interface(animacao_aeropendulo, controlador)

    ts = 1e-2
    # Condições Iniciais dos estados
    x = np.array([0.0, 0.0])
    t = 0.0
    t_ant = 0.0

    # Simulação do Sistema
    while True:
        vp.rate(100)
        if interface.EXE:
            # Calcula as derivadas do sitema
            dx = mma.modelo_aeropendulo(x, t)
            dt = t - t_ant

            # Atualização dos estados
            x = x + dt * dx

            # Pega o Ângulo e envia para o controlador
            # (Realimentação do sistema)
            controlador.set_sensor(x[1])

            # O controlador calcula o sinal de controle
            controlador.control_pi()

            # Controle proporcional
            # controlador.controle_proporcional(kp=10.0)
            # pega o sinal de controle calculado e salva na variável u
            u = controlador.get_u()

            # Sinal de controle aplicado a entrada do sistema
            mma.set_u(u)

            # print(x[1]*(180/np.pi))
            t_ant = t
            t += ts

            # Atualiza o ângulo do Aeropêndulo
            animacao_aeropendulo.aeropendulo.rotate(axis=vp.vec(0, 0, 1),
                                                    angle=x[0]*ts,
                                                    origin=vp.vec(0, 5.2, 0))

            # Animação da dinâmica da Hélice
            animacao_aeropendulo.update_helice(x[0], ts)

            # print(x[1] + interface.valor_angle)
            # Gráfico do ângulo.
            plot1.plot(t, x[1] + interface.valor_angle)
            # Gráfico do sinal de referência
            plot2.plot(t, controlador.r + interface.valor_angle)
            # Gráfico da velocidade ângular.
            plot3.plot(t, x[0])
            # Gráfico do sinal de controle
            plot4.plot(t, u)


if __name__ == "__main__":
    run_aeropendulo()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

labvirtual-0.3.0.tar.gz (43.6 MB view details)

Uploaded Source

Built Distribution

labvirtual-0.3.0-py3-none-any.whl (43.6 MB view details)

Uploaded Python 3

File details

Details for the file labvirtual-0.3.0.tar.gz.

File metadata

  • Download URL: labvirtual-0.3.0.tar.gz
  • Upload date:
  • Size: 43.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.0 CPython/3.8.10 Linux/5.15.0-71-generic

File hashes

Hashes for labvirtual-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e58d5fe278c92d2326b67493938625705f3ddaafbdf41fcb5b8e3be7075f5ef5
MD5 f9d5218e1a0561657f59c74904a018b9
BLAKE2b-256 5380ec9857b8fd07db465bd292532954a61a841040b20ba6bf606084817f5707

See more details on using hashes here.

File details

Details for the file labvirtual-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: labvirtual-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 43.6 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.0 CPython/3.8.10 Linux/5.15.0-71-generic

File hashes

Hashes for labvirtual-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e25e35e2ae56e9711f836449e4659b4836ffe65e8300a071cb0ce8704051b8ce
MD5 fa20e08f7abfa01434a09d91dbb6b96a
BLAKE2b-256 afccbbfc19d4e07142b36d537aebc685d743a090936b260db5bb4b8de56de36d

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page