Bts Framework

  • Home 
  • Documentação 
  • Fale conosco 
Github

Bts Framework

Github
  • Home 
  • Documentação 
  • Fale conosco 

BTS Framework

  • InstalaçãoInstalação
    • Como instalar
  • com 2Sistema multi-agente
    • Funcionamento do Sistema multi-agente
  • InputInput
    • Funcionamento do Input
  • OutputDataManager
    • Funcionamento do DataManager
    • KinectManager
    • Mediapipe Manager
    • Tipos de mapeamento
  • AnalysisAnalysis
    • Funcionamento do Analysis
  • UtilitiesUtils
    • Funcionamento do Utils
  • SupportExemplos
    • Projeto 1 – Rastreamento óptico
    • Projeto 2 – Multi-agente com BSN
  • FAQFAQ
    • Dúvidas frequentes
leafleafleafDocly banner shape 01Docly banner shape 02Man illustrationFlower illustration

BTS Framework

  • InstalaçãoInstalação
    • Como instalar
  • com 2Sistema multi-agente
    • Funcionamento do Sistema multi-agente
  • InputInput
    • Funcionamento do Input
  • OutputDataManager
    • Funcionamento do DataManager
    • KinectManager
    • Mediapipe Manager
    • Tipos de mapeamento
  • AnalysisAnalysis
    • Funcionamento do Analysis
  • UtilitiesUtils
    • Funcionamento do Utils
  • SupportExemplos
    • Projeto 1 – Rastreamento óptico
    • Projeto 2 – Multi-agente com BSN
  • FAQFAQ
    • Dúvidas frequentes

Funcionamento do DataManager

Autor: felipe 81 visualizações

Input

O módulo DataManager é responsável por manipular os dados, sejam os dados capturados dos dispositivos, persistindo os mesmos em disco, importando os dados de um arquivo externo para a aplicação, ou simplesmente usando os dados capturados diretamente na aplicação.

O framework utiliza o mesmo padrão de 20 articulações do Kinect, entretanto, o framework é flexível e permite utilizar outros padrões, como o padrão de rastreamento corporal e de mão do Mediapipe.

O rastreamento de mão do Mediapipe é interessante porque captura 21 partes, conseguindo capturar com precisão a movimentação da mão.

Essa flexibilidade é importante caso queira fazer a captura de outras partes não previstas com as 20 articulações padrões do framework, importante notar que o mapeamento também é diferente, ou seja, para uma mesma parte do corpo pode ter outra numeração, assim, é importante o desenvolvedor escolher adequadamente os padrões.

				
					using UnityEngine;

public class Poses : MonoBehaviour
{
    //Mediapipe Standard
    public enum PoseMediapipe
    {
        NOSE = 0,
        L_EYE_INNER = 1,
        L_EYE = 2,
        L_EYE_OUTER = 3,
        R_EYE_INNER = 4,
        R_EYE = 5,
        R_EYE_OUTER = 6,
        L_EAR = 7,
        R_EAR = 8,
        L_MOUTH = 9,
        R_MOUTH = 10,
        L_SHOULDER = 12,
        R_SHOULDER = 11,
        L_ELBOW = 14,
        R_ELBOW = 13,
        L_WRIST = 16,
        R_WRIST = 15,
        L_PINKY = 17,
        R_PINKY = 18,
        L_INDEX = 19,
        R_INDEX = 20,
        L_THUMB = 21,
        R_THUMB = 22,
        L_HIP = 24,
        R_HIP = 23,
        L_KNEE = 26,
        R_KNEE = 25,
        L_ANKLE = 28,
        R_ANKLE = 27,
        L_HEEL = 30,
        R_HEEL = 29,
        L_FINDEX = 32,
        R_FINDEX = 31
    }

    //Mediapipe Only
    public enum PoseHand
    {
        WRIST = 0,
        THUMB_CMC = 1,
        THUMB_MCP = 2,
        THUMB_IP = 3,
        THUMP_TIP = 4,
        INDEX_FINGER_MCP = 5,
        INDEX_FINGER_PIP = 6,
        INDEX_FINGER_DIP = 7,
        INDEX_FINGER_TIP = 8,
        MIDDLE_FINGER_MCP = 9,
        MIDDLE_FINGER_PIP = 10,
        MIDDLE_FINGER_DIP = 11,
        MIDDLE_FINGER_TIP = 12,
        RING_FINGER_MCP = 13,
        RING_FINGER_PIP = 14,
        RING_FINGER_DIP = 15,
        RING_FINGER_TIP = 16,
        PINKY_MCP = 17,
        PINKY_PIP = 18,
        PINKY_DIP = 19,
        PINKY_TIP = 20
    }

    // BTS Standard = Kinect - Mediapipe different mapping
    public enum PoseBts
    {
        HipCenter = 1,
        Spine = 2,
        ShoulderCenter = 3,
        Head = 4,
        LeftShoulder = 5,
        LeftElbow = 6,
        LeftWrist = 7,
        LeftHand = 8,
        RightShoulder = 9,
        RightElbow = 10,
        RightWrist = 11,
        RightHand = 12,
        LeftHip = 13,
        LeftKnee = 14,
        LeftAnkle = 15,
        LeftFoot = 16,
        RightHip = 17,
        RightKnee = 18,
        RightAnkle = 19,
        RightFoot = 20
    }
}				
			

No DataManager foi utilizado o padrão de projeto Repository que é usado para criar uma camada de abstração entre a camada de acesso a dados e a camada de negócios de um aplicativo. Tem-se como vantagem da utilização desse padrão: testes facilitados; gerenciamento mais simples da aplicação com o armazenamento de dados e permite facilmente trocar por vários data stores sem alterar a API.
A interface IRepository é uma interface genérica que define alguns métodos, como Insert responsável por inserir no SGBD, Remove para deletar, List para pesquisar na lista e o ApiRequest para trabalhar com API. Note que em vez da entidade Poses, estamos usando T em todos os lugares de forma genérica.

				
					using System.Collections.Generic;
using System.Linq;
using System;

public interface IRepository<T> where T : class
{
    void Insert(T obj);
    void Remove(T obj);
    List<T> List(Func<T, bool> expression = null);
    void ApiRequest(String con);
}				
			

O Repository é uma classe genérica e implementa a interface IRepository. Note que o repositório genérico não possui funções especificas para funcionar com as articulações.

				
					public class Repository<T> : IRepository<T> where T : class
{
    List<T> lt;

    public Repository()
    {
        lt = new List<T>();
    }

    public void Insert(T obj)
    {
        lt.Add(obj);
    }

    public void Remove(T obj)
    {
        lt.Remove(obj);
    }

    public List<T> List(Func<T, bool> expression = null)
    {
        return expression != null ? lt.Where(expression).ToList() : lt;
    }

    public void ApiRequest(String con)
    {
        // Waiting for the new rebase to be ready
    }
}				
			

A interface IPoseRepository é uma interface específica que define alguns métodos próprios para trabalhar com as articulações, como GetPose, responsável por retornar uma articulação específica; GetHandPose que retorna as articulações da mão; PoseFound que verifica se algum rastreamento já foi feito; SaveToTxt que persiste em disco em um arquivo txt; SaveToXml, persiste em disco em um arquivo XML (Extensible Markup Language). O LoadTxt e LoadXml carregam as articulações de um arquivo de texto e XML respectivamente.

				
					using System;
using UnityEngine;
using System.IO;
using System.Xml;

public interface IPoseRepository : IRepository<Poses>
{
    Vector3 GetPose(Poses.PoseBts obj);
    Vector2 GetPoseHand(Poses.PoseHand obj);

    bool PoseFound();
    void SaveToTxt(String data, String fileName);
    void SaveToXml(String data, String fileName);
    void LoadTxt(String fileName);
    void LoadXml(String fileName);
}				
			

O PoseRepository é um repositório específico que implementa a interface IPoseRepository, com métodos próprios para lidar com articulações, ao contrário do Repository, que é um repositório genérico. O PoseRepository faz uso do KinectManager, classe desenvolvida pela Microsoft para utilizar os recursos do Kinect, e também utiliza o MediapipeManager, análogo a classe anterior porém foi criada para o framework, pois não havia algo semelhante para explorar os recursos do Mediapipe. Como foi adotado o padrão de articulações do framework quando utilizado o Mediapipe precisamos converter um padrão para o outro, assim, foi utilizado o método ConvertKinectMapToMediaPipe, dessa forma fica transparante para o desenvolvedor independente do dispositivo óptico que ele esteja usando.

				
					public class PoseRepository : Repository<Poses>, IPoseRepository
{
    // Get pose from optical device
    public Vector3 GetPose(Poses.PoseBts obj)
    {
        if (InputSelector.inputFactory.GetInput("Mediapipe")
        .IsReady())
        {
            return MediapipeManager.
            GetPoint(MediapipeManager.
            ConvertKinectMapToMediaPipe(obj));
        }
        else if (InputSelector.inputFactory.GetInput("Kinect")
        .IsReady())
        {
            return KinectManager.
            GetRawSkeletonJointPos(KinectManager.
            GetPlayer1ID(), (int)obj);
        }
        else
        {
            return Vector3.zero;
        }
    }

    //Mediapipe only
    public Vector2 GetPoseHand(Poses.PoseHand obj)
    {
        if (MediapipeManager.VectorHand.Count > 0)
        {
            return new Vector2(
                MediapipeManager.VectorHand[(int)obj].X,
                MediapipeManager.VectorHand[(int)obj].Y
            );
        }
        else
        {
            return Vector2.zero;
        }
    }

    // If PoseFound return true
    public bool PoseFound()
    {
        if (InputSelector.inputFactory.
        GetInput("Mediapipe").IsReady())
        {
            return MediapipeManager.HasPose();
        }
        else if (InputSelector.inputFactory.
        GetInput("Kinect").IsReady())
        {
            return KinectManager.Player1Calibrated;
        }
        else
        {
            return false;
        }
    }

    // Save to txt file
    public void SaveToTxt(String data, String fileName)
    {
        string path = Application.dataPath + "/" + fileName + ".txt";
        File.AppendAllText(path, data + "\n\n");
    }

    // Save to xml file
    public void SaveToXml(String data, String fileName)
    {
        XmlDocument xmlDocument = new XmlDocument();
        XmlElement root = xmlDocument.CreateElement("Save");
        root.SetAttribute("FileName", fileName);

        // Begin node
        XmlElement pose = xmlDocument.CreateElement("Pose");
        pose.InnerText = data;
        root.AppendChild(pose);
        // End node

        xmlDocument.AppendChild(root);

        xmlDocument.Save(Application.dataPath + "/" + fileName + ".xml");
    }

    // Load txt file
    public void LoadTxt(String fileName)
    {
        string path = Application.dataPath + "/" + fileName + ".txt";
        string textFromFile = File.ReadAllText(path);
        Debug.Log(textFromFile);
    }

    // Load xml file
    public void LoadXml(String fileName)
    {
        string path = Application.dataPath + "/" + fileName + ".xml";
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load(path);

        XmlNodeList pose = xmlDocument.GetElementsByTagName("Pose");
        Debug.Log(pose[0].InnerText);
    }
}				
			

How can we help?

A premium WordPress theme with an integrated Knowledge Base,
providing 24/7 community-based support.

Nesta página
Leaf Illustration

BTS Framework © Copyright 2022 - Desenvolvido por Felipe Valente