Implementação em C++ de um controlador para uma máquina de venda de bebidas

Descrição do sistema e requisitos:

  • Máquina de estados (FSM) do controlador: “A máquina fornece dois tipos de refrigerantes, denominados MEET e ETIRPS. Estes estão disponíveis para escolha pelo usuário a partir de duas teclas no painel com o nome dos refrigerantes. Ambos refrigerantes custam R$1,50 e existe na máquina uma fenda para inserir moedas com um sistema eletromecânico capaz de reconhecer moedas de R$1,00, R$0,50 e R$0,25, e capaz de devolver automaticamente qualquer outro tipo de moeda ou objeto não reconhecido. Além disso, durante a compra, o usuário pode desistir da transação e apertar a tecla DEV que devolve as moedas inseridas até o momento. Somente após acumular um crédito mínimo de R$1,50 o usuário pode obter um refrigerante. A devolução de excesso de moedas é automática sempre que o valor inserido antes de retirar um refrigerante ultrapassar R$1,50. Uma terceira simplificadora consiste em ignorar a composição exata das moedas inseridas na máquina, atendo-se apenas ao montante total inserido.”
  • A interface de entrada e saída deve ser implementada utilizando o conceito de polimorfismo, visando a adaptação do código em C++ para diferentes interfaces. A idéia é ter uma classe “interface”, que possa assumir várias formas (várias implementações), dependendo de onde o programa for executado (ex. microcomputador; kit de desenvolvimento com microcontrolador embarcado em FPGA; kit de desenvolvimento com microcontrolador da TI; …).
  • A máquina de vendas deverá apresentar mensagens de anunciantes em um display. As mensagens devem ser apresentadas continuamente, e em sequencia, permanecendo no display por um certo tempo. Esporadicamente, após um número aleatório de propagandas ser apresentado, a informação de data/hora deve ser mostrada por alguns segundos, antes da sequencia de mensagens voltar a ser apresentada. O sistema deverá possibilitar a inserção de novas mensagens de anunciantes, e a remoção de mensagens expiradas. As novas mensagens deverão ficar armazenadas, e só passarão a ser apresentadas no display após o usuário fornecer um comando para adicioná-las ao conjunto de mensagens ativas. A apresentação de mensagens de propaganda deve ser interrompida sempre que ocorrer algum evento relacionado a venda de refrigerantes (exemplo: colocou moeda, pressionou botão, …).
  • Utilizar as seguintes estruturas de dados (e operações sobre as estruturas de dados), para gerencia das mensagens:
    • Utilizar uma fila (“Fila 1″) para armazenar as propagandas a serem apresentadas no display (ver Figura 1). A mensagem que estiver na frente da fila deve ser retirada da fila, apresentada no display por um tempo pré-determinado, e colocada de volta na fila (no fundo da fila).
    • Utilizar uma fila (“Fila 2″) para armazenar novas propagandas fornecidas pelo usuário, mas que ainda não estão sendo apresentadas no display.
    • Deve existir uma opção (ex. um botão na placa) para realizar a transferência de todas as propagandas da “Fila 2″, para a “Fila 1″ (basicamente, remover todas as mensagens da “Fila 2″, e incluir na “Fila 1″). No momento em que essa opção for selecionada, o sistema poderá interromper a apresentação das mensagens, pois estará passando por uma rotina de “manutenção”.
    • A remoção de uma mensagem expirada (ex. falta de pagamento por parte do anunciante), deve ser realizada após uma solicitação do usuário. Por exemplo, quando uma determinada mensagem estiver sendo apresentada, o usuário pode pressionar um determinado botão, e uma mensagem de confirmação poderá ser apresentada. Ao responder “Sim”, o nodo em questão não deve ser removido (não poderá voltar para o final da “Fila 1″).
    • A inclusão de novas propagandas no sistema pode ser realizada diretamente no computador hospedeiro, e enviadas para a placa utilizada como controlador da máquina de vendas. No momento do envio, um botão pode ser pressionado na placa do controlador, colocando o sistema embarcado em “espera” por novas mensagens de anunciantes, que devem ser adicionadas a “Fila 2″. Essas mensagens só serão enviadas para a “Fila 1″, quando o outro botão mencionado anteriormente for pressionado.
    • As filas devem ser implementadas por intermédio de listas encadeadas (ou duplamente encadeadas), utilizando alocação dinâmica de memória. Não devem ser utilizadas funções da STL.
    • Ao implementar as filas é importante respeitar os conceitos relacionados a esse tipo de estrutura de dados, ou seja, em uma fila só é possível realizar a inclusão no final (após o último nodo), e a leitura na frente da fila (primeiro nodo). Não devem existir facilidades para acesso aos demais nodos da fila, apenas o primeiro (leitura) e o último (escrita) nodo podem ser acessados. Assim, após apresentar uma propaganda, o nodo que se encontra na primeira posição (frente), deve ser removido, e incluído no final da fila.
    • As filas devem ser modeladas por intermédio de classes na linguagem C++. Devem ser definidas classes para representar os nodos, e a lista encadeada propriamente dita.
    • Devem ser definidas classes para modelagem das demais funcionalidades do sistema (ex. gerência do tempo, comunicação com o computador hospedeiro, gerência do display, entre outras).
    • O acesso ao display deve ser modelado por intermédio de classes, usando o conceito de polimorfismo. O objetivo é possibilitar a adaptação do sistema a diversos tipos de displays como, por exemplo: letreiro simulado na tela do computador hospedeiro; display OLED da placa Atlys; ou outro letreiro qualquer.
    • Cada mensagem (propaganda) deve ser apresentada no display durante 10 segundos (usar 1 segundo durante os testes).
    • A informação de data/hora deve ser apresentada por 5 segundos (usar 1 segundo durante os testes).
    • A data/hora deve ser apresentada, aleatoriamente, a cada 3 a 6 propagandas.
  • O software final deve possui as seguintes funcionalidades:
    1. Controle da máquina de venda de refrigerantes (recebe moedas, devolve moedas, fornece produtos, fornece troco).
    2. Apresentação de propagandas em um display, utilizando as filas como estruturas de dados.
    3. Uma terceira funcionalidade qualquer, a ser definida por cada desenvolvedor (ou dupla de desenvolvedores). Essa terceira funcionalidade deverá ser implementada utilizando conceitos e recursos de C++, e também alguma estrutura de dados (lista, pilha, árvore, grafo).

fig1

Figura 1. Estruturas de dados utilizadas para implementação do módulo de apresentação de propagandas de anunciantes da máquina de vendas.

  • Dicas e observações:
    • Desenvolver um ÚNICO software (pode ser composto por diversos arquivos .h e .cpp).
    • O software deve ser projetado de forma a ser utilizado tanto em uma placa (sistema embarcado), quanto em um microcomputador (saída na tela do computador hospedeiro).
    • Não existe necessidade de mostrar o funcionamento do software em um sistema embarcado, mas é necessário realizar a implementação (e compilação) visando também uma plataforma alvo a ser escolhida pelos alunos (exemplo: Raspberry Pi, ARM, …).
    • O software precisa ser desenvolvido utilizando classes, herança, polimorfismo, e outros mecanismos de orientação a objetos, conforme discutido nas aulas da disciplina.
    • As tentativas mal sucedidas de utilização de recursos de programação da linguagem C++ no sistema embarcado alvo (devido a limitações do cross-compiler, por exemplo), devem ser relatadas, assim como as soluções adotadas.
    • Preparar uma documentação (relatório técnico) descrevendo a arquitetura do sistema, ferramentas utilizadas, e o fluxo utilizado para o desenvolvimento do software. Incluir comentários sobre a experiência ao utilizar orientação a objetos na implementação desse tipo de sistema embarcado. Quais as vantagens e desvantagens? Quais recursos foram utilizados? Quais recursos gostaria de ter utilizado, e não foi possível devido as limitações do compilador? Porquê gostaria de ter utilizado (ou usou) determinados recursos? (exemplo: Reuso de módulos? Organização do código fonte?). A documentação é parte fundamental da avaliação, e deverá ser preparada de forma a possibilitar futuras alterações no software desenvolvido.
    • Preparar um manual do usuário, que pode ser incluído no relatório técnico como um apêndice.
  • Avaliação e entrega:
    • Será avaliado se na implementação do programa foram utilizados, pelo menos, os seguintes conceitos de C++:
      • Herança
      • Friends
      • Template
      • Funções virtuais
      • Tratamento de exceções
      • Sobrecarga de operadores
      • Polimorfismo (com classes abstratas)
    • O trabalho pode ser desenvolvido individualmente, ou em dupla. A avaliação é individual, mesmo no caso de trabalhos desenvolvidos em duplas.
    • Em caso de trabalhos desenvolvidos em dupla, ambos devem possuir conhecimento total do que foi desenvolvido. Não serão aceitas respostas tipo “essa parte não fui em que fiz”. Mesmo que uma determinada parte tenha sido desenvolvida por outro integrante da dupla, o outro integrante precisa estudar e entender tudo o que foi feito, para poder responder os questionamentos.
    • Deve ser utilizado o github para o controle de versão e compartilhamento dos programas.
    • Toda a documentação deve ser preparada e entregue em um único arquivo no formato PDF.
    • O software pode ser desenvolvido e apresentado em um microcomputador, porém é preciso realizar a entrega da implementação necessária para utilização em um sistema embarcado como, por exemplo, Raspberry Pi ou ARM.
    • Aqueles que não pretendem executar o software na plataforma (sistema embarcado) destino, devem apresentar um relatório da compilação sem erros do programa, usando a arquitetura destino como alvo (cross-compiler). Isso é importante para mostrar que o programa não possui restrições para execução em um sistema embarcado sem sistema operacional (ou que utilize um sistema operacional embarcado). IMPORTANTE!!! Não serão aceitos dois programas diferentes (um para o microcomputador, e outro para o sistema embarcado). Deverá ser desenvolvido um único programa que compile/funcione nas duas plataformas.
    • A entrega do trabalho será realizada no moodle, respeitando os prazos estabelecidos, e listados na tabela a seguir.
Data Entrega
09/11
  • Relatório incluindo:
    • Diagrama de classes (preliminar), que pode ser preparado com ferramentas disponíveis na web para desenho de diagramas como, por exemplo, yUML.
    • Funcionamento da máquina de estados (com a tabela de estados) do controlador da máquina de vendas.
    • Descrição do sistema embarcado alvo (ex. descrição da possível placa a ser utilizada, descrição das bibliotecas necessárias para a implementação, compilador e ferramenta de desenvolvimento a ser utilizada, entre outros).
  • Software para o controlador da máquina de vendas (máquina de estados) implementado e funcionando em C++.
  • Essa entrega será avaliada com um peso de 20% sobre a nota final do projeto.
16/11
  • Relatório incluindo:
    • Diagrama de classes (revisão).
    • Modelagem do módulo de apresentação de mensagens (estruturas de dados utilizadas, operações a ser realizadas sobre as estruturas de dados, algoritmos, …).
    • Modelagem da funcionalidade adicional, definida pelos desenvolvedores.
    • Estratégias de polimorfismo utilizadas para permitir a execução do programa tanto em um microcomputador, quanto no sistema embarcado alvo (ex. bibliotecas, funções, …).
  • Filas implementadas e funcionando em C++ (utilizando estruturas de dados encadeadas – listas). Nessa entrega, basta fornecer as filas funcionando, sem necessidade de atender os requisitos do trabalho.
  • Essa entrega será avaliada com um peso de 20% sobre a nota final do projeto.
23/11
  • Relatório incluindo:
    • Diagrama de classes (revisão).
    • Arquitetura do sistema.
    • Ferramentas utilizadas.
    • Fluxogramas.
    • Plano de testes, contendo as sequencias de testes utilizadas para verificar o funcionamento do programa, de acordo com os requisitos. Incluir casos de teste utilizados para mostrar se o programa atende situações de entradas de dados inválidas, e também capacidade de memória para alocação dinâmica de dados.
    • Incluir comentários sobre a experiência ao utilizar orientação a objetos na implementação desse tipo de sistema embarcado. Quais as vantagens e desvantagens? Quais recursos foram utilizados? Quais recursos gostaria de ter utilizado, e não foi possível devido as limitações do compilador? Porquê gostaria de ter utilizado (ou usou) determinados recursos? (exemplo: Reuso de módulos? Organização do código fonte?).
    • Manual do usuário (em um apêndice).
  • Software de apresentação de mensagens em C++, utilizando as filas implementadas com estruturas de dados encadeadas (listas), conforme os requisitos do trabalho.
  • Software com a demonstração da funcionalidade proposta pelos desenvolvedores (item 3 do resumo das funcionalidades descrito nos requisitos).
  • Essa entrega será avaliada com um peso de 20% sobre a nota final do projeto.
30/11
  • Relatório final
    • Além do conteúdo incluído nas versões anteriores, essa versão final do relatório deverá conter uma análise do desempenho da execução do programa. “Desempenho” não significa apenas velocidade de execução, mas também outros parâmetros como, por exemplo, espaço ocupado, consumo de energia, entre outros. Incluir nesse relatório os parâmetros que conseguir medir (ex. dados obtidos após a compilação) e, também, parâmetros obtidos através de uma análise teórica.
  • Código fonte completo (github) e DOCUMENTADO (com comentários).
  • Demonstração do programa funcionando em um microcomputador OU em um sistema embarcado (ou em ambos).
  • Execução do plano de teste proposto, mostrando que o programa atende os requisitos.
  • Essa entrega será avaliada com um peso de 40% sobre a nota final do projeto.

 

Links: