Você está na página 1de 173

Robótica Teoria e Prática

Robótica Teoria e Prática


Robótica Teoria e Prática

INTRODUÇÃO A ROBÓTICA

Historia da robótica
rob tica

O precursor do termo robô (Groover, 1988) foi Karel Capek, novelista e escritor
de uma peca teatral da Tchecoslovaquia, que usou pela primeira vez, em 1920,
a palavra “robota” (serviço compulsório, atividade forcada) originando a palavra
“robot” em inglês e traduzido para o português como “robô”. Diversos filmes de
ficção cientifica mostraram robôs produzidos com o comportamento e a forma
humana, levando muitos jovens a pesquisar e desenvolver robôs para o mundo
real. Com o surgimento dos computadores na metade do século, iniciaram-se
especulações em termos da capacidade de um robô pensar e agir como um ser
humano. No entanto, os robôs foram, neste período, criados especialmente
para executarem tarefas difíceis, perigosas e impossíveis para um ser humano.
Por outro lado, eles não eram projetados com a capacidade de criar ou
Executar processos que não lhes foram ensinados ou programados. Assim
sendo, foram às indústrias que mais se beneficiaram com o desenvolvimento
da robótica, aumentando a produção e eliminando tarefas perigosas, antes
executadas por seres humanos.
Na robótica moderna, ha pesquisas e desenvolvimentos de robôs intitulados
humanóides ou antropomórficos. Estes são criados com a semelhança humana
e com capacidade de interagir com o ambiente, como o A sim o construído pela
montadora japonesa Honda Motor Co. Citam-se ainda diversos brinquedos
articulados com feições que lembram animais de estimação como cães, por
exemplo, e que se destinam ao entretenimento. Contudo, tais robôs são
incapazes de realizar quaisquer tipos de tarefas, e apenas respondem a
estímulos externos. Estes equipamentos não fazem parte do propósito deste
documento, que visa exclusivamente estudar e compreender os robôs
industriais. Estes, por sua vez, caracterizam se por serem capazes de realizar
tarefas, podem ser programados, e possuem forca elevada.

Robótica Teoria e Prática


Robótica Teoria e Prática

Automação
Automa o
Automação e uma tecnologia que faz uso de sistemas mecânicos, elétricos,
eletrônicos e de computação para efetuar controle de processos produtivos.
Alguns exemplos de processos de automação nas indústrias são:

linhas de montagem automotiva


integração de motores – linha “transfer”
maquinas operatrizes do tipo CNC
robôs
Podem-
Podem-se identificar três
tr s formas distintas de automação
automa o industrial:
automação fixa
automação flexível
automação programável

a) Automação
Automa o fixa

Na automação fixa as maquinas são especificas para o produto a ser reduzido.


Elas produzem grande quantidade um único produto, ou produtos com
pequenas variações entre eles. O volume de produção e elevado, e o custo da
maquina e elevado, pois e projetada para um produto especifico. Por outro
lado, como o volume de produção e alto, o custo do produto em geral e baixo.
Tal maquina são encontradas em linhas transfer de motores, produção de
lâmpadas, fabricação de papel e de garrafas. Neste tipo de automação, deve-se
ter cuidado com o preço final do produto, pois, como o investimento de
aquisição da maquina e alto, a amortização só acontece com vendas elevadas.
Alem disso, se o produto sair do mercado por obsolescência perde-se o
investimento.

b) – Automação
Automa o flexível
flex vel

Na automação flexível o volume de produção e médio e geralmente a maquina


pode ser programada para produzir um outro produto, ainda que semelhante.
Esta automação possui características da automação fixa e da programável. A

Robótica Teoria e Prática


Robótica Teoria e Prática

maquina deve ser adaptável a um numero grande de produtos similares, e,


neste sentido, ela e mais flexível que a automação fixa.
A automação flexível e empregada, por exemplo, numa linha de montagem
Automotiva.

Na automação programável o volume de produção e baixo, mas a variedade de


Produtos diferentes e alta. Ela e adaptável por meio de programação. Os
principais exemplos de automação programável são as maquinas CNC e os
robôs industriais. De todos os processos de automação, a robótica mais se
aproxima da automação programável. Portanto, os volumes de produção de um
robô industrial não são grandes, mas ele e extremamente adaptável a produtos
diferentes. Embora robôs industriais sejam produzidos em diversas
configurações, algumas delas se assemelham, ate certo ponto, a características
humanas (antropomórficas), e, portanto, são propicias para substituir operações
realizadas por humanos. Os robôs são totalmente programáveis, possuem
braços moveis, e são empregados em varias atividades, entre as quais se
destacam:

carregamento e descarregamento de maquinas


soldagem a ponto ou outra forma
pintura ou jateamento
processo de conformação ou usinagem

Embora haja uma tendência de dotar os robôs industriais de mais habilidade


humana, ainda assim eles não possuem forma humana.

Robótica Teoria e Prática


Robótica Teoria e Prática

Distribuição automa o quanto à diversidade de produtos e


Distribui o dos processos de automação
Volume de produção
produ o.

Fundamentos da tecnologia de robôs


A robótica abrange tecnologia de mecânica, eletrônica e computação. Alem
disso, participam em menor grau teoria de controle, microeletrônica, inteligência
artificial, fatores humanos e teoria de produção. Neste capitulo caso serão
analisadas as características dos robôs industriais que permitem avaliar o grau
de aplicação de um determinado braço a um determinado processo produtivo.
Serão também estudados os fundamentos teóricos dos elementos que definem
características físicas do braço, bem como o desempenho dinâmico e o sistema
de controle.

Nomenclatura

As maquinas robóticas podem ser classificadas segundo critérios distintos. Por


Exemplo pode ser agrupada quanto à aplicação, quanto à cadeia cinemática,
quanto ao tipo de atuadores, quanto à anatomia, etc. Sequer o termo robô
possui um significado único. Pode tanto representar um veiculo autônomo
quanto um humanóide ou um simples braço com movimentos. O grau de
interatividade com agentes externos permite classificá-los em totalmente

Robótica Teoria e Prática


Robótica Teoria e Prática

autônomos, programáveis, seqüenciais ou ainda inteligentes. De certa forma,


dada a quantidade de aplicações que surgem a cada momento, e praticamente
impossível haver uma única forma de classificação. Para concentrar esforços no
nosso propósito, limitaremos a abrangência deste manuscrito a robôs
industriais. Eles são, em sua grande maioria, maquinas projetada para
substituir o trabalho humano em situações de desgaste físico ou mental, ou
ainda situações perigosas e repetitivas no processo produtivo em indústrias.
Com isso descartam-se aqueles que possuem o atrativo da forma humanóide,
mas que são de pouca serventia no ramo industrial. Veículos autônomos e
outras formas robóticas também ficam de fora. Na nossa terminologia, um robô
será composto de um circuito eletrônico computadorizado de controle e um
mecanismo articulado denominado manipulador. Porem usará sem distinção os
termos:

robô
braço mecânico
mecanismo robótico
manipulador
manipulador mecânico
manipulador robótico

Que passam a representar, portanto, o mesmo dispositivo. Para compreender


melhor a tecnologia robótica, serão analisados, a seguir, alguns fatores que
caracterizam os manipuladores e que são, em grande parte, responsáveis por
tornar uma determinada configuração de braço mais adequada a uma dada
automação. Entre estas características citam-se:

Anatomia
Volume de trabalho
Sistemas de acionamentos
Sistema de controle
Desempenho e precisão
Órgãos terminais

Robótica Teoria e Prática


Robótica Teoria e Prática

Sensores
Programação
Anatomia dos braços
bra os mecânicos
mec nicos industriais

O braço robótico (Groover, 1988) e composto pelo braço e pulso. O braço


consiste de elementos denominados elos unidos por juntas de movimento
relativo, onde são acoplados os acionadores para realizarem estes movimentos
individualmente, dotados de capacidade sensorial, e instruídos por um sistema
de controle. O braço e fixado a base por um lado e ao punho pelo outro. O
punho consiste de varias juntas próximas entre si, que permitem a orientação
do órgão terminal nas posições que correspondem à tarefa a ser realizada. Na
Extremidade do punho existe um órgão terminal (Mao ou ferramenta) destinada
a realizar a tarefa exigida pela aplicação. Nos braços reais, a identificação dos
elos e juntas nem sempre e fácil, em virtude da estrutura e de pecas que
cobrem as juntas para protegê-las no ambiente de trabalho.

Esquema de notação de elos e juntas num braço mecânico ilustrativo. Numa


junta qualquer, o elo que estiver mais próximo da base e denominado ela de
Entrada. O elo de saída e aquele mais próximo do órgão terminal.

Robótica Teoria e Prática


Robótica Teoria e Prática

Seqüência de elos numa junta de um braço robótico. Mostra um braço robótico


industrial, com todas as suas partes.

Juntas

Robótica Teoria e Prática


Robótica Teoria e Prática

As juntas (Fu, 1987) podem ser rotativa, prismática, cilíndrica, esférica,


parafuso e planar.

A junta prismática
prism tica ou linear: Move em linha reta. São compostas de duas
hastes que deslizam entre si;
A junta rotacional: Gira em torno de uma linha imaginaria estacionaria
chamada de eixo de rotação. Ela gira como uma cadeira giratória e abrem e
fecham como uma dobradiça;
A junta esférica:
esf rica: Funciona com a combinação de três juntas de rotação,
realizando a rotação em torno de três eixos;
A junta
junta cilíndrica:
cil ndrica: E composta por duas juntas, uma rotacional e uma
prismática;
A junta planar: E composta por duas juntas prismáticas, realiza movimentos
em duas direções;
A junta parafuso: E constituída de um parafuso que contem uma porca ao
qual executa um movimento semelhante ao da junta prismática, porem, com
movimento no eixo central (movimento do parafuso).

Tipos de juntas empregadas em robôs


rob s

Robôs industriais utilizam em geral apenas juntas rotativas e prismáticas. A


junta planar pode ser considerada como uma junção de duas juntas

Robótica Teoria e Prática


Robótica Teoria e Prática

prismáticas, e, portanto, e também utilizada. As juntas rotativas podem ainda


ser classificadas de acordo com as direções dos elos de entrada e de saída em
relação ao eixo de rotação. Têm-se assim as seguintes juntas rotativas:

Rotativa de torção
tor o ou torcional T: O elo de entrada e de saída tem a mesma
Direção do eixo de rotação da junta.
Rotativa rotacional R: Os elos de entrada e de saída são perpendiculares ao
eixo de rotação da junta.
Rotativa revolvente V: O elo de entrada possui a mesma direção do eixo de
rotação, mas o elo de saída e perpendicular a este.

Representação
Representa o esquemática
esquem tica de juntas

Robôs industriais adotam com freqüência soluções que tornam o


reconhecimento das juntas mais complexo. De fato, dependendo da forma com
que os elos são construídos numa representação esquemática, a nomenclatura
do braço pode ser ambígua. Este braço poderia ser denominado,
indistintamente, de TVR ou VRR. Para tornar a identificação única deve-se
buscar uma geometria onde os elos sejam formados por, no Maximo, dois
segmentos lineares. Neste caso, a configuração VRR seria a correta.

Robótica Teoria e Prática


Robótica Teoria e Prática

Duas configurações distintas com movimentação idêntica: TVR e VRR.


Graus de liberdade

Os graus de liberdade (GL) determinam os movimentos do braço robótico no


espaço bidimensional ou tridimensional. Cada junta define um ou dois graus de
liberdade, e, assim, o numero de graus de liberdade do robô e igual à somatória
dos graus de liberdade de suas juntas. Por exemplo, quando o movimento
relativo ocorre em um único eixo, a junta tem um grau de liberdade; caso o
movimento se de em mais de um eixo, a junta tem dois graus de liberdade.
Observa-se que quanto maior as quantidades de graus de liberdade, mais
complicadas são a cinemática, a dinâmica e o controle do manipulador. O
numero de graus de liberdade de um manipulador esta associado ao numero
de variáveis posicionais independentes que permitem definir a posição de todas
as partes de forma unívoca. Braços com um (à esquerda) e dois graus de
liberdade (a direita) Os movimentos robóticos podem ser separados em
movimentos do braço e do punho.

Em geral os braços são dotados de 3 acionadores e uma configuração 3GL,


numa configuração que permita que o órgão terminal alcance um ponto
qualquer dentro de um espaço limitado ao redor do braço. Pode-se identificar 3
movimentos independentes num braço qualquer:
Vertical transversal – movimento vertical do punho para cima ou para baixo
Rotacional transversal – movimento do punho horizontalmente para a
esquerda ou para a direita.
Radial transversal – movimento de aproximação ou afastamento do punho

Robótica Teoria e Prática


Robótica Teoria e Prática

Os punhos são compostos de 2 ou 3 graus de liberdade. As juntas dos punhos


são agrupadas num pequeno volume de forma a não movimentar o órgão
terminal em demasia ao serem acionadas. Em particular, o movimento do
punho possui nomenclaturas especificas.

Roll ou rolamento
rolamento - rotação do punho em torno do braço
Pitch ou arfagem - rotação do punho para cima ou para baixo
Yaw ou guinada - rotação do punho para a esquerda e para a direita.

Movimentos de um punho com 3 GL, nas direções


dire es guinada, arfagem e
rolamento.

Cadeias cinemáticas
cinem ticas:
ticas:

Uma das principais características de um braço industrial e sua capacidade de


carga, isto e, qual e o peso Maximo que ele consegue manipular (erguer) sem
que sua precisão seja afetada. Esta capacidade e sempre medida na posição
mais critica, o que significa em geral uma posição de máxima extensão do
braço. Varias soluções podem ser adotadas para aliviar o peso do próprio
manipulador e, conseqüentemente, aumentar a capacidade de carga, como,
por exemplo, a adoção de acionamento indireto, que será visto mais adiante.
Uma outra forma e utilizar cadeias cinemáticas fechadas ou parcialmente
fechadas. Um robô de cadeia cinemática aberta e aquele que, partindo da

Robótica Teoria e Prática


Robótica Teoria e Prática

base, chegam-se ao punho por meio de um único caminho numa seqüência


elo-junta-elo. Um braço articulado do tipo revoluto e um exemplo típico de
cadeia aberta. Já num braço de cadeia fechada, não existe um único caminho
para se chegar ao punho. Vários elos podem estar conectados entre si, de tal
forma que e possível percorrer, por exemplo, um caminho que parta da base e
retorne a ela por outro caminho apos atingir o punho. Exemplos deste tipo de
manipuladores são os robôs pórticos (“gantry”), utilizados em operações de
manipulação e armazenagem de material. Existem ainda braços que
apresentam parte da cadeia aberta e parte fechada, denominados de cadeia
parcialmente fechada. A Figura 3.9 mostra um esquema de um braço com
cadeia parcialmente fechada. Percebe-se, neste esquema, que o braço possui
apenas um grau de liberdade, embora possua 4 articulações e 3 elos. O
acionamento deste braço deve ser feito com um único motor, conectado a uma
das duas articulações da base. Tais cadeias permitem que o motor de
acionamento de uma dada junta possa ser fixado mais próximo da base, o que
permite reduzir a inércia do conjunto e aumentar a velocidade e precisão do
manipulador.

Representação
Representa o esquemática
esquem tica de braço
bra o robótico
rob tico com cadeia cinemática
cinem tica
Parcialmente fechada.

Robótica Teoria e Prática


Robótica Teoria e Prática

Manipuladores de cadeia parcialmente fechada (a esquerda) e fechada (a direita)

A representação esquemática de junções ou articulações não motoras nos


braços com cadeia fechada e diferente daquela utilizada nas juntas motoras.
Costuma-se utilizar a mesma representação daquela utilizada nas juntas,
porem em tamanho menor. Alem disso, e freqüente, em tais braços, a
existência de 3 ou mais articulações ou juntas fixadas ao mesmo elo.

Representação
Representa o esquemática
esquem tica de articulações
articula es não
n o motoras

Configuração
Configura o dos robôs
rob s
A configuração física dos robôs (Groover, 1988) esta relacionada com os tipos
de juntas que ele possui. Cada configuração pode ser representada por um
esquema de notação de letras, como visto anteriormente. Considera-se

Robótica Teoria e Prática


Robótica Teoria e Prática

primeiro os graus de liberdade mais próximos da base, ou seja, as juntas do


corpo, do braço e posteriormente do punho. Como visto anteriormente, um
braço mecânico e formado pela base, braço e punho. O braço e ligado a base e
esta e fixada ao chão, a parede ou ao teto. E o braço que efetua os movimentos
e posiciona o punho. O punho e dotado de movimentos destinados a orientar
(apontar) o órgão terminal. O órgão terminal executa a ação, mas não faz parte
da anatomia do braço robótico, pois depende da aplicação a ser exercida pelo
braço. A movimentação do braço e a orientação do punho são realizadas por
juntas, que são articulações providas de motores. Em resumo, a base sustenta
o corpo, que movimenta o braço, que posiciona o punho, que orienta o órgão
terminal, que executa a ação. Em geral utilizam-se 3 juntas para o braço e de 2
a 3 juntas para o punho. Os elos do braço são de grande tamanho, para
permitir um longo alcance. Por outro lado, os elos do punho são pequenos, e,
às vezes, de comprimento nulo, para que o órgão terminal desloque-se o
mínimo possível durante a orientação do punho. Adota-se uma nomenclatura
para os manipuladores com base nos tipos de juntas utilizadas na cadeia de
elos, que parte da base em direção ao órgão terminal. Assim um manipulador
TRR teria a primeira junta (da base) torcional, e as duas seguintes seriam
rotacionais. “““ “““ O punho segue a mesma notação, porem separa-se o corpo
do punho por dois pontos”:”, por exemplo, TRR: RR. As configurações típicas
para o braço e o punho de robôs industriais são apresentadas nas Tabelas.

Esquema de notação
nota o para designar configurações
configura es de robôs
rob s
Configura
Configuração rob – braço
igura o do robô bra o e corpo Símbolo
mbolo

Configuração cartesiana LLL

Configuração cilíndrica LVL

Configuração articulada ou revoluta TRR

Configuração esférica TRL

Robótica Teoria e Prática


Robótica Teoria e Prática

Configuração SCARA VRL

Esquema de notação
nota o para designar configurações
configura es do pulso
Configuração rob – (pulso)
Configura o do robô Símbolo
mbolo

Configuração Pulso de 2 eixos RT

Configuração Pulso de 3 eixos TRT

Configuração
Configura o de um punho TRT na forma compacta. Embora todas as
juntas sejam resolventes, este punho tem denominação
denomina o TRT.

Robô
Rob cartesiano
cartesiano

O robô de coordenadas cartesianas usa três juntas lineares. E o robô de


configuração mais simples, desloca as três juntas uma em relação a outra. Este
robô opera dentro de um envoltório de trabalho cúbico.

Robótica Teoria e Prática


Robótica Teoria e Prática

Robô
Rob cartesiano (LLL)
Robô
Rob cilíndrico
cil ndrico
Este braço possui na base uma junta prismática, sobre a qual apóia uma junta
rotativa (resolvente ou torcional). Uma terceira junta do tipo prismática e
conectada na junta rotativa formando uma configuração LVL. Este braço
apresenta um volume de trabalho cilíndrico, e pode-se apresentar também na
configuração TLL.

Braço
Bra o robótico
rob tico cilíndrico
cil ndrico

Robô
Rob esférico
esf rico ou polar
Este tipo de braço robótico foi projetado para suportar grandes cargas e ter
grande alcance. E bastante utilizado para carga e descarga de maquinas,

Robótica Teoria e Prática


Robótica Teoria e Prática

embora o braço revoluto seja mais comum nestas aplicações. Ele conta com
duas juntas rotativas seguidas de uma junta prismática. A primeira junta move o
braço ao redor de um eixo vertical, enquanto que a segunda junta gira o
conjunto ao redor de um eixo horizontal. O volume de trabalho e um setor
esférico, de onde este manipulador obteve seu nome. A denominação “polar”
deve-se as coordenadas polares de sistemas de eixos cartesianos,
caracterizadas por duas coordenadas angulares (juntas rotativas) e uma
coordenada radial (junta prismática). Este tipo de braço esta em desuso, sendo
substituídos pelos braços revolutos.

Robô
Rob polar em configuração
configura o VVL.
Robô
Rob SCARA
Este e também um braço bastante utilizado, pois e compacto, tem grande
precisão e repetibilidade, embora com um alcance limitado. Estas
características o tornam próprios para trabalhos em montagem mecânica ou
eletrônica que exigem alta precisão. Possui duas juntas rotativas e uma junta
linear, que atua sempre na vertical, como visto na Figura 3.16. O volume de
trabalho deste braço e cilíndrico, porem, como utiliza juntas rotativas, e também
considerado articulado. O nome e um acrônimo de Selective Compliance
Assembly Robot Arm, ou Braço Robótico de Montagem com Complacência
Seletiva.

Robótica Teoria e Prática


Robótica Teoria e Prática

Robô
Rob com articula
articulação
icula o horizontal SCARA.

Robô
Rob articulado ou revoluto

Estes tipos de robôs (Groover, 1988, Adade Filho, 1992), possuem 3 juntas
rotativas, conforme ilustrada a Figura 3.17. Eles são os mais usados nas
indústrias, por terem uma configuração semelhante ao do braço humano,
(braço, antebraço e pulso). O pulso e unido a extremidade do antebraço, o que
propicia junta adicional para orientação do órgão terminal. Este modelo de
configuração e o mais versátil dos manipuladores, pois assegura maiores
movimentos dentro de um espaço compacto.

Os braços
bra os revolutos podem ser de dois tipos:

Cadeia aberta ou cadeia parcialmente fechada. Nos primeiros pode-se


distinguir facilmente a seqüencia natural formada por elo-junta, da base ate o
punho.
Nos braços de cadeia parcialmente fechada o atuador da terceira junta efetua o
movimento desta por meio de elos e articulações não motorizadas adicionais.

Robótica Teoria e Prática


Robótica Teoria e Prática

Robô
Rob articulado ou revoluto

Robô
Rob paralelo
Estes tipos de manipuladores possuem juntas que transformam movimentos de
rotação em translação, ou usam diretamente juntas prismáticas. Sua principal
característica e um volume de trabalho reduzido, porem uma alta velocidade, o
que o torna propicio para certas atividades de montagem. Outra característica
destes braços e que eles não possuem cinemática com cadeia aberta, como a
maioria dos robôs industriais. Os quatro ou seis atuadores destes braços unem
a base diretamente ao punho.

Robótica Teoria e Prática


Robótica Teoria e Prática

Um robô
rob do tipo pórtico
p rtico (“
(“gantry”
gantry”), a esquerda, fabricado pela BMI, e um robô
rob
Cilíndrico
Cil ndrico feito pela ST
ST Robotics, a direita.

Braço robô SCARA, produzido


Bra o do tipo polar, feito pela Fanuc, a esquerda e um rob
Pela Staubli, a direita.

Um braço revoluto de cadeia aberta comercializado pela Panasonic (a


esquerda) e o robô paralelo Quattro produzido pela Adept (a direita).

Órg
rgão
rg o terminal
Na robótica, órgão terminal (Groover, 1988) e usado para descrever a Mao ou
Ferramenta que esta conectada ao pulso, como por exemplo, uma pistola de
solda, garras, pulverizadores de tintas, entre outros. O órgão terminal e o
responsável por realizar a manipulação de objetos em diferentes tamanhos,

Robótica Teoria e Prática


Robótica Teoria e Prática

formas e materiais, porem esta manipulação depende da aplicação ao qual se


destina. E valido ressaltar que os órgãos terminais requerem cuidados ao
serem projetados, pois e necessário controlar a forca que esta sendo aplicada
num objeto. Para isso, alguns órgãos terminais são dotados de sensores que
fornecem informações sobre os objetos. Existe uma grande variedade de
modelos de garras que podem ser utilizadas em diversas aplicações, como por
exemplos:
Garra de dois dedos;
Garra para objetos cilíndricos;
Garra articulada.
A garra de dois dedos, e um modelo simples e com movimentos paralelos ou
rotacionais. Este modelo de garra proporciona pouca versatilidade na
manipulação dos objetos, pois existe limitação na abertura dos dedos. Desta
forma a dimensão dos objetos não pode exceder esta abertura.

Modelo de garras de dois dedos

A garra de objetos cilíndricos, como pode ser visualizada, também consiste de


dois dedos com semicírculos, os quais permitem segurar objetos cilíndricos de
diversos diâmetros diferentes.

Robótica Teoria e Prática


Robótica Teoria e Prática

Modelo de garra para objetos cilíndricos


cil ndricos
A garra articulada tem a forma mais similar a mão humana, a qual proporciona
uma versatilidade considerável para manipular objetos de formas irregulares e
tamanhos diferentes. Esta característica esta relacionada com a quantidade de
elos. Estes elos são movimentados por cabos ou músculos artificiais, entre
outros.

Modelo de garra articulada

Sensores
Sensores são dispositivos cuja finalidade e obter informações sobre o ambiente
em que se encontram, e são utilizados como componentes do sistema de
controle de realimentação do robô. Ha diversos tipos de sensores que podem
ser classificados de acordo com os princípios físicos sobre os quais eles estão
baseados.

Sensor de posição
posi o

O sensor de posição determina as posições dos elos ou de elementos externos,


informando ao sistema de controle que, então, executa as decisões apropriadas
para o funcionamento. Um tipo de sensor de posição, por exemplo, e o
“encoder” que tem como propriedade informar a posição por meio de contagem
de pulsos. Neste caso, tem-se uma fonte de luz, um receptor e um disco
perfurado, que ira modular a recepção da luz ao girar. Este disco esta preso a

Robótica Teoria e Prática


Robótica Teoria e Prática

uma junta, de forma a criar um movimento rotacional, enquanto que a fonte de


luz e o receptor estão fixos. A rotação do disco cria uma serie de pulsos pela
interrupção ou não da luz recebida pelo detector. Estes pulsos de luz são
transformados pelo detector em uma serie de pulsos elétricos. Os “encoders”
podem ser classificados em absoluto e incremental.

Sensor de toque

O sensor de toque fornece um sinal binário de saída que indica se houve ou


não contato com o objeto. Um dos modelos mais simples e feito com duas
chapas de metal que devem ser tocadas ao mesmo tempo pelos dedos de uma
pessoa. A resistência dos dedos e suficiente para acionar um circuito sensível.

Sensor de pressão
press o

O sensor de pressão e uma estrutura mecânica planejada a deformar-se dentro


de certos limites. Um modelo simples deste tipo de sensor pode ser feito com
material de esponja condutora, pois ela tem uma resistividade elevada que se
altera quando deformada. Outro modelo mais sofisticado e versátil e o strain-
gage, que e, na sua forma mais completa, um resistor elétrico composto de
uma finíssima camada de material condutor. As tensões mecânicas são
proporcionais as deformações medidas pelo sensor.

Sistemas de acionamento

Os acionadores (Groover, 1988) são dispositivos responsáveis pelo movimento


das articulações e do desempenho dinâmico do robô. Esses dispositivos podem
ser elétricos, hidráulicos ou pneumáticos, cada um com suas características. A
seguir será descrito o funcionamento desses dispositivos.

Acionadores hidráulicos
hidr ulicos

Robótica Teoria e Prática


Robótica Teoria e Prática

Os principais componentes deste sistema são: motor, cilindro, bomba de óleo,


válvula e tanque de óleo. O motor e responsável pelo fluxo de óleo no cilindro
em direção ao pistão que movimenta a junta. Assim, este tipo de acionador e
geralmente associado a robôs de maior porte, quando comparados aos
acionadores pneumáticos e elétricos. Entretanto a precisão em relação aos
acionadores elétricos e menor. Existem diversos tipos diferentes de motores
hidráulicos, como motor de palheta, de engrenagem, de lóbulos, etc., e todos
eles apresentam características de alto torque especifico, ou seja, torque
elevado com massa e volume reduzidos. São, portanto, apropriados para
braços que manipulam grandes cargas. Em contrapartida, a exigência de
elementos de controle e pressurização do fluido hidráulico faz com que o custo
destes sistemas seja elevado, tornando-se vantajoso apenas em braços de
grande porte. Apresentam, adicionalmente, problemas de manutenção, já que
podem ocorrer vazamentos do fluido e desgaste na bomba e motores. Deve ser
mencionado, finalmente, que atuadores hidráulicos lineares são mais
compactos e robustos do que seus equivalentes elétricos ou mesmo
pneumáticos, e com isso são indicados para uso em robôs do tipo pórtico ou
esféricos, que utilizam juntas prismáticas.

Acionadores elétricos
el tricos
Geralmente robôs de tamanho pequeno a médio utilizam acionadores elétricos.
Os acionadores elétricos mais comuns em uso nos robôs são: motor de
corrente continua ou DC, servo-motor e motor de passo. Esses tipos de
acionadores não propiciam muita velocidade ou potencia, quando comparados
com acionadores hidráulicos, porem atingem maior precisão. Em geral são
dotados de redutores para reduzir a velocidade e aumentar o torque.
Acionamentos elétricos podem ser utilizados em juntas prismáticas, com a
transformação do movimento rotativo do motor em movimento linear por meio
de um fuso. Motores elétricos lineares não são utilizados, pois produzem forcas
de pequena intensidade. O custo do acionamento elétrico cresce com o torque
necessário para acionar o braço mecânico, já o tamanho do motor e
praticamente proporcional ao conjugado produzido. Por outro lado, a simples
redução da velocidade, por meio de redutor, embora propicie maior precisão e

Robótica Teoria e Prática


Robótica Teoria e Prática

maior torque, reduz significativamente a produtividade. Maior torque significa


maior velocidade ou maior carga, e ambos são desejáveis. O custo de
acionadores hidráulicos cresce também com a demanda de torque, porem de
forma mais lenta, já que tais motores tendem a ser mais compactos.
Adicionalmente o custo dos equipamentos de condicionamento e controle do
fluido hidráulico e alto e pouco influenciado pela escala. Isto indica, que o
acionamento elétrico e mais vantajoso economicamente em braços de pequeno
e médio porte, ao passo que o acionamento hidráulico e melhor quando se trata
de gerar grandes potencias e cargas.

Custo de braços
bra os robóticos
rob ticos em função
fun o da capacidade de carga, para
acionamento hidráulico
hidr ulico e elétrico.
el trico.
Servo-
Servo-motor
Servos-motores são compostos por motores DC e um redutor de velocidades,
junto com um sensor de posição e um sistema de controle re-alimentado. Em
outras palavras, os servos-motores podem ser considerados como sendo
motores comandados em posição (angular ou linear), já que, do ponto de vista
de quem os utiliza, o controle interno em malha fechada e irrelevante. Os
servos-motores são pequenos, com ampla variação de torques. O mecanismo
de posicionamento ajusta a posição angular por meio de um sinal codificado
que lhe e enviado. Enquanto esse código estiver na entrada, o servo ira manter
a sua posição angular. Em geral o sinal e do tipo PWM (Pulse Width
Modulation), ou seja, a posição angular ira depender da largura do pulso
enviado.

Robótica Teoria e Prática


Robótica Teoria e Prática

Motor de passo

Os motores de passo são usados em aplicações de serviço relativamente leves


e algumas das suas características de desempenho são apresentadas a seguir:
Rotação em sentido horário e anti-horário;
Variações incrementais de precisão angular;
Repetição de movimentos bastante exatos;
Baixo torque;
Um torque de sustentação a velocidade zero;
Possibilidade de controle digital.
Os motores de passo podem ser bipolares ou unipolares. Em ambos os casos
as fontes utilizadas são de tensão continua e requerem um circuito digital que
produza as seqüências de sinais para que o motor funcione corretamente. A
forma com que o motor ira operar dependera bastante do que se deseja
controlar. Existem casos em que o torque e mais importante, em outras a
precisão ou mesmo a velocidade são mais relevantes. Ao trabalhar com
motores de passo, precisa-se de algumas características de funcionamento,
como a tensão de alimentação, a máxima corrente elétrica suportada nas
bobinas, o grau (precisão), o torque. Motores de passo podem ser acionados
de diversas formas. As duas formas mais comuns são: passo completo e meio
passo. No modo de operação em passo completo pode-se acionar apenas uma
ou duas bobinas a cada passo. No primeiro caso apenas uma bobina e
energizada a cada passo, o torque gerado e menor, assim como o consumo.

Passo completo com uma bobina energizada em rotação


rota o com sentido horário.
hor rio.

Robótica Teoria e Prática


Robótica Teoria e Prática

No caso de modo completo com duas bobinas energizadas, tem-se um maior


torque, e um consumo maior do que no caso anterior. A velocidade costuma
ser maior do que nas demais formas, mas a velocidade máxima de um motor
de passo e altamente dependente da eletrônica e da estratégia de controle. A
seqüência dos passos em sentido horário e o acionamento das bobinas.

Passo completo com duas bobinas em rotação


rota o no sentido horário
hor rio

Por outro lado, no modo de operação em meio passo combinam-se as duas


estratégias anteriores, obtendo-se com isso um efeito de meio passo a cada
mudança no acionamento das bobinas. Este modo consome mais energia que
os dois anteriores, mas atinge maior precisão em virtude do menor passo. O
torque gerado e próximo ao do acionamento completo com duas bobinas, mas
a velocidade costuma ser menor.
Meio passo em sentido horário
hor rio

Para mudar a direção de rotação do motor nos dois modos de acionamento,


basta inverter a seqüência dos passos.

Robótica Teoria e Prática


Robótica Teoria e Prática

Acionadores pneumáticos
pneum ticos
Os acionadores pneumáticos são semelhantes aos acionadores hidráulicos,
porem a diferença e a utilização de ar ao invés de óleo. Entretanto o ar e
altamente compressível, o que causa uma baixa precisão e forca, mas estes
acionadores possuem alta velocidade. Acionadores pneumáticos lineares
(cilindros) requerem sistemas sofisticados e complexos para controlarem a
posição em pontos ao longo do curso. Justamente por isso, são pouco
utilizados em aplicações que tenham tal necessidade. Porem, diversas tarefas
de produção podem ser automatizadas com atuadores pneumáticos lineares
trabalhando entre os extremos de posição, ou seja, totalmente recolhido ou
totalmente estendido, que apresentam boa repetibilidade. Estas tarefas em
geral são simples, consistindo de movimentação de material, fixação de pecas e
separação de objetos, chamadas genericamente de operações “pega-e-poe”. O
baixo custo dos acionadores pneumáticos e da geração de ar-comprimido faz
com que a automação pneumática seja a mais adequada se o trabalho a ser
realizado for simples. Pode-se utilizar o acionamento pneumático em juntas
rotativas de forma direta (acionadores rotativos) ou com redutores (motores
pneumáticos de lóbulos ou palhetas). Tais aplicações são, contudo, muito
especificas e indicadas apenas quando houver restrições quanto ao
acionamento elétrico ou hidráulico. A programação de sistemas pneumáticos
pode ser realizada com controladores lógicos programáveis (PLC), ou mesmo
por chaves distribuidoras e chaves fim-de-curso. Este tipo de programação
permite certa flexibilidade na seqüência de acionamentos, porem e bastante
limitada no que se refere a mudanças na forma e no tipo de tarefa executada.
Pode-se dizer, portanto, que sistemas pneumáticos estão mais próximos de
uma automação fixa do que da automação programável.

Métodos
todos de acionamento

Os acionadores elétricos (Groover, 1988) tendem a ser maiores e mais


pesados que acionadores hidráulicos e pneumáticos. Por este motivo, nem
sempre e possível posicionar tais atuadores próximos as respectivas juntas, em

Robótica Teoria e Prática


Robótica Teoria e Prática

virtude de restrições no espaço disponível ou de problemas com deflexões


devido ao peso. Assim sendo, os acionadores podem ser acoplados de forma
direta ou indireta.

Acionamento indireto

Uma vez que os atuadores das juntas são pesados, os fabricantes tentam
introduzir alterações no projeto que permitam redução do peso nas juntas
próximas ao pulso e transferir este peso, quando possível, para a base. Desta
forma consegue-se uma capacidade de carga maior para o braço. Este tipo de
acionamento e denominado indireto, já que o atuador fica afastado da junta
movida por ele. Neste tipo de acionamento, e necessário usar algum tipo de
transmissão de potencia, como polias, correntes, rodas dentadas,
engrenagens, parafusos e correias, ou seja, o acionador e adaptado longe da
junta pretendida do manipulador. Entretanto este método sofre efeitos
indesejados no desempenho do robô, devido a folga nas engrenagens, flexão
dos vínculos do manipulador, escorregamento dos sistemas de polias.

Acionamento direto
Neste método, o acionador e adaptado diretamente na junta, o que, em
determinados casos, proporciona melhor precisão e rendimento de potencia em
relação ao acionamento indireto. Contudo, devido ao baixo torque por unidade
de peso alcançado pelos motores elétricos, costuma-se utilizá-los em conjunto
com redutores de engrenagens, que aumentam o torque, porem reduzem a
velocidade. Neste caso, se o acionador estiver fixado no elo motor, o
acionamento e considerado direto. Nas juntas rotativas com acionamento
direto, o sensor de posição angular (“encoder”) fornece o angulo relativo entre o
elo motor e o elo movido. No acionamento indireto esta leitura fornece o angulo
do elo movido em relação a um outro elo, anterior ao elo motor.
Volume de trabalho
O volume de trabalho (Groover, 1988) e o termo que se refere ao espaço que
um determinado braço consegue posicionar seu pulso. Este volume, em geral,
e estabelecido conforme os limites impostos pelo projeto estrutural do braço, ou

Robótica Teoria e Prática


Robótica Teoria e Prática

seja, a configuração física do braço robótico, os limites dos movimentos das


juntas e o tamanho dos componentes do corpo, braço e pulso. Por exemplo, o
volume de trabalho de um braço esférico (TRL) seria, teoricamente, o volume
da esfera cujo raio e o comprimento do braço esticado. Braços robóticos
possuem volumes que dependem, e claro, da geometria e dos limites impostos
ao movimento por motivos estruturais ou de controle. Na maior parte deles, o
volume e altamente dependente de detalhes construtivos e raramente aparenta
ou aproxima-se do volume teórico. Por exemplo, o volume de um manipulador
cilíndrico deveria ser um cilindro, mas em geral não e. Em resumo, o volume de
trabalho de um manipulador depende, basicamente, da configuração do braço,
dos comprimentos dos elos (braço e punho) e de limites e restrições
construtivas a movimentação das juntas.

Volume de trabalho teórico


te rico de um robô
rob cilíndrico.
cil ndrico.
Os volumes de trabalho são medidos em unidades volumétricas, porem isto
pouco ou nada contribui na seleção de um braço para determinada aplicação.
Muito mais importante do que conhecer que o volume de um braço e de 1832
litros seria saber se ele consegue ou não atingir um ponto afastado de 840 mm
do seu eixo vertical, por exemplo. Em virtude deste aspecto, os fabricantes de
manipuladores robóticos fornecem o volume de trabalho em termos do alcance
do braço em um ou mais planos. A área de trabalho de um braço SCARA em
vista superior, produzido pela Staubli. O deslocamento da terceira junta e de
200 mm, neste braço. Braços articulados ou resolventes apresentam em geral
um volume bastante complexo, pois as juntas têm movimentos limitados. O
volume do braço KR30HA produzido pela Kuka Robotics.

Robótica Teoria e Prática


Robótica Teoria e Prática

( rea) útil
Volume (área) til do manipulador RS40B. (Fonte: Staubli Robotics)

Robótica Teoria e Prática


Robótica Teoria e Prática

Volume de manipulador KR30HA produzido pela Kuka Robotics. (Fonte: Kuka


Robotics).
Os volumes, alcances ou áreas de trabalho devem ser expressos sem a
presença do órgão terminal, já que este pode alterar significativamente tais
valores, dependendo da aplicação.

Dispositivos de entrada para manipuladores


Vários tipos de dispositivos de entrada como joystick, mouse, teclado e luvas
artificiais permitem programar um robô. Esses dispositivos são meios de
interação homem35 maquina, isto e, sinais de dados que são enviados ao
sistema de controle, e este os transmitem para os acionadores, os quais
realizam os movimentos dos manipuladores.

Sistema de Controle

O sistema de controle de qualquer robô e realizado por meio de um sistema de


“Software” e “hardware”. Este sistema processa os sinais de entrada e converte
estes sinais em uma ação ao qual foi programado. O software pode ser
desenvolvido em um computador pessoal ou num micro controlador.
controlador Neste
aspecto, deve-se levar em consideração os pontos fortes e fracos de cada
possibilidade. O micro controlador reduz o custo do projeto, e rápido, dedica-se
apenas ao controle do robô, porem possui limitações em relação ao tamanho do
software. Já o computador pessoal possui alta taxa de processamento e maior
espaço para a alocação do software. Pode-se ainda aplicar uma solução mista,
em que a parte mais leve do software fica no micro controlador e a parte de
maior processamento fica no computador pessoal. O sistema de hardware
pode constituir, por exemplo, de motores de passos, cabos, dispositivo de
entrada, sensores e amplificadores de potencia. Um dos fatores mais
importantes e a utilização de sensores (Bolton, 1995), pois podem ser
dispositivos de um sistema de malha fechada, ou seja, consiste em verificar o
estado atual do dispositivo a ser controlado e comparar essa medida com um
valor predefinido. Esta comparação resultara num erro, ao qual o sistema de

Robótica Teoria e Prática


Robótica Teoria e Prática

controle fará os ajustes necessários para que o erro seja reduzido a zero. Um
esquema simples de malha fechada e apresentado em diagrama de blocos.

Diagrama de blocos do controle em malha fechada de um manipulador


manipulador
robótico.
rob tico.

Programação
Programa o de robôs
rob s
Braços
Bra os mecânicos
mec nicos são
s o programados de diversas formas:

Manipulador manual: E todo engenho mecânico de manejo de pecas ou


ferramentas que requeira a intervenção manual do homem para sua operação,
ou seja, o homem guia manualmente a maquina servindo essa como uma
multiplicadora de forcas;
Robô
Rob seqüencial:
seq encial: E aquele que realiza um trajeto seqüencial, podendo ser
uma seqüência fixa definida pelo fabricante e inacessível para o usuário, ou de
seqüência variável em que e alterada conforme as necessidades dos usuários;
Robô
Rob de aprendizagem: Neste tipo de robô, o trajeto ou seqüência e
programado guiando-o manualmente pelo caminho que deve seguir;
Robô "inteligente”: E aquele que muda as condições de trabalho mediante
estímulos externos provenientes de sensores óticos, magnéticos, sonoros, etc.

Dinâmica
Din mica do braço
bra o robótico
rob tico

O desempenho dinâmico do braço robótico (Groover, 1988) esta associado a


velocidade de resposta, estabilidade e precisão. A velocidade de resposta
refere-se a destreza do braço robótico ao mover-se de um lugar para outro num
curto período de tempo. Desta forma, o torque existente em cada junta do

Robótica Teoria e Prática


Robótica Teoria e Prática

braço e a aceleração em cada elo devem ser analisadas. Já a estabilidade pode


ser estimada com base no tempo necessário para amortecer as oscilações que
ocorrem durante o movimento de uma posição para a outra. Se a estabilidade
for baixa pode-se aplicar elementos de amortecimento no braço, que melhoram
a estabilidade, mas influem na velocidade de resposta. A precisao esta
relacionada com a velocidade e estabilidade, pois e uma medida de erro na
posição do órgão terminal. Os conceitos relacionados com a precisão são
analisados a seguir.

Precisão
Precis o dos movimentos

A precisão de movimento esta intrinsecamente correlacionada com três


características, como segue:

Resolução espacial
Precisão
Repetibilidade.

A resolução espacial depende diretamente do controle de sistema e das


inexatidões mecânicas do braço robótico. O sistema de controle e o
responsável por controlar todos os incrementos individuais das articulações. Já
as inexatidões relacionam-se com a qualidade dos componentes que formam
as uniões entre as articulações, como as folgas nas engrenagens, tensões nas
polias, e histereses mecânicas e magnéticas, entre outros fatores. A precisão
esta relacionada com a capacidade de um braço posicionar o seu pulso em um
ponto marcado dentro do volume de trabalho. A precisão relaciona-se com a
resolução espacial, pois a precisão depende dos incrementos que as juntas
podem realizar para se movimentar e atingir um ponto determinado. Por fim, a
repetibilidade esta relacionada com a capacidade do braço robótico de
posicionar repetidamente seu pulso num ponto determinado. Estes movimentos
podem sofrer influencias de folgas mecânicas, da flexibilidade e das limitações
do sistema de controle.

Robótica Teoria e Prática


Robótica Teoria e Prática

Transmissão
Transmiss o de potencia

Na maioria dos braços robóticos não e possível encontrar acionadores com as


propriedades exatas de velocidade-torque ou de velocidade-forca. Sendo
assim, existe a necessidade de se usar algum tipo de dispositivo de
transmissão de potencia. Para isso pode-se usar correias e polias, correntes e
rodas dentadas, engrenagens, eixos de transmissão e parafusos. Um exemplo
de dispositivo de transmissão simples e bastante utilizado em robôs e a
engrenagem. As engrenagens possuem movimentos rotativos e a transferência
pode ser entre eixos perpendiculares ou eixos paralelos. Duas engrenagens
para transmissão com eixos paralelos e são conhecidas como engrenagens
cilíndricas. A menor e conhecida como pinhão, e a maior e a coroa. Se o pinhão
tiver um quarto do tamanho da coroa, para cada revolução feita pelo pinhão a
coroa gira apenas um quarto de uma revolução, reduzindo, portanto, em um
quarto a velocidade angular e aumentando o torque em quatro vezes.

Engrenagens para transmissão, com eixos paralelos.


O numero de dentes numa engrenagem e proporcional a seu diâmetro, então a
relação das engrenagens e obtida por:

onde N1 e o numero de dentes do pinhão e N2 e numero de dentes da coroa.


A velocidade da saída em relação a entrada e dada por:

Robótica Teoria e Prática


Robótica Teoria e Prática

em que ω e a velocidade de saída e ω e a velocidade de entrada. O torque


o in

vale:

Precisão
Precis o cartesiana em juntas robóticas
rob ticas
Supondo-se que sejam conhecidas as precisões (ou resolução do controle) em
cada uma das juntas de um braço mecânico, deseja-se saber qual será a
precisão cartesiana, isto e, qual será a precisão do braço num determinado
ponto de trabalho. E evidente que a precisão cartesiana depende do ponto de
operação, pois os erros de juntas rotativas são mais acentuados quando o
braço estiver estendido do que quando estiver recolhido. Será feita agora uma
analise simples para um braço de apenas uma junta rotativa, e, a seguir, um
braço composto de duas juntas rotativas movendo-se num plano. Considera-se
um braço articulado movendo-se no plano xy, tal que a origem do sistema
coincida com o eixo de rotação, conforme mostra a figura 3.30. Ao passar da
posição P para a posição P', movendo-se do incremento mínimo (resolução da
junta), as novas coordenadas cartesianas do ponto passam a ser x' e y'. Como
o vetor de deslocamento v possui modulo a , e lembrando que PP' e
perpendicular ao elo a em P para pequenos valores do ângulo , tem-se que:

Nota-se que um erro de posicionamento tanto pode ser positivo quanto


negativo. Contudo, uma vez que deseja-se em geral o erro Maximo que um
dado braço possa apresentar, então deve-se obter o modulo do erro ou seja:

Robótica Teoria e Prática


Robótica Teoria e Prática

Deslocamento angular de um braço


bra o com 1GL.

Considera-se agora um braço com dois graus de liberdade e duas juntas


rotativas movendo-se num plano. Neste braço percebe-se que as imprecisões
cartesianas dependem do movimento de ambas as juntas, uma vez que tanto
J1 quanto J2 movimentam a extremidade do braço (garra). O erro total será
portanto composto pela soma dos erros causados por cada uma das juntas. A
junta J2 provoca um erro semelhante ao causado por um braço de uma única
junta, visto anteriormente, de tal forma que.

Robótica Teoria e Prática


Robótica Teoria e Prática

Deslocamento angular de um braço


bra o com 2GL num plano.

Se for também pequeno, então se pode projetar o vetor v em ambas as


direções para se obter:

Se o braço possuir uma junta prismática, como visto abaixo, então segue
imediatamente que a projeção do erro _a nos eixos cartesianos devido ao
movimento linear da junta J2 e dado por.

e o erro devido ao movimento rotacional da junta J1 e semelhante ao descrito


no primeiro exemplo acima, resultando para o erro total.

Robótica Teoria e Prática


Robótica Teoria e Prática

Deslocamento de um braço
bra o com 2GL e juntas
juntas RL.
Percebe-se nos exemplos mostrados que passando o incremento ao limite,
tem-se que,

onde indica a derivada parcial da coordenada cartesiana x com relação


a variação do angulo . Esta expressão vale também para a segunda junta, e
vale igualmente para braços que se movem no espaço. Isto permite generalizar
a expressão para a precisão cartesiana na forma:

onde w e um eixo cartesiano qualquer (x, y ou z), e os (i = 1, 2, ..., n) são as


variáveis das n juntas deste braço. Esta mesma expressão pode ser utilizada
em braços com juntas prismáticas, tomando-se apenas o cuidado de lembrar
que nestas juntas a variável e o comprimento do elo e não o angulo da junta.

Robótica Teoria e Prática


Robótica Teoria e Prática

Cinemática e dinâmica de manipuladores

A cinemática trata do estudo dos movimentos dos robôs sem considerar as


causas que lhes dão origem (Groover, 1988). Por sua vez, a dinâmica e o
estudo do movimento levando se em conta as forcas e torques que os causam.
Para tratar dos movimentos dos manipuladores e necessário desenvolverem
técnicas para representar a posição de determinado ponto do braço no tempo.
Esta representação depende da posição das juntas e dos elos, sendo que e
necessário ter a base do robô como ponto de referencia. Manipuladores
compostos essencialmente por juntas prismáticas não apresentam grandes
problemas com relação a cinemática. Contudo, braços articulados são
amplamente utilizados na indústria devido a sua versatilidade em substituir
trabalhador humano e também por ser altamente compacto. Nestes
manipuladores a cinemática torna-se mais complexa. Independentemente da
geometria do manipulador, a solução da cinemática requer conhecimento de
geometria, trigonometria e calculo vetorial. No Apêndice A e oferecido um
resumo da trigonometria necessária para resolver problemas de cinemática.
Uma vez que não ha uma regra geral para equacionar a cinemática em braços
mecânicos, deve-se analisar caso a caso. Iniciaremos a analise nos
manipuladores mais simples e aumentaremos a complexidade a cada novo
exemplo. A posição do órgão terminal de um manipulador depende, a cada
instante, dos valores dos deslocamentos angulares das juntas rotativas e
deslocamentos lineares das juntas prismáticas. Em outras palavras, se for
possível conhecer a posição de cada junta, pode-se saber a posição do órgão
terminal e, inversamente, caso se conheça a posição da extremidade do robô
pode-se calcular qual deve ser a configuração das juntas para atingir tal
posição. Para o sistema de controle dos braços mecânicos somente as posições
das juntas são relevantes. Em geral estes não reconhecem comandos com
posicionamento no espaço. Por outro lado, e freqüente encontrar-se aplicações
nas quais se deseja que braço posicione o órgão terminal numa dada posição,
com uma dada orientação do punho. Um caso típico e uma aplicação na qual se

Robótica Teoria e Prática


Robótica Teoria e Prática

deseja reprogramar um braço sem parar a linha de produção. Nesta situação,


uma medição cuidadosa da posição e orientação desejadas com relação a um
sistema de referencias cartesiano fixado a base do manipulador oferece uma
alternativa a programação usual por aprendizagem. Veja-se, contudo, que
muitas vezes esta medição pode ser complexa em virtude da precisão exigida e
requer instrumentos especiais. Constata-se, portanto, que e perfeitamente
possível calcular a posição cartesiana no espaço, bem como a orientação do
punho, com base no conhecimento dos ângulos das juntas. Este
equacionamento e conhecido como cinemática direta. O calculo das posições
angulares a partir da posição no espaço consiste, portanto, na cinemática
inversa. Uma vez que a determinação das posições das juntas pode tanto ser
feita em ângulos, nas juntas rotativas, quanto em deslocamentos, nas juntas
lineares, denomina-se genericamente a estes de variáveis de junta. A posição
no espaço e realizada num sistema de eixos retangulares e conhecida como
coordenadas cartesianas.

Transformações
Transforma es entre variáveis
vari veis de junta e variáveis
vari veis cartesianas

O calculo da cinemática, tanto direta quanto inversa, requer o conhecimento do


Comprimento dos elos com precisão adequada. Fabricantes de manipuladores
fornecem não apenas estes comprimentos, como também quaisquer
deslocamentos entre juntas que possa existir no braço, de forma a se poder
calcular completamente a posição cartesiana. Nos exemplos que se seguem as
juntas devem ser rotuladas como J , com n iniciando com 1 na base do braço
n

robótico. Os elos são rotulados por L , novamente sendo 1 o elo mais próximo
n

da base. Variáveis angulares são representadas genericamente por ,


numeradas a partir da base, e variáveis lineares são representadas por a ou i

Robótica Teoria e Prática


Robótica Teoria e Prática

então di. E conveniente que a numeração seja seqüencial com relação as


juntas, sem se esquecer, contudo, que certos tipos de juntas podem ter mais
de um grau de liberdade, e, portanto, mais de uma variável. Num braço TRL,

por exemplo, a notação de variáveis de junta poderia ser: Nos


exemplos a seguir, inicia-se com um braço articulado com 2 graus de liberdade,
com movimento num plano. Nos demais exemplos adicionam-se
gradativamente mais juntas e, posteriormente, passa-se ao movimento no
espaço.

Manipulador RR em movimento plano

Neste exemplo será calculada a cinemática direta, a cinemática inversa e a


precisão cartesiana de um manipulador RR de elos com comprimento a1 e a2
movendo-se num plano vertical.

Manipulador RR em movimento plano vertical

As equações da cinemática direta são obtidas pela aplicação de trigonometria


aos triângulos formados pelas juntas e elos. Estas equações resultam:

Robótica Teoria e Prática


Robótica Teoria e Prática

Geometria do manipulador RR

As equações da cinemática inversa podem ser obtidas de:

Robótica Teoria e Prática


Robótica Teoria e Prática

Pode-se igualmente obter a expressão acima pela aplicação da lei dos co-
senos ao triangulo formado pelo centro da junta 1, centro da junta 2 e ponto P
na extremidade da garra. Neste caso, o angulo conhecido e o angulo entre os
elos, que e igual a 180 –
o . Nota-se que a inversão do co-seno fornece dois
valores possíveis para o angulo , que correspondem a duas situações nas
quais existe uma solução para o problema. Na primeira delas com > 0, tem-
se a solução normal, com cotovelo para baixo. Na segunda solução, igualmente
valida, a junta 2 situa-se acima tal que o angulo e negativo. Nota-se também
que o valor de e diferente nas duas situações.

As duas soluções
solu es possíveis
poss veis para a cinemática
cinem tica inversa do
do manipulador RR

O angulo será obtido pela aplicação da tangente da diferença entre ângulos.


No triangulo OPQ, (onde O e o centro da junta 1, P e a extremidade do órgão
terminal e PQ e perpendicular a reta OR, e R e o centro da junta 2), tem-se que

Robótica Teoria e Prática


Robótica Teoria e Prática

Ângulos do manipulador RR para a determinação da cinemática inversa


Da mesma figura, tem-se também que

Robótica Teoria e Prática


Robótica Teoria e Prática

Esta expressão mostra que o angulo depende de , que já foi determinado


previamente no calculo da cinemática inversa. Pode-se, caso seja necessário,
substituir os valores do seno e do co-seno de nesta expressão. Porem isto
só aumentaria a complexidade da equação e tornaria o calculo mais trabalhoso.
E mais pratico deixar nesta forma, desde que todas as variáveis que apareçam
na equação estejam previamente calculadas. A titulo de exemplo, adotando-se
a solução positiva de e substituindo o seno e o co-seno deste ângulo na
expressão acima se chega apos uma simplificação, a

Quando substituídos nesta expressão, os dois valores possíveis para o angulo


irão resultar em dois valores distintos de . A escolha entre eles fica a
cargo do programador do braço, que pode selecionar o cotovelo para cima ou
para baixo. As equações da cinemática inversa podem ser também obtidas por
manipulação algébrica da cinemática direta. Partindo-se das equações que
fornecem x e y em termos das variáveis de junta, então ao aplicar-se a
decomposição do seno e do co-seno da soma de ângulos chega-se a

Tem-se agora um sistema linear composto por duas equações e duas


incógnitas que são o seno e co-seno de , pois se considera que seja

Robótica Teoria e Prática


Robótica Teoria e Prática

conhecido. Este sistema pode ser resolvido facilmente por substituição ou


qualquer outro método, e obtêm o resultado

A tangente de e agora calculada pela relação entre o seno e o co-seno e,


Obviamente, resulta na mesma expressão já relacionada acima.
A precisão nos eixos cartesianos neste braço e obtida da formulação geral e
vale:

Manipulador RRR em movimento plano


Será apresentada agora a formulação da cinemática direta, da cinemática
inversa e a da precisão cartesiana de um manipulador RRR de elos a1, a2 e a3
movendo-se num plano vertical, dado que a orientação do ultimo elo com
relação a horizontal e um angulo ∏ conhecido.

Robótica Teoria e Prática


Robótica Teoria e Prática

Manipulador RRR em movimento plano vertical


As equações da cinemática direta são obtidas de maneira semelhante ao
exemplo anterior, ou seja, pela adição das projeções das juntas nos eixos
cartesianos. Com isso tem-se que:

Nota-se que a cinemática inversa não pode ser resolvida, pois ha apenas duas
equações com 3 incógnitas (os três ângulos das juntas). De fato, pode-se
mostrar facilmente que existem infinitas soluções de ângulos que satisfazem a
condição do órgão terminal atingir um dado ponto no plano. E necessário
assumir uma condição a mais e esta condição já foi estabelecida no enunciado
do problema ao se fixar a orientação da junta J com o angulo ∏ (com relação a
3

horizontal). Isto significa que nem todas as soluções satisfazem as equações,


mas somente aquela (ou aquelas) nas quais o angulo do elo a com relação a
3

horizontal for igual a ∏ (fornecido). Isto indica claramente que a posição da


junta J pode ser determinada, uma vez que se conheça a posição do órgão
3

terminal x e y e este angulo. De fato, por geometria tira-se que a posição de J ,


3

denotada por x e y vale :


3 3

Robótica Teoria e Prática


Robótica Teoria e Prática

Algumas das infinitas configurações


configura es possíveis
poss veis do braço
bra o RRR na cinemática
cinem tica
inversa.

O problema agora e reduzido a se encontrar os valores dos ângulos e A


geometria deste braço reduzido e idêntica aquela apresentada no exemplo
anterior, composta por duas juntas RR, com a única modificação de que os
valores de x e y são substituídos por x e y . A solução e, portanto, dada por:
3 3

Finalmente para o calculo do terceiro angulo percebe-se que o angulo e


igual a soma dos ângulos das juntas, ou seja, . Logo, como e
conhecido e já foram determinados, então

Robótica Teoria e Prática


Robótica Teoria e Prática

Derivando as equações
equa es da cinemática
cinem tica direta e substituindo na expressão
express o acima
tem-
tem-se

Manipulador RLR em movimento plano

Este exemplo mostra o equacionamento da cinemática direta, cinemática


inversa e da precisão cartesiana de um manipulador RLR de elos a e a 2 3

movendo-se num plano vertical, dado que a orientação do ultimo elo com
relação a horizontal e um angulo conhecido.

Geometria do manipulador
manipulador RLR em movimento plano vertical

Robótica Teoria e Prática


Robótica Teoria e Prática

A cinemática direta deste braço e idêntica a do primeiro exemplo, uma vez que
ambos possuem a mesma geometria. Assim,

Uma vez que este braço apresenta 3 variáveis de junta ( ,a e 2 ), então se


deve obter 3 equações para a cinemática inversa. Como a cinemática direta
fornece apenas duas equações, então existem infinitas soluções possíveis para
a cinemática inversa, como pode ser visto na figura 4.9. Destas soluções, só
existe uma que satisfaz a condição + = ∏. Percebe-se então que a posição
x , y da junta J fica fixada caso o ponto P = (x, y) e o ângulo ∏ sejam
3 3 3

conhecidos. Esta posição e obtida por geometria e vale

Isto permite escrever a cinemática direta para a posição desta junta, ou seja:

Algumas
Algumas soluções
solu es possíveis
poss veis para a cinemática
cinem tica inversa
Como x e y são conhecidos, pode-se resolver este sistema para as variáveis
3 3

de junta e a . Dividindo-se a segunda pela primeira, tem-se:


2

Robótica Teoria e Prática


Robótica Teoria e Prática

E adicionando-se o quadrado de ambas resulta:

E finalmente

A precisão cartesiana deste braço e dada por

Que resulta:

Manipulador TRR em movimento no espaço


espa o
A partir deste exemplo, os manipuladores passam a mover-se no espaço ao
invés do plano. Em geral o movimento destes manipuladores pode ser
decomposto num movimento plano, semelhante aos exemplos anteriores, e
num movimento rotativo ao redor de um eixo contido no plano, o que faz com
que este plano gire no espaço. Serão obtidas neste exemplo as equações da
cinemática direta, da cinemática inversa e da precisão cartesiana de um
manipulador revoluto com 3 graus de liberdade em configuração TRR
movendo-se no espaço. A junta J1 gira sob um eixo vertical, enquanto que J2 e
J3 possuem eixos horizontais.

Robótica Teoria e Prática


Robótica Teoria e Prática

Para que os movimentos e os ângulos possam ser visualizados, serão


construídas duas vistas esquemáticas do braço: superior e lateral mostrando,
respectivamente, o movimento horizontal e os movimentos verticais (no plano).
Estas vistas são mostradas esquematicamente, com as principais medidas a
serem obtidas por relações geométricas. A vista lateral e mostrada numa
direção perpendicular a linha de interseção do plano vertical do movimento e o
plano xy.

Braço
Bra o revoluto TRR em movimento no espaço
espa o

A projeção do ponto P no órgão terminal sobre o plano xy fornece a distancia


horizontal d, que corresponde, no exemplo anterior, ao comprimento x. Esta
distancia pode ser obtida pelas projeções dos elos a e a no plano, o que
2 3

resulta Da vista superior, percebe-se que a

Robótica Teoria e Prática


Robótica Teoria e Prática

distancia d e a hipotenusa de um triangulo retângulo, o que permite que esta


distancia seja decomposta nas direções x e y. A coordenada z e calculada de
maneira semelhante a utilizada nos exemplos anteriores, e assim a cinemática
direta fica.

Nota-se que a cinemática inversa, de maneira análoga ao primeiro exemplo,


apresenta duas soluções para os ângulos : cotovelo para baixo e
cotovelo para cima. Uma vez que d representa a horizontal da projeção de P,
então deve-se exprimir esta distancia em termos das variáveis conhecidas na
cinemática inversa, que são x, y e z. Da vista superior tira-se facilmente que

Assim, a distancia r, que vai do centro da junta J ao ponto P, conforme mostra


2

a vista lateral pode também ser calculada por meio da hipotenusa do triangulo
retângulo PQR:

Aplicando agora a lei dos co-senos ao triangulo PRS, onde S e o centro da


junta J ,tira-se que (ver exemplo 1)
3

Da mesma forma, o angulo 2 e obtido por meio de diferença entre os ângulos

de maneira similar a empregada no exemplo 1. Neste caso, por


geometria tem-se que

Robótica Teoria e Prática


Robótica Teoria e Prática

Cabe neste ponto um breve comentário a respeito do calculo de ângulos com o


ar cotangente.Computacionalmente o arco-tangente e uma função que retorna
com um ângulo compreendido entre . Isto e suficiente para
finalidades matemáticas ou para estudo da cinemática de robôs, mas
certamente e insuficiente num caso real, quando a cinemática inversa for
calculada pelo sistema de controle do braço mecânico. O motivo disto e que o
braço pode atingir, e em geral atinge, ângulos fora desta faixa de limitação
como, por exemplo, entre . A função arco-tangente fornece, no
caso de um angulo real de o valor complementar de , o que
certamente levaria o braço a posicionar-se num local totalmente errado. Para
corrigir este problema emprega-se em tais programas uma função denominada
de atan2, que necessita de dois parâmetros que são os equivalentes ao seno e
ao co-seno do angulo, e que gera um angulo compreendido agora entre
.As calculadoras de bolso não programáveis não possuem tal função e,
portanto, e necessário uma analise posterior para que se conheça o quadrante
real do angulo. Para isso nota-se que o arco tangente e sempre calculado
como o produto de uma divisão entre dois fatores, associados ao seno e ao co-
seno deste angulo, ou seja:

Robótica Teoria e Prática


Robótica Teoria e Prática

onde S e no numerador e C e o denominador da fração. Se o valor de C for


positivo, o ângulo calculado pelo arco-tangente estará no seu valor correto,
entre . Se o valor de C for, ao contrario, negativo, então deve-se
acrescentar ao resultado, se este estiver em radianos, ou –180 ou
o

180 caso esteja em graus, para colocá-lo no quadrante correto. Para o calculo
o

da precisão cartesiana, deve-se lembrar que o braço possui 3 graus de


liberdade e move-se no espaço tridimensional. Tem-se, portanto 3 equações
para a precisão cartesiana e cada uma delas depende dos 3 ângulos das
juntas, ou seja

Efetuando-se as derivadas das equações da cinemática direta chega-se a

Robótica Teoria e Prática


Robótica Teoria e Prática

Manipulador TRL:R em movimento no espaço


espa o

O próximo exemplo constitui um manipulador do tipo esférico. Será obtido o


equacionamento da cinemática direta, da cinemática inversa e da precisão
cartesiana deste manipulador, com 4 graus de liberdade em configuração
TRL:R movendo-se no espaço. A junta J1 gira o conjunto sob um eixo vertical,
enquanto que J2 e J4 possuem eixos horizontais. Será considerado na
cinemática inversa que o angulo de pitch do punho e conhecido e dado por ,

Manipulador esférico
esf rico TRL:R

De forma semelhante ao problema anterior, deve-se inicialmente desenhar um


esboço do braço em direções perpendicular as do movimento, ou seja, uma
vista superior na qual o movimento da primeira junta e observada e uma vista
frontal do plano vertical, na qual as demais juntas aparecem em perfil. Os
desenhos ficarão a cargo do leitor, que deve, na medida do possível, habituar-
se com a geometria da vista em perspectiva para derivar as expressões da
cinemática. De fato, o movimento vertical deste braço e semelhante ao do
exemplo 3, e portanto a distancia no plano xy entre a origem e a projeção do
órgão terminal neste plano será dada por:

Robótica Teoria e Prática


Robótica Teoria e Prática

Para a cinemática inversa observa-se que as variáveis de junta são

e a , o que indica serem necessárias quatro equações para se


2

ter uma solução. Uma vez que a cinemática direta fornece 3 equações, será

utilizada a condição fornecida do angulo do punho . Com isso


pode-se determinar a distancia da projeção da junta 4 no plano xy, de forma
semelhante aquela realizada no exemplo 3, ou seja:

Comparando agora o movimento deste braço no plano vertical com o exemplo


3, percebe-se que d corresponde a coordenada x do exemplo 3 e que
4

corresponde a coordenada y. A solução de ambos e, portanto, igual,


restando apenas efetuar as devidas substituições nas variáveis. Com isto
resulta

Robótica Teoria e Prática


Robótica Teoria e Prática

Manipulador VVL:R em movimento no espaço Este manipulador, conhecido


como manipulador esférico de Stanford, possui braço formado por juntas em
configuração VVL movendo-se no espaço. Neste exemplo, será adotado um
punho composto por apenas uma junta rotativa, resultando 4 graus de
liberdade ao todo. A junta J1 gira num eixo vertical, enquanto que J2 e J4
possuem eixos horizontais. A junta J3 e prismática. Será considerado
conhecido, na cinemática inversa, o angulo de pitch do punho com relação a
horizontal.

Robótica Teoria e Prática


Robótica Teoria e Prática

Manipulador de Stanford em configuração


configura o VVL:R.

Este problema e bastante semelhante ao anterior, com exceção da primeira


junta, que passa a ser revoluta neste exemplo. O braço possui 4 graus de
liberdade, o que significa que existem infinitas soluções para a cinemática
inversa. O angulo dado introduz a quarta condição que permite escolher
uma das soluções. Este braço tem também um elo (a2) que se desloca
lateralmente com relação a base, o que torna a cinemática um pouco mais
complexa. Este esquema e adotado por certos fabricantes de robôs que
conseguem, com esta técnica, reduzir o espaço ocupado pelo braço alem de
conseguir simplificar o projeto mecânico. As vistas superior e lateral são
mostradas na figura 4.14. Percebe-se que o braço possui dois tipos de
movimento: o primeiro e um movimento em torno de um eixo vertical, realizado
pela junta J1, e o segundo e um movimento num plano vertical, realizado pelas
demais juntas. Os ângulos associados a estes movimentos são indicados em
sua verdadeira grandeza nas duas figuras. A distancia d corresponde ao
comprimento da projeção dos elos a3 e a4 no plano horizontal xy. Da vista lateral
tira-se facilmente que

Robótica Teoria e Prática


Robótica Teoria e Prática

Vistas superiores e laterais do movimento do manipulador de Stanford


Para a cinemática inversa, dados que as coordenadas x, y, z são conhecidas,
alem do angulo de arfagem do pulso, deve-se inicialmente calcular qual
seria a expressão equivalente da projeção d em termos das variáveis
fornecidas. Do triangulo retângulo OSP da vista superior tem-se, já que o
angulo OSP e reto:

Robótica Teoria e Prática


Robótica Teoria e Prática

O problema agora e encontrar os valores dos ângulos de junta, mas percebe-se


que o movimento vertical e semelhante aqueles vistos nos Exemplos 3 e 5.
Deve-se, portanto, calcular as coordenadas da projeção do ponto central da
junta J no plano horizontal. Chamando de d esta distancia, tem-se, da vista
4 4

lateral, que:

Nota-se que tanto d quanto z podem ser calculados, uma vez que se
4 4

consideram dados as coordenadas cartesianas e o angulo . Tem-se então


duas equações:

Robótica Teoria e Prática


Robótica Teoria e Prática

Robótica Teoria e Prática


Robótica Teoria e Prática

Notação de Denavit-Hartenberg
Os parâmetros de Denavit-Hartenberg permitem obter o conjunto de equações
que descreve a cinemática de uma junta com relação a junta seguinte e vice-
versa. São 4 os parâmetros: o angulo de rotação da junta , o angulo de torção
da junta t, o comprimento do elo a e o deslocamento da junta d. Considera-se
uma seqüência de juntas robóticas de revolução como indicado na figura
abaixo. Para obter os parâmetros de Denavit-Hartenberg para a junta Jn, aplica-
se os seguintes procedimentos:

Geometria de juntas rotativas e parâmetros


par metros das juntas.
1) Numerar as juntas, partindo de J1 ate a ultima junta. Numerar os elos
partindo do elo 0. Tem-se com isso a configuração: elo 0, junta 1, elo 1, junta 2,
elo 2, ...
2) Fixar um sistema de coordenadas cartesianas no elo 0 (base), no qual a
posição e orientação dos elos serão obtidos. A fixação deste sistema e explicada
mais adiante neste documento.
3) Definir os eixos das juntas. No caso de juntas rotativas, o eixo de rotação da
junta n será coincidente com o eixo zn−1 do sistema de coordenadas do elo
anterior. No caso de juntas prismáticas, o eixo de deslocamento da junta sera
coincidente com o eixo zn−1 do elo anterior.
4) Obter a normal comum: Hn-On, para todos os elos. A normal comum Hn-On e
definida como sendo a reta perpendicular aos eixos das juntas Jn a J n+1. O

Robótica Teoria e Prática


Robótica Teoria e Prática

comprimento Hn-On e denominado comprimento do elo, an. Se os eixos forem


paralelos, haverá inúmeras normais que satisfazem a condição. Neste caso
adota-se a normal passando pela origem do sistema do elo anterior, ou seja
On−1. Se os eixos das juntas interceptarem-se num único ponto, então a reta Hn-
On degenera-se neste ponto comum, e o comprimento do elo será nulo (an = 0).
5) Definir sistema n (ver explicação adiante). O eixo xn possui a direcao de Hn-
On e passa pelo ponto On (origem do sistema n). O eixo yn define o sistema
destrogiro junto com xn e zn. Se o comprimento do elo an for nulo, então a
direcao de xn sera dada pela reta perpendicular ao plano formado por zn 1 e zn.
6) Obter o deslocamento da junta. A distancia On−11-Hn, medida ao longo do
eixo zn 1, e conhecida como o deslocamento da junta, dn. E positivo se o vetor
que vai de On−11 a Hn tiver a mesma direção do eixo zn−11. Se a junta Jn for
prismatica, entao dn sera a variavel da junta. Se os eixos zn−1 e zn forem
paralelos, então o deslocamento da junta dn sera nulo, uma vez que os eixos
xn−1 e xn interceptam-se no ponto On−1.
7) Obter o angulo de rotação da junta. Troca uma reta paralela a xn passando
pelo ponto On−1. Por definição tanto esta reta quanto o eixo xn−1 sa7) Obter o
angulo de rotação da junta. Troca uma reta paralela a xn passando pelo ponto
On−1. Por definição tanto esta reta quanto o eixo xn−1 são perpendiculares a zn−1.
O ângulo de rotação da junta, n, e medido a partir do eixo xn−1 ate a reta
paralela, no plano perpendicular a zn 1. Se a junta Jn for rotativa, o angulo de
rotação da junta e a própria variável da junta. Se o deslocamento da junta, dn,
for nulo, o angulo de rotação será medido entre xn−1 e xn.
8) Obter o angulo de torção da junta. Troca uma reta paralela ao eixo da junta
Jn, isto e, zn−1, passando por On, origem do sistema n. Por construção, esta reta
estará contida no plano formado por xn e yn. O angulo de torção, tn, e medido a
partir da reta paralela a zn 1 ate o eixo zn. Se os eixos forem paralelos, o angulo
de torção será nulo.
9) Fazer uma tabela contendo os parâmetros n, dn, an e tn, conhecidos como
parâmetros de Denavit-Hartenberg: o perpendiculares a zn 1. O ângulo de
rotação da junta, n, e medido a partir do eixo xn 1 ate a reta paralela, no plano

Robótica Teoria e Prática


Robótica Teoria e Prática

perpendicular a zn 1. Se a junta Jn for rotativa, o angulo de rotação da junta e a


própria variável da junta. Se o deslocamento da junta, dn, for nulo, o angulo de
rotação será medido entre xn 1 e xn.
8) Obter o angulo de torção da junta. Troca uma reta paralela ao eixo da junta
Jn, isto e, zn 1, passando por On, origem do sistema n. Por construção, esta reta
estará contida no plano formado por xn e yn. O angulo de torção, tn, e medido a
partir da reta paralela a zn 1 ate o eixo zn. Se os eixos forem paralelos, o angulo
de torção sera nulo.
9) Fazer uma tabela contendo os parâmetros n, dn, an e tn, conhecidos como
parâmetros de Denavit-Hartenberg:

Se a junta Jn for prismática, então o processo para obter os parâmetros de


Denavit-Hartenberg e bastante semelhante ao da junta rotativa. Deve-se notar,
porem, que o deslocamento de uma junta prismática se da numa direção, e não
existe um "eixo" (como na junta rotativa), no qual será fixado o eixo zn-1. Isto
pode ser melhor visualizado supondo-se que a junta prismática seja formada
não por um mancal de deslizamento linear, mas sim por dois, ainda que
paralelos. Nesta situação, a origem do sistema n−1 fica indeterminada, pois
poderá coincidir com o centro de qualquer um dos mancais. E obvio que ambos
são equivalentes. O mesmo raciocínio aplica-se no caso de haver 3 ou mais
juntas prismáticas paralelas atuando em conjunto. Fica claro, portanto, que a
origem do sistema que será fixado numa junta prismática e arbitrário (sistema
n−1). Esta origem poderá encontrar-se, inclusive, coincidente com a origem da
junta anterior n−1 ou posterior n+1.

Robótica Teoria e Prática


Robótica Teoria e Prática

Geometria de uma junta prismática.


prism tica.

Mostra-se, como no exemplo da figura 5.3, uma junta prismática onde a direção
do eixo da junta foi transferida para o ponto On, onde ocorre a interseção desta
direção com o eixo da junta n+1. Nesta situação o comprimento do elo an torna-
se nulo (na verdade e adicionado a an −1). Nota-se também que a direção de xn
e obtida como sendo perpendicular simultaneamente a direção de
deslocamento da junta prismática (eixo zn 1), e ao eixo da junta Jn+1.

Parâmetros
Par metros de Denavit-
Denavit-Hartenberg em juntas prismáticas.
prism ticas.
A matriz de rotacao entre os sistemas n 1 e n+1 sera dada entao por uma
rotacao do sistema n 1 em torno do eixo zn 1, seguida de uma translacao de dn
na direcao de zn 1, 5.1 - Sistemas de coordenadas da base e do orgao terminal.
O sistema de coordenadas da base e o sistema de coordenadas do orgao
terminal são especiais, uma vez que nao existem restricoes para que o sistema

Robótica Teoria e Prática


Robótica Teoria e Prática

seja unico. Desta forma e necessario adotar-se certas regras na definicao de


ambos. O sistema de coordenadas da base tera seu eixo z0 paralelo ao eixo da
primeira junta. Se esta junta for rotativa, entao o eixo z0 sera coincidente com o
eixo da junta. Se a junta for prismatica, contudo, basta entao que z0 possua a
mesma direcao do deslocamento linear da junta. A origem pode ficar em
qualquer local sobre z0. As direcoes de x0 e y0 podem ser quaisquer. Porem
pode-se simplificar a escolha se os eixos forem adotados como paralelos aos
eixos x1 e y1 quando a variavel da junta 1 for nula. Adota-se a origem do
sistema do órgão terminal em algum ponto situado no próprio órgão. No caso
de uma garra, geralmente adota-se um ponto situado entre os dedos quando
esta encontra-se fechada. Ferramentas especiais, como solda-a-ponto, por
exemplo, tem sua origem fixada no ponto de trabalho da ferramenta. O eixo xn
e orientado de tal forma que intercepta o eixo zn−1 da ultima junta em angulo
reto. A direção de zn pode ser qualquer, mas em geral escolhe-se zn tal que o
angulo de torção tn seja nulo.

Matriz de transformação n−1 e n.


transforma o entre os sistemas n−

Dado um vetor no sistema n, ele pode ser expresso no sistema n−1 por meio
da matriz que relaciona ambos os sistemas.

Robótica Teoria e Prática


Robótica Teoria e Prática

As matrizes de transformação indicadas são todas geométricas. A matriz


inversa, que permite expressar um vetor no sistema n dado o mesmo vetor no
sistema n−1 fica então:

Exemplo
Exemplo de aplicação
aplica o num manipulador VVR:VR.
Este exemplo mostra a obtenção dos parâmetros de Denavit-Hartenberg no
manipulador. Admite-se conhecidos os comprimentos de todos os elos.. Deve-
se relacionar os sistemas de coordenadas de cada junta e preencher a tabela
de parâmetros.
Manipulador robótico
rob tico esquemático
esquem tico para obtenção
obten o dos parâmetros
par metros de Denavit-
Denavit-
Hartenberg.

O diagrama mostra os eixos das juntas obtidos pela aplicação da notação de


Denavit-Hartemberg no braço mecânico fornecido. A tabela e preenchida com
base no diagrama completo.

Robótica Teoria e Prática


Robótica Teoria e Prática

Sistemas de coordenadas intermediários


intermedi rios e parâmetros
par metros de Denavit-
Denavit-Hartenberg
do manipulador VVR:VR.

Tabela de parâmetros
par metros de Denavit-
Denavit-Hartemberg

Trigonometria
Semelhança
Semelhan a de triângulos
tri ngulos
Dois triângulos são semelhantes quando possuem dois ângulos iguais. Como a
soma dos ângulos internos de um triangulo e sempre igual a 180o, então todos
os ângulos de triângulos semelhantes são iguais.

Robótica Teoria e Prática


Robótica Teoria e Prática

Teorema de Pitágoras
Pit goras

Num triangulo retângulo OPQ, no qual o angulo do vértice Q e reto (igual a 90


o

ou /2) e o angulo do vértice o cateto oposto e definido como o


comprimento b da aresta PQ, o cateto adjacente e definido como o
comprimento a da aresta OQ, e a hipotenusa e o comprimento c da maior
aresta, OP. O teorema de Pitágoras fornece que o quadrado da hipotenusa e
igual a soma dos quadrados dos catetos, ou seja

Seno, co-
co-seno e tangente

Robótica Teoria e Prática


Robótica Teoria e Prática

Numa circunferência de raio unitário desenhamos um sistema de eixos


passando pelo centro da circunferência e um arco de circulo de angulo
definido pelo ponto P. A projeção deste ponto nos eixos das abscissas e
das ordenadas define os pontos Q e R, respectivamente.

Circulo de raio unitário:


unit rio: seno, co-
co-seno, tangente, co-
co-tangente, secante e co-
co-
secante.
O seno deste angulo e definido como o comprimento do cateto oposto ao
triangulo OPQ, ou seja, ao comprimento RO ou PQ. Da mesma forma, o co-
seno e o comprimento do cateto adjacente ao angulo , cujo comprimento e
RP ou OQ. A tangente e medida ao longo da reta paralela ao eixo das
ordenadas que tangencia a circunferência no ponto T em que esta encontra o
eixo das abscissas, ate o ponto U em que esta encontra o prolongamento de
OP. Analogamente, a co-tangente do angulo e o comprimento medido ao
longo da reta paralela ao eixo das abscissas que passa pelo ponto S, encontro
da circunferência com o eixo das ordenadas, ate o ponto V em que esta reta
encontra o prolongamento de OP. Tem-se, finalmente, a secante sendo dada
pelo comprimento OU e a co-secante por OV.
Resumidamente,

Robótica Teoria e Prática


Robótica Teoria e Prática

Complementos de ângulos
ngulos
Supondo conhecidos o seno e o co-seno do angulo , deseja-se saber o valor
do seno e co-seno do angulo complementar 180 o . Conforme
indica a figura abaixo, estes podem ser obtidos da semelhança entre os
triângulos OAC e OBD:

Robótica Teoria e Prática


Robótica Teoria e Prática

Ângulos
ngulos complementares.
Da mesma figura pode-se ainda verificar que, da semelhança entre os
triângulos OAC e OEA,

Robótica Teoria e Prática


Robótica Teoria e Prática

Angulos reciprocos.
Figuras semelhantes a essas podem ser desenhadas para se obter as
igualdades:

Robótica Teoria e Prática


Robótica Teoria e Prática

Pode-se exprimir as funções trigonométricas do seno, co-seno e tangente em


termos delas próprias. Do teorema de Pitágoras, por exemplo, tira-se que

A tangente pode ser obtida de

Em todas as expressões acima o quadrante do angulo deve ser determinado


para se verificar se a solução correta e a positiva ou negativa.

diferen a de ângulos
Soma e diferença ngulos
Em geometria e comum a necessidade de se conhecer o seno ou o co-seno da
soma de dois ângulos. Pode-se relacionar o seno (ou o co-seno) da soma com

Robótica Teoria e Prática


Robótica Teoria e Prática

os senos e co-senos dos ângulos individuais.

Embora seja também possível obter uma solução geométrica para a tangente
da soma, e mais fácil neste ponto calcular pela relação entre o seno e o co-
seno, ou seja:

Robótica Teoria e Prática


Robótica Teoria e Prática

Lei dos senos

Lei dos co-


co-senos
Num triangulo qualquer ABC, traca-se uma a reta que, a partir do vértice A,
encontra o lado BC em angulo reto (perpendicular a BC). No triangulo retângulo
ABH, aplica-se o teorema de Pitágoras, obtendo-se.

Lei dos co-


co-senos.

Robótica Teoria e Prática


Robótica Teoria e Prática

Transformações
Transforma es de Coordenadas
Coordenadas
Em diversos problemas físicos e mecânicos existe a necessidade de se
expressar determinada grandeza vetorial em um ou mais sistemas de
coordenadas distintos. Em geral um destes sistemas encontra-se parado
enquanto o outro e o sistema móvel. Por exemplo, a posição de um guindaste
num navio pode ser conhecida com relação a um sistema de eixos fixados a
embarcação, ou, similarmente, ser conhecida com relação a um sistema de
coordenadas fixadas ao ancoradouro. Navios, aeronaves, foguetes, satélites,
veículos em geral, alem de uma grande serie de fenômenos apresentam o
mesmo tipo de problema. Vamos apresentar uma forma de sistematizar estas
transformações de coordenadas.

Rotações
Rota es de coordenadas

Considere um sistema de eixos cartesianos fixos O, de eixos x, y, z, conforme


ilustra a figura B-1. Supomos que haja um corpo que se gira com relação a este
sistema, no qual um outro sistema Q de eixos u, v, w esteja rigidamente fixado,
e tal que suas origens sejam coincidentes, mas que seus eixos possuam

Robótica Teoria e Prática


Robótica Teoria e Prática

direções distintas. As direções dos eixos u, v e w podem ser postas na forma


vetorial com versões unitários, isto e, de modulo unitário, com relação ao
sistema fixo (x, y, z). Supondo que tais direções sejam, respectivamente u, v e
w, tal que u = (u , u , u ), v = (v , v , v ) e w = (w , w , w ), sabe-se, do calculo
x y z x y z x y z

vetorial, que u , v , e w são os co-senos diretores das direções u, v e w,


i i i

respectivamente (para i = x, y ou z), ou seja, c e igual ao co-seno do angulo


i

entre os eixos c e i.

Sistemas de coordenadas cartesianas fixas (x, y, z) e moveis (u, v, w)


Se, agora, montarmos a matriz quadrada A de ordem 3 dada por:

teremos uma forma de relacionar a orientação de um vetor qualquer dado num


sistema com a orientação deste mesmo vetor expresso no outro sistema. De
fato, se r = (r , r , r ) for o vetor expresso no sistema O, as coordenadas deste
o x y z

mesmo vetor no sistema Q, r = (r , r , r ) serão dadas por:


q u v w

Robótica Teoria e Prática


Robótica Teoria e Prática

onde o operador (⊕) indica o produto interno ou produto escalar. A matriz A e


conhecida como matriz de transformação de coordenadas entre os dois
sistemas, e pode-se mostrar que ela possui características especiais. Ela e
uma matriz ortogonal própria, isto e, seu determinante e unitário, e o produto
escalar entre duas de suas linhas ou coluna e sempre nulo. Alem disso, nas
matrizes ortogonais próprias o produto da matriz pela sua transposta resulta na
matriz identidade, ou seja:

no qual o sobre-escrito T indica a transposição da matriz e I e uma matriz


identidade de ordem 3. Da relação acima decorre imediatamente que a inversa
de uma matriz ortogonal e igual a sua própria transposta, ou seja:

Este resultado nos permite obter a representação inversa entre os dois


sistemas de coordenadas, isto e, calcular as componentes do vetor r caso o

sejam conhecidas as coordenadas do vetor r . De fato, ao multiplicar ambos os


q

termos da relação de transformação pela inversa da matriz A chega-se


facilmente a

Conclui-se, também, que as direções dos eixos (x, y, z), quando representadas
nos sistema Q serão dadas respectivamente por x = (u , v , w ), y = (u , v , w ),
x x x y y y

e z = (u , v , w ). Como regra geral tem-se, portanto, a relação:


z z z

Robótica Teoria e Prática


Robótica Teoria e Prática

Rotações ao redor dos eixos cartesianos Em algumas aplicações, percebe-se


que a relação que une os dois sistemas de coordenadas O e Q e uma mera
rotação ao redor de um dos eixos cartesianos do sistema O, isto e, ao redor do
eixo x, y ou z, como mostra a figura A-2. Neste caso, como ambos os sistemas
compartilham a origem num mesmo ponto, pode-se calcular os co-senos
diretores dos eixos transformados caso o angulo de rotação seja conhecido.
Ha 3 possibilidades, já que existem 3 eixos cartesianos. A rotação pode ser
efetuada ao redor do eixo x, y ou z. O matemático Euler mostrou que qualquer
que seja a orientação do sistema de coordenadas Q com relação ao sistema O,
pode-se decompor esta transformações em 3 rotações efetuadas nos eixos
cartesianos, desde que não haja duas rotações sucessivas efetuadas ao longo
do mesmo eixo. São validas, por exemplo, rotações x-y-z, y-z-x, y-x-z, etc., mas
também são igualmente validas rotações na forma x-y-x, z-x-z, y-z-y. De fato,
existem 12 possibilidades distintas para tais transformações.

- Rotação
Rota o no sistema de coordenadas Q de um angulo ao redor do eixo x.
Uma rotação
rota o de um angulo ao redor do eixo cartesiano
cartesiano x ira levar a seguinte
matriz de rotação:
rota o:

Robótica Teoria e Prática


Robótica Teoria e Prática

transformações são direcionais com relação ao angulo, isto e, considera-se o


angulo como sendo positivo quando, ao passar do sistema O para o sistema Q,
utiliza-se a regra da Mao direita. Neste caso, com o polegar direito apontando
na direção positiva do eixo de rotação, os demais dedos devem indicar o
sentido de rotação.
Caso os dedos apontem na direção oposta, então o angulo de rotação será
negativo.
Como a transformação inversa, ou seja, do sistema Q para o sistema O pode
ser realizada pela rotação de um angulo negativo ao redor do mesmo eixo,
conclui-se que

Translações
Transla es de coordenadas
Muitas vezes os eixos coordenados não possuem origens coincidentes. Nestes
casos, para obter a posição de um dado vetor ou objeto num dos sistemas será
necessário efetuar, alem da transformação de orientação entre os sistemas,
também uma translação. Considere então o sistema Q com sua origem

Robótica Teoria e Prática


Robótica Teoria e Prática

deslocada do sistema O, mas admite-se inicialmente que os eixos de ambos


sejam paralelos.

Translação
Transla o entre sistemas de eixos coordenados.
Nesta situação, se a posição de um ponto P do espaço for dada pelo vetor r , e
o

se s for a posição da origem do sistema Q, ambos referidos ao sistema O,


o

então a posição deste ponto P no sistema Q será dada pela soma vetorial:

Nota-se que o vetor s e, na verdade, a posicao da origem do sistema O


o

referido ao sistema Q, ou seja, e igual a s . Para obter a inversa desta relacao


q

basta isolar o vetor r :


o

Transformações
Transforma es compostas
Num caso mais geral, os eixos dos sistemas O e Q não são paralelos, e nem
suas origens são coincidentes. Para analisar este caso, pode-se supor que
exista um sistema de eixos intermediário, cujos eixos são paralelos ao do
sistema O, porem sua origem e coincidente com o sistema Q. Percebe-se
então que a transformação entre os dois sistemas reduz-se entre uma
translação de O para o sistema intermediário, seguido de uma rotação entre
este ultimo e o sistema Q.

Robótica Teoria e Prática


Robótica Teoria e Prática

Transformação
Transforma o composta de rotação
rota o e translação
transla o
Sabe-se que a transformação que relaciona um vetor no sistema intermediário I
com seu correspondente no sistema Q e dada por:

onde A O-Q e a matriz de transformação entre os sistemas I e Q. Uma vez que o


sistema I e paralelo a O, então a matriz A e também igual a transformação entre
os sistemas Q e O. Por outro lado, a translação de coordenadas entre os
sistemas I e O leva a:

pois as origens de I e Q são coincidentes. Substituindo-se esta ultima na


expressão anterior, tem-se que:

Porem, como foi dito, o vetor e a posição da origem do sistema O referido


ao sistema I, ou seja, s . Mas A
i O-Q s e justamente a transformação deste vetor
i

para o sistema Q, ou simplesmente s . Tem-se com isto a relação:


q

que relaciona um vetor expresso no sistema O com as componentes deste


vetor no sistema Q, desde que sejam conhecidas a matriz de transformação
entre ambos, e a posição da origem de O referida ao sistema Q.

Robótica Teoria e Prática


Robótica Teoria e Prática

Transformações
Transforma es homogêneas
homog neas

Vimos que as transformações podem ser entendidas como sendo compostas


de rotações e translações. Quando apenas dois sistemas estão envolvidos no
processo de transformação, não ha problemas na utilização da formulação
apresentada anteriormente. Porem, se houver mais de dois sistemas, a
composição de transformações torna-se complexa e de difícil compreensão.
Sejam, por exemplo, os sistemas O, Q e R, tal que se conheçam as
transformações entre O e Q e entre Q e R:

o que significa que o numero de termos que aparece na transformação


depende do numero de sistemas de coordenadas envolvidos nela. Ha uma
forma mais eficiente de expressar tais transformações, conhecida como
transformações homogêneas. Nela, tanto as rotações quanto as translações sao
efetuadas por multiplicações de matrizes, o que permite facilmente compor
transformações entre diversos sistemas. O preço a pagar por isto e o aumento
na dimensão do problema, que passa para 4 dimensões para que a translação
possa ser posta na forma matricial. Uma matriz homogênea e, portanto, uma
matriz quadrada de ordem 4, formada pelo acréscimo de uma coluna e uma
linha adicionais a matriz de transformação de coordenadas usual. No caso de
uma rotação, a matriz homogênea e dada por:

Robótica Teoria e Prática


Robótica Teoria e Prática

na qual o vetor que fornece a origem do sistema Q e dado por s = (s , s , s ).


o x y z

Os vetores a serem transformados devem agora ter sua dimensão aumentada,


e para isto introduz-se um quarto componente que representa um fator de
escala, mas que aqui será adotado como sendo sempre unitário. Tem-se assim
que:

Analogamente, as rotações efetuadas ao redor dos eixos cartesianos


encontram também suas correspondentes nas transformações homogêneas,
dadas por:

Robótica Teoria e Prática


Robótica Teoria e Prática

Relações
Rela es inversas

Robótica Teoria e Prática


Robótica Teoria e Prática

Robótica Teoria e Prática


Robótica Teoria e Prática

Robótica Teoria e Prática


Robótica Teoria e Prática

Anexo 1

INTRODUÇÃO A LINGUAGEM C
ESTRUTURA BÁSICA DE UM PROGRAMA C

Os programas em C sempre iniciam pelo main() . De forma geral os programas


em C consistem de funções (o termo função será explicado depois), e o main()
consiste de uma função. Seguindo o nome da função seguem as chaves {} que
delimitam o início e o fim da função. Neste exemplo o printf() é o único
comando da função main(). Este comando imprime mensagens na tela padrão
e como será visto mais tarde, também imprime o conteúdo de variáveis.
Observe que após todo comando dentro de uma função segue um ponto e
vírgula ( ; ). Os caracteres em branco são invisíveis para o compilador.

Exemplo:
#include <stdio.h>
Robótica Teoria e Prática
Robótica Teoria e Prática

main ()
{
printf ( " Programa Inicial " );
}

Variáveis
Uma variável é um espaço reservado na memória do computador para armazenar certos
tipos de dados.

#include <stdio.h>
main ()
{
int num;
num = 2;
printf("Numero = %d",num);

A primeira linha do main() declara a variável e o tipo:

Int num;
Tipo da variável Nome da variável

Declarando uma variável você informa ao compilador o nome e o tipo da variável.


Como regra geral, todas as variáveis em C devem ser declaradas nas primeiras linhas da
função. O nome da variável deve iniciar com uma letra.

A segunda linha atribui o valor 2 para a variável num:

num = 2;

Existem sete tipos principais de variáveis:

char ---------------------------------- Capaz de conter um caractere (-128 a 127)


short --------------------------------- Inteiro com capacidade reduzida (0 a 15384)
int --------------------------------- Inteiro (–32768 a 32767)
long int ------------------------ Inteiro estendido (-2 147 483 648 a 2 147 483 647)
float -------------------------- Ponto flutuante em precisão simples (10e−38 a 10e38)
double ---------------------- Ponto flutuante em precisão dupla (10e−308 a 10e308)
Unsigned char
Unsigned int
Unsigned long
Unsigned ----------- Retira o sinal e, portanto troca a variação de valores, por
Exemplo: unsigned int varia de 0 a 65 535

A função printf()

Robótica Teoria e Prática


Robótica Teoria e Prática

O printf() é de fato uma função assim como o main(). Os parênteses contêm a sentença
a ser apresentada na tela. Esta sentença deve ser limitada por aspas (“ “), e o conteúdo
de variáveis também podem ser exibidas pelo printf conforme o exemplo abaixo:

#include <stdio.h>
main()
{
int a = 1;
char tipo = ‘c’;
float valor = 22.53;
printf("inteiro= %d char= %c float= %f \n",a,tipo,valor);
}

O resultado da execução deste programa será:

Inteiro= 1 char= c float= 22.530001

O símbolo % dentro de uma sentença do printf indica que desejamos imprimir o


conteúdo de alguma variável.
Abaixo uma descrição dos principais tipos que o printf reconhece:

%c ---------- Caracter
%s ---------- String
%d ---------- Inteiro
%f ---------- Float (notação decimal)
%e ---------- Float (notação exponencial)
%g ---------- Float
%u ---------- Inteiro sem sinal
%x ---------- Hexadecimal inteiro
%o ---------- Octal inteiro
%ld ------------------- Long
%lu ------------------- Long
%lx ------------------- Long
%lo ------------------- Long

Ainda no último exemplo, observe que o ultimo caracter do printf era “\n”. Este caracter
de controle indica que queremos inserir uma nova linha. Existem outros caracteres de
controle, e todos iniciam com um \ “, conforme a tabela abaixo:
\n ---------- Nova linha
\t ----------- Tabulação
\b ---------- Backspace
\’ ---------- Aspas simples
\” ---------- Dupla aspas
\\ ----------- Barra

No exemplo abaixo ilustraremos alguns resultados obtidos com o comando printf (Os
retângulos abaixo de cada comando printf ilustra o resultado obtido na tela do
computador):

#include <stdio.h>
Robótica Teoria e Prática
Robótica Teoria e Prática

main()
{
int i = 52;
float x = 28.534;
printf("i = %2d\n",i);
i = 52
printf("i = %4d\n",i);
i = 52
printf("x = %8.3f\n",x);
x=28.534
printf("x = %-8.3f\n",x);
x = 28.53 4
}

A função scanf()
Esta função é responsável pela entrada de dados via teclado. Existem várias funções de
entrada e saída em C, porém o printf e o scanf são as mais comuns. Examine o exemplo
abaixo:

#include <stdio.h>
main()
{
int i,j;
float x,y;
double a,b;
scanf("%d",&i);
scanf("%f",&x);
scanf("%lf",&a);
j = i % 2;
y = x * 2;
b = a / 2;
printf("i= %3d j= %3d \n",i,j);
printf("x= %.3f y= %.3f \n",x,y);
printf("a= %g b= %g \n",a,b);
}

O comando scanf interrompe a execução do programa e aguarda o usuário entrar com


um valor para a variável x. Existem dois campos a serem informados neste comando:

scanf( "%f" ,&x);


Tipo da variável Endereço da variável (você deve colocar um “&” na frente da variável

Para o tipo double o prefixo do scanf deve ser lf.

Operadores
Os operadores aritméticos sobre as variáveis são os seguintes:
Robótica Teoria e Prática
Robótica Teoria e Prática

+ --------- Soma
- --------- Subtração
* -------- Multiplicação
/ --------- Divisão
% ------- Resto da divisão
A operação de incremento de uma unidade tem também um formato reduzido, ou seja, o
comando:
i = i + 1;
é freqüentemente representado por:
i++;
Da mesma forma i = i-1; pode ser escrito como i--;

Como exemplo dos operadores, o programa abaixo calcula as raízes reais de um


polinômio de segundo grau:

#include <stdio.h>
#include <math.h>
main()
{
float a,b,c;
float x1,x2;
printf("Entre a,b,c:");
scanf("%f %f %f",&a,&b,&c);
x1=(-b+sqrt(b*b-4*a*c))/(2*a);
x2=(-b-sqrt(b*b-4*a*c))/(2*a);
printf("\n x1 = %f x2 = %f\n",x1,x2);
}

Comentários
É possível introduzir comentários dentro de um programa C, bastando para isso colocá-
los no seguinte formato:

/* Comentario */

/* * * * * * * * * * * * * * * * * * * * * * * * */

Observe o exemplo abaixo:

/* Soluções reais da equação ax*x + b*x + c = 0 */


#include <stdio.h>
Robótica Teoria e Prática
Robótica Teoria e Prática

#include <math.h>
main()
{
/* Definicao das variaveis */
float a,b,c; /* Coeficientes do polinomio */
float x1,x2; /* Solucoes desejadas */
/* Entrada de Dados */
printf("Entre a,b,c:");
scanf("%f %f %f",&a,&b,&c);
/* Calculo das raizes */
x1=(-b+sqrt(b*b-4*a*c))/(2*a);
x2=(-b-sqrt(b*b-4*a*c))/(2*a);
/* Impressao dos dados finais */
printf("\n x1 = %f x2 = %f\n",x1,x2);
}

LAÇOS (LOOPS)
Existem três formatos básicos de laços:

1 – do {} while();
2 - while() {}
3 - for( ; ;) { }

Comando for( ; ; ) {}
O for é um comando apropriado quando queremos executar um conjunto de operações
um número fixo de vezes. O exemplo abaixo imprime os números de 0 até 9:

#include <stdio.h>
main()
{
int n;
10
for(n=0; n<10; n++) {
printf("n = %d\n",n);
}
}
O resultado será:
n=0
n=1
n=2
n=3
n=4
n=5
n=6
n=7
n=8
n=9

O comando for é composto de três argumentos:


for( n=0 ; n<10 ; n++ )
Robótica Teoria e Prática
Robótica Teoria e Prática

Expressão de inicialização Expressão de teste Incremento

Expressão de inicialização
Inicializa a variável do laço. A inicialização é feita uma única vez quando o laço inicia.

Expressão de teste
Esta expressão testa (a cada vez que o conjunto de comandos no interior do for finaliza),
se o laço deve ser encerrado. Enquanto a expressão for verdadeira o laço é repetido.
Para realizar teste utilizamos os operadores relacionais. Os principais operadores são:

< Menor
> Maior
<= Menor ou igual
>= Maior ou igual
== Igual
!= Diferente

&& e
! negação
|| ou

Expressão de incremento
A cada repetição do laço, o terceiro argumento (n++) incrementa a variável n.

Exemplo: Métodos numéricos de integração (ponto a esquerda)


Como aplicação do comando for o exemplo abaixo ilustra a implementação do método
do ponto a esquerda para avaliar numericamente:

/* * * * * * * * * * * * * * * * * * * * */
/* Integracao Numerica: Ponto a Esquerda */
/* * * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
main()
{
int i;
int n;
float w;
float dx ;
float a,b ;
float soma;
printf("\nEntre o extremo inferior do intervalo: ");
scanf("%f",&a);
printf("\nEntre o extremo superior do intervalo: ");
scanf("%f",&b);

Robótica Teoria e Prática


Robótica Teoria e Prática

printf("\nEntre com o numero de particoes: ");


scanf("%d",&n);
soma = 0.0;
dx = (b-a)/n;
for(i=0; i< n; i++) {
w = a + i * dx;
soma += (w * w) * dx;
printf("\nSoma parcial = %f ",soma);
}
printf("\nIntegral = %15.9f ",soma);
}

Comando do {} while();
Este segundo tipo de laço é adequado para situações onde não sabemos ao certo quantas
vezes o laço deve ser repetido. O exemplo abaixo ilustra a utilização do comando:

#include <stdio.h>
main()
{
int n;
n = 0;
do {
printf("n = %d\n",n);
n++;
} while (n < 10);
}

No exemplo acima o programa entra dentro do laço faz o primeiro printf, incrementa n
de uma unidade e só então verifica a condição while (n < 10). Caso a condição seja
verdadeira, a execução do programa retorna a primeira linha do laço (printf("n =
%d\n",n);) e prossegue até que a condição seja falsa. O programa sempre entra
executando os comando no interior do laço, para somente no final realizar o teste.

Exemplo: Método de Newton

O programa abaixo determina as raízes da função: utilizando o método de


Newton, ou seja, dada uma condição inicial x0, e um erro máximo E, a seqüência
abaixo pode convergir para uma das raízes:

/* Metodo de Newton */
#include <stdio.h>
Robótica Teoria e Prática
Robótica Teoria e Prática

#include <math.h>
main()
{
int i ;
double xn, x0,xn_1;
double erro ;
printf(" Entre com a condicao inicial: ");
scanf("%lf",&x0);
printf("\n Erro maximo: ");
scanf("%lf",&erro);
xn = x0;
i = 0;
do {
xn_1 = xn;
xn = xn_1 - (xn_1 * xn_1 - 2) / (2 * xn_1);
i++;
printf("\nx[%2d] = %20.17f",i,xn);
} while (fabs(xn - xn_1) > erro);
printf ("\n A raiz obtida foi: %20.17f\n",xn);
}

Comando while() {};


Este último tipo de laço é muito semelhante ao anterior. Partindo do exemplo abaixo
vamos observar a única diferença para o laço da seção anterior:

#include <stdio.h>
main()
{
int n;
n = 0;
while (n < 10){
printf("n = %d\n",n);
n++;
}
}

Neste exemplo, primeiro é feito o teste (while (n < 10)) e somente em caso verdadeiro
os comandos dentro do while são executados. Assim se a condição for falsa a primeira
vez, em nenhum momento os comandos dentro do laço serão executados. Já no do{}
while(); pelo menos a primeira vez os comandos dentro do laço serão executados.

Comando break e continue


Para auxiliar nos laços contamos com dois comandos de interrupção do laço, cada um
com objetivos diferentes. O comando break; interrompe o laço (Qualquer dos três
formatos apresentados) e o programa continua no primeiro comando após o laço.
Exemplo:

#include <stdio.h>
main()
Robótica Teoria e Prática
Robótica Teoria e Prática

{
int n;
n = 0;
while (n < 10){
printf("n = %d\n",n);
if (n > 3)
break;
n++;
}
printf (“Fim do programa \n”);
}

O resultado deste programa será:

n=0
n=1
n=2
n=3
n=4
Fim do programa

O comando continue; transfere a execução do programa para o teste do laço, que pode
ou não prosseguir conforme a condição seja verdadeira ou falsa.

DECISÕES
Comando if () {}

O comando principal de decisão é o if(). Através deste comando o fluxo do programa


pode ser desviado para executar ou não um conjunto de comandos. Considere o
exemplo abaixo:

/* * * * * * * * * * * * * * * * * * */
/* Testa se um numero e par ou impar */
/* * * * * * * * * * * * * * * * * * */
#include <stdio.h>
main()
{
int i,n;
printf("Entre com n = ");
scanf("%d", &n);
i = n % 2;
if (i == 0) {
printf("\n n e um numero par\n");
}
else {
printf("\n n e um numero impar\n");
}
}
Neste exemplo a variável i armazena o resto da divisão de n por 2. Caso seja zero, então
o programa passa a execução do comando printf("\n n e um numero par\n"). Se a
Robótica Teoria e Prática
Robótica Teoria e Prática

condição falha, o comando else indica que o programa deve executar o comando
printf("\n n e um numero impar\n"). Observe que o else é um comando opcional. Caso
você não o inclua, o programa segue para o próximo comando após o if.

Exemplo: Método da Bis seção

O programa abaixo determina as raízes da função: utilizando o método da


bisseção. No método da bisseção procuramos uma raiz contida em certo intervalo [a,b]
dado. A raiz existe desde que a função seja contínua e o sinal da função troque de um
extremo para outro (ou seja f(a) * f(b) < 0).

/* * * * * * * * * * * * * * * * * * */
/* Metodo da Bissecao */
/* * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
main()
{
float a,b,c;
float erro;
float fa,fb,fc;
printf("\nEntre com a = ");
scanf("%f",&a);
printf("\nEntre com b = ");
scanf("%f",&b);
printf("\nEntre com o erro = ");
scanf("%f",&erro);
fa = a*a - 2;
fb = b*b - 2;
if ((fa * fb) > 0) {
printf("\nCondicao inicial nao contem raiz !\n");
exit(0);
}
while(fabs(a-b) > erro) {
c = (a+b)/2.0;
fc = c*c - 2.0;
if (fa * fc < 0) {
b = c;
}
else {
if (fb * fc < 0)
a = c;
else
break;
}
printf("\n Raiz parcial = %f ",c);
}
printf("\n\n Raiz obtida = %f \n",c);
Robótica Teoria e Prática
Robótica Teoria e Prática

FUNÇÕES
Introdução
As funções cumprem como primeiro papel, evitar repetições desnecessárias de código.
No exemplo anterior precisamos calcular o valor y=x*x-2 em diversas partes do
programa. Se desejássemos trocar a função, seria necessário alterar várias partes do
código. Para evitar isso, utilizaremos uma função como no exemplo abaixo:

/* * * * * * * * * * * * * * * * * * * */
/* Metodo da Bisssecao */
/* * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
float f(float x)
{
return(x*x-2);
}
void main()
{
int i = 0;
float a,b,c;
float erro;
float fa,fb,fc;
printf("Entre com os extremos do intervalo [a, b]: ");
scanf("%f,%f",&a,&b);
printf("\nErro: ");
scanf("%f",&erro);
fa = f(a);
fb = f(b);
if ((fa * fb) > 0) {
printf("Condicao inicial nao contem raiz !\n");
exit(0);
}
while(fabs(a-b) > erro) {
i++;
c = (a+b)/2.0;
fc = f(c) ;
if (fa * fc < 0)
b = c;
else
if (fb * fc < 0)
a = c;
else
break;
printf("Raiz parcial no passo %d = %f \n",i,c);
}
printf("\n Raiz obtida = %f \n",c);
Robótica Teoria e Prática
Robótica Teoria e Prática

Vamos examinar alguns detalhes da função introduzida:

float f (float x)
Define o tipo Nome da Função Argumentos retornado pela função de entrada

{
float y;
y = x * x - 2;
return(y); /*Valor a ser retornado*/
}
Uma observação importante é que as variáveis dentro da função não são conhecidas fora
da função e vice versa.

Exemplo: Métodos de Integração Numérica (Ponto a esquerda, Trapézio e


Simpson)

Para ilustrar o conceito de funções, o exemplo seguinte calcula a integral numérica de


uma função definida na função float f(float x) .

/* * * * * * * * * * * * * * * * * * */
/* Metodos de Integracao Numerica */
/* * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <conio.h>
float f(float x)
{
float y;
y = 1/(1+x*x);
return(y);
}
float Integra_Ponto_a_esquerda(float a,float b,int n)
{
int i ;
float soma ;
float dx ;
soma = 0.0;
dx = (b-a)/n;
for(i=1; i<= n; i++) {
soma = soma + f(a + (i-1)*dx) * dx;
printf("\nSoma parcial = %f ",soma);
}
return(soma);
}
float Integral_Trapezio(float a,float b,int n)
{
int i ;
Robótica Teoria e Prática
Robótica Teoria e Prática

float soma ;
float dx ;
dx = (b-a)/n;
soma = f(a);
for(i=1; i < n; i++) {
soma = soma + 2*f(a + i*dx);
printf("\nSoma parcial = %f ",soma);
18
}
soma = dx/2 * (soma + f(b));
return(soma);
}
float Integral_Simpson(float a,float b,int n)
{
int i ;
float soma ;
float dx ;
dx = (b-a)/n;
soma = f(a);
for(i=1; i < n; i++) {
if ((i%2) == 1)
soma = soma + 4*f(a + i*dx);
else
soma = soma + 2*f(a + i*dx);
printf("\nSoma parcial = %f ",soma);
}
soma = dx/3 * (soma + f(b));
return(soma);
}
main()
{
int i;
int n;
char c;
float a,b ;
float soma;
do {
printf("Selecione um do metodos de integracao \n");
printf("1- Ponto a esquerda \n");
printf("2- Trapezio \n");
printf("3- Simpson \n");
printf("Opcao: ");
scanf("%d",&i);
printf("\nEntre o extremo inferior do intervalo: ");
scanf("%f",&a);
printf("\nEntre o extremo superior do intervalo: ");
scanf("%f",&b);
printf("\nEntre com o numero de particoes: ");
scanf("%d",&n);
switch(i)
Robótica Teoria e Prática
Robótica Teoria e Prática

{
case 1:
soma = Integra_Ponto_a_esquerda(a,b,n);
break;
case 2:
soma = Integral_Trapezio(a,b,n);
break;
case 3:
soma = Integral_Simpson(a,b,n);
break;
}
printf("\nIntegral = %15.9f ",soma);
printf("\n Continua (s/n) ");
c = getche();
} while((c != 'n') && (c != 'N'));

VETORES E MATRIZES

Vetores
Quando você deseja representar uma coleção de dados semelhantes, pode ser muito
inconveniente utilizar um nome de variável diferente para cada dado. Para ilustrar
vamos considerar o seguinte exemplo: Montar um programa que armazena as notas de
15 alunos e calcula a média obtida pela turma. As notas serão armazenadas em uma
variável do tipo float, porém ao invés de criarmos 15 variáveis, utilizamos uma variável
do tipo vetor, definida como abaixo:

float notas[15];

o programa completo seria:

#include <stdio.h>
main()
{
int i ;
float media ;
float soma ;
float notas[15];
for(i=0;i < 15;i++) {
printf("\n Aluno %2d ",i+1);
scanf("%f",&notas[i]);
}
for(i=0;i<15;i++)
soma = soma + notas[i];
media = soma / 15;
printf("\n A media final foi: %f",media);
}

Declaração

Robótica Teoria e Prática


Robótica Teoria e Prática

Um vetor é uma coleção de variáveis de certo tipo, alocadas seqüencialmente na


memória. Para o compilador C um declaração de variável vetor do tipo: int n[5]; reserva
o espaço de 5 variáveis do tipo inteira, onde cada variável pode ser referenciada
conforme abaixo:

n[0] n[1] n[2] n[3] n[4]

IMPORTANTE: Observe que a declaração anterior cria cinco variáveis, porém o


primeiro elemento é n[0]. A declaração de vetor inicia com o índice 0 e finaliza no
índice 4. Se você quer atribui um valor a um dos componentes do vetor basta referencia-
lo por exemplo:

n[3] = 29;

29
n[0] n[1] n[2] n[3] n[4]

Inicializando vetores

Assim como é possível inicializar uma variável simples na mesma linha da declaração,
o mesmo pode ser feito para vetores. Observe o exemplo abaixo:

int n[5] = {23, 3, -7, 288, 14};

Exemplo: Método de Ordenação


Como exemplo vamos apresentar um programa que ordena um seqüência de 10
números reais.

/* * * * * * * * * * * * * * * * * * * * * */
/* Metodo da Bolha (ordenacao de um vetor) */
/* * * * * * * * * * * * * * * * * * * * * */
#define MAX 10
#include <stdio.h>
main()
{
int i ;
int flag;
float swap;
float n[MAX];
/* Entrada de Dados */
printf("Entre com os numeros para ordenacao \n");
for(i=0;i<MAX;i++)
{
printf("\n numero %2d: ",i);
scanf("%f",&(n[i]));
}
/* Ordena a sequencia de numeros */
flag = 1;
while(flag == 1) {
Robótica Teoria e Prática
Robótica Teoria e Prática

flag = 0;
for(i=0;i<(MAX-1);i++)
{
if (n[i] > n[i+1])
{
swap = n[i] ;
n[i] = n[i+1];
n[i+1] = swap ;
flag = 1 ;
}
}
}
/* Imprime a sequencia de numeros ordenada */
printf("\nSequencia ordenada : ");
for(i=0; i<MAX; i++)
printf("\n %10.5f ",n[i]);
printf("\n");
}

Matrizes

Para representar uma matriz 3x4 (3 linha e 4 colunas) de números reais utilizamos a
seguinte declaração:
float A[3][4];
Assim fica reservado um espaço de memória conforme a figura abaixo:

A[0][0] A[0][1] A[0][2] A[0][3]


A[1][0] A[1][1] A[1][2] A[1][3]
A[2][0] A[2][1] A[2][2] A[2][3]

Exemplo: Produto de uma matriz por um vetor


Vamos montar um programa que multiplica um vetor por uma matriz.

/* * * * * * * * * * * * * * * * * * * * * * */
/* Multiplicacao de um vetor por uma matriz */
/* * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
main()
{
int i,j;
float A[3][3] = {{1.0, 1.5, 2.1}, {3.4, 2.2, 9.1}, {-1.2, -3.4, 0.9}};
float v[3] = {2.0, 1.0, 0.5};
float p[3];
for(i=0;i<3;i++) {
p[i] = 0;
for(j=0;j<3;j++) {
p[i] += A[i][j] * v[j];
}
}
Robótica Teoria e Prática
Robótica Teoria e Prática

for(i=0;i<3;i++) {
printf("\n[");
for(j=0;j<3;j++) {
printf("% 5.3f ",A[i][j]);
}
printf(" ] ");
printf(" [ %5.3f ]",v[i]);
}
for(i=0;i<3;i++)
printf("\n p[%1d] = %10.4f",i,p[i]);
}

PONTEIROS
Considere o seguinte programa:

#include <stdio.h>
int teste(int i)
{
i = i + 20;
printf("Dentro da funcao i = %d \n",i);
return(i);
}
void main()
{
int i,j;
i = 1;
printf("Fora da funcao i = %d \n",i);
j = teste(i);
printf("Fora da funcao i = %d \n",i);
printf("Fora da funcao j = %d \n",j);
}

Observe que o valor da variável i não tem seu conteúdo alterado pela função. Isto ocorre
porque quando uma função é chamada durante o programa, todas as variáveis presentes
Robótica Teoria e Prática
Robótica Teoria e Prática

na função são criadas neste. Quando a função finaliza, todas as variáveis da função são
apagadas da memória. Muitas vezes gostaríamos que os argumentos de entrada da
função pudessem ter seus valores alterados quando a função finalizasse. Esta será uma
das aplicações do conceito de ponteiros.

O que é um ponteiro?

Um ponteiro é uma variável que contém o endereço de memória de outra variável.


Todas as variáveis são alocadas em algum espaço de memória do computador. O
ponteiro fornece um mecanismo para obter e armazenar este endereço de memória.
Considere o exemplo:

#include <stdio.h>
void main()
{
int i;
printf("Endereco de i = %x\n",&i);
}

O endereço da variável é obtido utilizando-se o operador unário & na frente da variável.


Assim &i fornece o endereço da variável i.

Principais Aplicações de Ponteiros

Algumas situações em que os ponteiros são úteis:


1. Quando em uma função desejamos retornar mais de um valor.
2. Para passar vetores e matrizes de forma mais conveniente como argumentos de
funções.
3. Para manipular vetores e matrizes de forma mais eficiente.
4. Para manipular estruturas de dados mais complexas, tais como listas e árvores.
5. Na utilização das funções calloc() e malloc() responsáveis pela alocação de memória
dinâmica.

Armazenando os Endereços das Variáveis

Para armazenar o endereço de uma variável (por exemplo &i) em outra variável, é
necessário criar um tipo especial de variável denominada apontador. Exemplo:

#include <stdio.h>
void main()
{
int i ;
int *pi;
pi = &i;
printf("Endereco de i = %x ou %x\n",&i,pi);
}

A variável pi é uma variável do tipo ponteiro para inteiro (ou seja, ela recebe o endereço
de uma variável do tipo inteiro). Para informar que esta variável é do tipo apontador
colocamos um asterisco (*) na frente da variável no momento da sua declaração:

Robótica Teoria e Prática


Robótica Teoria e Prática

int * pi
Tipo de ponteiro Indica ponteiro Nome da variável

Acessando o conteúdo de um endereço

Considere o exemplo anterior em que pi = &i. Além do endereço de i, (já armazenado


em pi) podemos também acessar o conteúdo armazenado no endereço de memória. Isto
equivale a obter o valor da variável i.

Observe o exemplo:

#include <stdio.h>
void main()
{
int i ;
int j ;
int *pi;
pi = &i;
i = 25;
j = *pi + 8; /* equivalente a j = i + 8 */
printf("Endereco de i = %x \n",pi);
printf("j = %d \n",j);
}

O operador unário * trata seu operando como um endereço e acessa este endereço para
buscar o conteúdo da variável. Observe que o * tem dupla função:

1. Em uma declaração de variável, indica que a variável é do tipo ponteiro.


2. Durante uma atribuição, acessa o conteúdo do endereço armazenado pela variável
ponteiro.

No nosso exemplo, para alterar o valor da variável i, temos duas alternativas (totalmente
equivalentes) :
i = 5;
*pi = 5;

Ponteiros e Argumentos de Funções

Como sabemos, uma função não consegue alterar diretamente uma variável utilizada
como argumento. Com o auxílio dos ponteiros podemos encontrar uma alternativa para
esta situação. No exemplo do programa de ordenação, foi preciso permutar dois
elementos do vetor que estavam fora de ordem. Não seria possível permutar dois valores
através de uma função como abaixo:

/* * * * * * * * * * * * * * * * * * * * * * * * * */
/* Este programa NÃO consegue permutar os valores */
#include <stdio.h>

Robótica Teoria e Prática


Robótica Teoria e Prática

void troca(float x, float y)


{
float auxiliar;
auxiliar = x;
x = y;
y = auxiliar;
}
main()
{
float x = 1.2;
float y = 56.89;
troca(x,y);
printf("x = %6.2f e y = %6.2f\n",x,y);
}
O resultado deste programa seria:

x = 1.2 e y = 56.89

Utilizando ponteiros existe uma maneira de obter o efeito desejado:

/* * * * * * * * * * * * * * * * * * * * * * * * * */
/* Este programa permutar os valores das variaveis */
#include <stdio.h>
void troca(float *x, float *y)
{
float auxiliar;
auxiliar = *x;
*x = *y;
*y = auxiliar;
}
main()
{
float x = 1.2;
float y = 56.89;
troca(&x,&y);
printf("x = %6.2f e y = %6.2f\n",x,y);
}

O uso comum de argumentos do tipo ponteiro ocorre em funções que devem retornar
mais de um valor. No exemplo acima, a função retornou dois valores.

Ponteiros com Vetores

Na linguagem C, o relacionamento de ponteiros com vetores e matrizes é tão direto que


daqui para frente sempre trataremos vetores e matrizes utilizando ponteiros. Qualquer
operação que possa ser feita com índices de um vetor pode ser feita através de ponteiros.
Vamos acompanhar através do exemplo de ordenação:
/* * * * * * * * * * * * * * * * * */
/* Ordenacao pelo metodo da bolha */
#define MAX 10

Robótica Teoria e Prática


Robótica Teoria e Prática

#include <stdio.h>
void troca(float *x, float *y)
{
float auxiliar;
auxiliar = *x;
*x = *y;
*y = auxiliar;
}
void ordena(float *px)
{
int i ;
int flag;
/* Ordena a sequencia de numeros */
flag = 1;
while(flag == 1) {
flag = 0;
for(i=0;i<(MAX-1);i++)
{
if (px[i] > px[i+1])
{
troca(&(px[i]),&(px[i+1]));
flag = 1;
}
}
}
}
main()
{
int i ;
float n[MAX];
/* Entrada de Dados */
printf("Entre com os numeros para ordenacao \n");
for(i=0;i<MAX;i++)
{
printf("\n numero %2d: ",i);
scanf("%f",&(n[i]));
}
ordena(n);
/* Imprime a sequencia de numeros ordenada */
printf("\nSequencia ordenada : ");
for(i=0; i<MAX; i++)
printf("\n %10.5f ",n[i]);
printf("\n");
}

Observe que quando chamamos a função ordena(n,MAX), utilizamos como argumento


n referência a nenhum índice. A função ordena é declarada como: void ordena(float
*px, int limite) Como o C sabe que estamos nos referenciando a um vetor e não a uma
simples variável ? Na verdade px é uma variável ponteiro para um float. Ela recebe o
Robótica Teoria e Prática
Robótica Teoria e Prática

endereço do primeiro elemento do vetor . Porém, os vetores são alocados


sequencialmente na memória do computador. , de forma que a referência px[5], acessa o
quinto conteúdo em sequencia na memória. Quando o nome de um vetor é passado para
uma função, o que é passado é a posição do início do vetor.

Alocação de Vetores Dinamicamente

Uma das restrições do nosso programa de ordenação é que o usuário não pode definir a
princípio quantos elementos ele pretende ordenar. Isto ocorre porque precisamos
informar na declaração do vetor qual será a sua dimensão. Vamos retirar essa restrição.
Para isso utilizaremos um novo comando: malloc(). Vamos utilizar um exemplo:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
void main()
{
int i;
int n;
float *v;
printf("Entre com a dimensao do vetor desejada = ");
scanf("%d",&n);
v = (float *) malloc(n * sizeof(float));
for(i=0;i<n;i++)
scanf("%f",&(v[i]));
for(i=0;i<n;i++)
printf("v[%2d]=%f\n",i,v[i]);
free(v);
}

Para efetuar a alocação dinâmica observe as etapas do programa:

1. O vetor que será alocado foi declarado como um ponteiro: float *v;
2. O comando malloc(n * sizeof(float)) reserva n espaços de memória, cada um do
tamanho de um float.
3. A função malloc retorna o endereço do primeiro elemento do vetor: (float *) malloc()
4. A função free, libera o espaço de memória reservado para o vetor.

Alocação de Matrizes Dinamicamente

Para alocar matrizes observe o exemplo:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
float **matalloc(int n,int m)
{
int j;
float **A;
28
Robótica Teoria e Prática
Robótica Teoria e Prática

A = (float **)malloc(n * sizeof(float *));


for(j=0;j<n;j++)
A[j] = (float *) malloc(m * sizeof(float));
return(A);
}
void matfree(float **A,int n,int m)
{
int i;
for(i=0;i<n;i++)
free(A[i]);
free(A);
}
void main()
{
int i;
int j;
int n;
int m;
float **A;
printf("Entre com a dimensão da matriz desejada = ");
scanf("%d, %d",&n,&m);
A = matalloc(n,m);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%f",&(A[i][j]));
for(i=0;i<n;i++) {
printf("\n");
for(j=0;j<m;j++)
printf("A[%2d][%2d]=%f\n",i,j,A[i][j]);
}
matfree(A,n,m);
}

Método LU para resolução de Sistemas Lineares

Um dos métodos clássicos para se resolver um sistema linear da forma Ax=b, é a


decomposição LU. De
forma reduzida temos três etapas:
1. Decompor A = LU
2. Resolver Lc = b
3. Resolver Ux = c
Vamos descrever este método partindo de um exemplo. Considere o sistema linear
abaixo:

Robótica Teoria e Prática


Robótica Teoria e Prática

Determinando a matriz L e U
Nosso objetivo inicial é aplicar um conjunto de operações elementares sobre a matriz
dos coeficientes de tal forma que ao final do processo obtemos A = LU, ou seja, a
matriz A pode ser escrita como o produto de duas matrizes onde:

L : Matriz triangular inferior, cuja diagonal contêm apenas o valor 1.


U : Matriz triangular superior.
Para obter estas matrizes existem três tipos de operações elementares:
1- Permutação de linhas (Li <-> Lj) (Não é necessário implementar, para o primeiro
trabalho).
2- Multiplicação de uma linha por um escalar K (Li = K Li). (Não é necessário
implementar, para o primeiro trabalho).
3- Substituição da i-ésima linha pela i-ésima linha acrescida de K vezes a j-ésima linha
(Li = Li + K Lj ) Vamos iniciar determinando a matriz U. Para isso nosso objetivo é
transformar a matriz dada em uma matriz triangular superior. Começamos na primeira
coluna, eliminando todos os elementos abaixo do 2:

E para a ultima linha obtemos:

Passamos agora para a segunda coluna e eliminaremos os elementos abaixo do –8 (neste


exemplo o 8):

Obtemos então uma matriz triangular superior. Esta matriz é matriz U desejada. Para
obter a matriz L, observamos que cada uma das operações elementares aplicadas pode
ser representada por uma matriz. Vamos acompanhar pelo exemplo.

A primeira operação elementar foi :

Esta operação elementar é representada pela matriz:

Robótica Teoria e Prática


Robótica Teoria e Prática

De forma geral todas as operações elementares são representadas por matrizes:


1. Permutação de linhas (Li <-> Lj): Partindo da matriz identidade (de mesma
dimensao que a matriz A) troque a i-ésima linha pela j-ésima linha.
Ex: L2 <-> L3, basta trocar as linhas 2 e 3 da matriz identidade para obter a matriz:

2. Multiplicação de uma linha por um escalar K (Li = K Li): Partindo da matriz


identidade troque o iésimo elemento da diagonal pelo valor K.
Ex: L2 = 5 L2, basta trocar na segunda linha da identidade a diagonal para 5:

3. Substituição da i-ésima linha pela i-ésima linha acrescida de K vezes a j-ésima linha
(Li = Li + K Lj ):Partindo da matriz identidade, coloque o valor K na i-ésima linha e j-
ésima coluna.
Ex: L2 = L2 + 4 L3. Partindo da matriz identidade, coloque na segunda linha e na
terceira coluna o valor 4:

Robótica Teoria e Prática


Robótica Teoria e Prática

Robótica Teoria e Prática


Robótica Teoria e Prática

Robótica Teoria e Prática


Robótica Teoria e Prática

VISUALIZAÇÃO E APLICAÇÕES GRÁFICAS 2D


PONTOS E RETAS NO OPENGL

A Tela do Computador
A tela do computador pode ser considerada uma matriz de células discretas (Pixels),
cada qual pode estar acesa ou apagada.

0,1 1,1 2,1 …


0,0 1,0 2,0 …

A definição da tela varia conforme o monitor e a placa gráfica. As definições básicas


encontradas na maioria dos monitores são:

640 x 480

800 x 600

1024 x 768

1280 x 1024

Cores
A cada pixel associamos uma cor. Para obter uma cor, o monitor envia certa
combinação de vermelho, verde e azul (RGB). O número de cores possíveis varia
conforme o hardware. Cada pixel tem uma mesma quantidade de memória para
armazenar suas cores. O buffer de cores (Color Buffer) é uma porção da memória
reservada para armazenar as cores em cada pixel. O tamanho deste buffer é usualmente
medido em bits. Um buffer de 8 bits pode exibir 256 cores diferentes simultaneamente.
Conforme a capacidade da placa gráfica podemos ter:

8 bits – 256 cores


(High Color) 16 bits – 65.536 cores
(True Color) 24 bits – 16.777.216 cores
(True Color) 32 bits – 4.294.967.296 cores

Existem duas formas básica de acessar as cores no OpenGL: RGB e Modo Indexado.
Trabalharemos sempre em formato RGB. No formato RGB você deve informar as
intensidades de Vermelho, Verde e Azul desejadas. Estas intensidades devem variar
entre 0.0 a 1.0. A tabela abaixo mostra como obter as cores básicas:

Cores R G B R G B

Robótica Teoria e Prática


Robótica Teoria e Prática

Vermelho 1.0 0.0 0.0


Verde 0.0 1.0 0.0
Azul 0.0 0.0 1.0
Amarelo 1.0 1.0 0.0
Cyan 0.0 1.0 1.0
Magenta 1.0 0.0 1.0
Branco 1.0 1.0 1.0
Preto 0.0 0.0 0.0

Introdução ao OpenGL

O sistema gráfico OpenGL (GL significa Graphics Library) é uma biblioteca (de
aproximadamente 350 comandos) para aplicações gráficas. O OpenGL foi desenvolvido
pela Silicon Graphics (SGI) voltado para aplicações de computação gráfica 3D, embora
possa ser usado também em 2D. As rotinas permitem gerar primitivas (pontos, linhas,
polígonos, etc) e utilizar recursos de iluminação 3D. O OpenGL é independente do
sistema de janelas, ou seja, suas funções não especificam como manipular janelas. Isto
permite que o OpenGL possa ser implementado para diferentes sistemas: X Window
System (Unix), Windows 95 e NT, OS/2 , Macintosh, etc.

Exemplo: Plotar um ponto na tela utilizando as bibliotecas do OpenGl

#include <gl\glut.h>
void redesenha()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f(1.0,0.0,0.0);
glBegin(GL_POINTS);
glVertex2f(200.0,200.0);
glEnd();
glFlush();
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400); /* Antes do glutCreateWIndow */
glutInitWindowPosition(1,1);
glutCreateWindow("Ponto");
gluOrtho2D(0,399,399,0); /* Apos CreateWindow */
glutDisplayFunc(redesenha); /* Esta funcao e necessaria, caso
contrario o opengl nao consegue
criar a janela */
glutMainLoop();
}

Vamos comentar comando a comando:

glutInit(&argc,argv);
É utilizado para iniciar a biblioteca GLUT.

Robótica Teoria e Prática


Robótica Teoria e Prática

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);


Quando uma janela é criada, seu tipo é determinado pelo Display Mode. O tipo da
janela inclui um conjunto de características desejadas. Neste caso temos três:
GLUT_SINGLE: Buffer simples
GLUT_RGBA...: Utilizaremos o modo RGBA.
GLUT_DEPTH.: Buffer de profundidade (utilizado em remoção de superfícies
escondidas).
glutInitWindowSize(400,400);
Indica o tamanho da janela a ser aberta (em pixels).
glutInitWindowPosition(1,1);
Indica a posição inicial da janela.
glutCreateWindow("Ponto");
Cria uma janela para o OpenGL denominada Ponto
gluOrtho2D(0,399,399,0);
Este comando estabelece a escala da tela. Sua sintaxe é:
gluOrtho2D(GLdouble left, Gldouble right, Gldouble bottom, Gldouble top);
glutDisplayFunc(redesenha);
Este comando registra que a função void redesenha() será a rotina a ser chamada sempre
que a
janela necessita ser redesenhada.
glutMainLoop();
Inicia o gerenciamento da janela e mantém o programa em loop, aguardando por
eventos.
Quando a função redesenha é chamada temos o seguinte resultado:
glClearColor(0.0,0.0,0.0,0.0);
Indica cor para ser utilizada no fundo da tela.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Pinta os buffers indicados com a cor do glClearColor()
glColor3f(1.0,0.0,0.0);
Define o vermelho como cor atual.
glBegin(GL_POINTS);
glVertex2f(200.0,200.0);
glEnd();
Plota um ponto na posição (200,200) na tela.
glFlush();
Imprime o conteúdo do buffer na tela.

Exercícios:

1) Comente as seguintes linhas na função redesenha e veja o resultado:


glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

2) Acrescente um contador para verificar quantas vezes a função redesenha é chamada.

void redesenha()
{
static int i = 0;
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Robótica Teoria e Prática
Robótica Teoria e Prática

glColor3f(1.0,0.0,0.0);
glBegin(GL_POINTS);
glVertex2f(200.0,200.0);
glEnd();
glFlush();
printf(" %d ",i++);
}

Comente a seguinte linha do código e veja o resultado.


glutDisplayFunc(redesenha);

Exemplo: Plotar uma reta unindo dois pontos


Como exemplo vamos desenhar uma reta (não vertical) unindo dois pontos (x0,y0) e
(x1,y1).
A equação da reta que passa por dois pontos é:

Algoritmo ingênuo

A primeira idéia de como resolver este problema é proposto pelo programa abaixo. Este
é um exemplo ingênuo de como desenhar a reta que passa por dois pontos dados.
Vamos discutir a seguir os principais problemas deste programa e as possíveis soluções.

/* -------------------------------------------------------------- */
/* Exemplo ingênuo de como plotar a reta definida por dois pontos */
/* -------------------------------------------------------------- */
#include <gl\glut.h>
#include <stdio.h>
int pontos;
float x0,y0,x1,y1;
float Reta_dois_pontos(float x)
{
float y;
y = (y1-y0)/(x1-x0)*(x-x0) - y0;
return(y);
}
void display()
{
int i ;
float x,y;
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f(1.0,0.0,0.0);
for (i=0;i<pontos;i++)
{
x = x0 + i * (x1 - x0)/pontos;
y = Reta_dois_pontos(x);
glBegin(GL_POINTS);
glVertex2f(x,y);
Robótica Teoria e Prática
Robótica Teoria e Prática

glEnd();
}
glFlush();
glutSwapBuffers();
}
void main(int argc, char **argv)
{
printf("x0 = ");
scanf("%f",&x0);
printf("\ny0 = ");
scanf("%f",&y0);
printf("\nx1 = ");
scanf("%f",&x1);
printf("\ny1 = ");
scanf("%f",&y1);
printf("\nPontos = ");

scanf("%d",&pontos);
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
glOrtho(0,399,399,0,-1,1);
glutDisplayFunc(display);
glutMainLoop();
}

Algumas desvantagens do programa proposto:

1) Este método requer operações em ponto flutuante (float ou double) para cada pixel.
Isto acarreta em um algoritmo lento, se comparado a um algoritmo que opera somente
com números inteiros. Para o caso da reta, existe um tal algoritmo que utiliza somente
aritmética com números inteiros. Este algoritmo foi desenvolvido por Jack E.
Bresenham na década de 60 e será descrito adiante.
2) O usuário estabelece o número de pontos da reta a serem plotados entre os dois
pontos. Podem ocorrer dois casos: faltarem pontos (a reta fica pontilhada), sobrarem
pontos (neste caso o algoritmo faz contas desnecessárias). O ideal é o próprio programa
se encarregar de determinar o número de pontos necessários e suficientes para resolver
o problema.
3) O caso particular da reta vertical x = K (onde K é constante) não pode ser plotado.

Algoritmo de Bresenham

Partindo da informação do pixel inicial (Ax,Ay) e do pixel final (Bx,By), o algoritmo de


Bresenham, para a reta, determina quais pixels devem ser acessos de (Ax,Ay) até
(Bx,By) utilizando para isso unicamente aritmética inteira. A idéia fundamental do
algoritmo é que se restringirmos a reta para inclinações entre 0 e 1 (de 0 a 45 graus),
então para cada pixel existem somente duas possibilidades como indica a figura abaixo:

Robótica Teoria e Prática


Robótica Teoria e Prática

Para os casos em que a inclinação não está entre 0 e 1, utilizamos a mesma solução
considerando simetrias. O algoritmo completo deve considerar oito casos:

1) 0 m 1 com Ax < Bx.


2) 1 < m < com Ay < By.
3) −1 > m > − com Ay < By.
4) 0 m −1 com Ax > Bx.
5) 0 m 1 com Ax > Bx.
6) 1 < m < com Ay > By.
7) −1 > m > − com Ay > By.
8) 0 m −1 com Ax < Bx

Vamos descrever o funcionamento do algoritmo para o caso 1, os casos restantes


seguem por simetria.

• Partindo do ponto (Ax,Ay), como 0 m 1, então para o próximo pixel temos


somente duas escolhas possíveis: (Ax+1,Ay) e (Ax+1,Ay+1). Lembre da figura anterior
que os círculos transparentes são as duas opções. O incremento em uma unidade vem do
fato que estamos avançando um pixel na direção do x (Ax + 1), e podemos ou não
avançar um pixel na direção do y (Ay ou Ay +1).
• O ponto ideal é dado por (Ax+1,y) onde y = m (Ax + 1) + b. Nós devemos portanto
escolher qual dos dois pontos anteriores está mais próximo do ponto ideal (Ax+1, y).
Para isso calculamos a distância entre destes dois pontos para o ponto ideal:

D1 = y – Ay e D2 = Ay + 1 – y

• Assim se D1 <= D2 então escolhemos o ponto (Ax+1,Ay), caso contrário, se D1 > D2


então escolhemos o ponto (Ax+1, Ay+1). Contudo, como queremos desenvolver um
algoritmo rápido para fazer isto, teremos que nos restringir a aritmética inteira. Observe
que o ponto ideal y é real e não inteiro. Assim, os próximos passos têm por objetivo
obter um resultado equivalente a testar D1 e D2, porem utilizando somente números
inteiros.

• Considere P1 = D1 – D2. Testar D1 <= D2 , ou D1 > D2 é equivalente


respectivamente a testar
P1 <= 0, ou P1 > 0. Esta variável P1 será denominada a variável de decisão. Assim,
temos que:

Robótica Teoria e Prática


Robótica Teoria e Prática

P1 = D1 – D2
= y – Ay – (Ay + 1) + y
= 2y – 2Ay -1
Substituindo y = m (Ax + 1) + b, obtemos
P1 = 2m(Ax + 1) + 2b – 2Ay -1

• Temos que m = dY/dX, onde dY = abs(By – Ay) e dX = Bx – Ax e substituindo


obtemos:
P1 = 2 dY/dX (Ax + 1) + 2b – 2Ay -1
Multiplicando por dX obtemos:
P1 dX = 2 dY (Ax + 1) + 2 b dX – 2Ay dX - dX
Observe que para o caso 1 em questão dX > 0, assim o sinal de P1 e de P1 * dX é o
mesmo.
Consideramos então a variável de decisão P1 como sendo
P1 = dY (Ax + 1) + 2 b dX – 2Ay dX – dX

• A expressão
2 dY (Ax + 1) + 2 b dX – 2Ay dX - dX
é o teste que estamos procurando, pois ele envolve somente números inteiros
(dY,dX,Ax,Ay,b). Porém ainda podemos melhorar o algoritmo, pois esta avaliação
ficaria demasiada cara para ser feita a cada novo pixel da reta.

• Neste passo vamos tentar calcular a variável de decisão P2 para o próximo pixel,
utilizando a informação que adquirimos no passo anterior para estimar P1. De forma
geral para dois passos subseqüentes temos que:
P2 – P1 = 2dY(Ax + 2) +2b dX –2Ay dX –dX – (2dY(Ax + 1) +2b dX –2Ay dX - dX)
= 2 dY -2 (Ay – Ay) dX
Temos duas possibilidades: ou Ay = Ay ou Ay = Ay+1, o que se resume a:
P2 – P1 = 2 dY ,caso em que escolhemos o ponto (Ax+1,Ay)
P2 – P1 = 2 dY -2 dX ,caso em que escolhemos o ponto (Ax+1,Ay+1)
Assim uma vez que calculamos a variável de decisão P1 para o primeiro pixel, nos
pixels subseqüentes, basta incrementar 2 dY ou (2 dY – 2 dX), conforme o pixel
escolhido no passo anterior.

• Calculando P1 para o pixel inicial (Ax,Ay) obtemos:


P1 = 2 dY (Ax + 1) + 2 b dX – 2 Ay dX – dX
Para obter b, observe que de y = mx + b obtemos b = y – mx, e no ponto (Ax,Ay) temos
que
b=Ay-mAx = Ay – dY/dX Ax. Substituindo em P1 obtemos:
P1 = 2 dY (Ax + 1) + 2 (Ay – dY/dX Ax) dX – 2 Ay dX – dX
= 2 dY Ax + 2 dY + 2 Ay dX – 2 dY Ax -2 Ay dX – dX
= 2 dY – dX

• Conclusão: como resultado final, o algoritmo se resume a:


dX = Bx – Ax
dY = By – Ay
Decisão inicial P1 = 2 dY – dX

Incremente Ax até Bx e para cada passo:

Robótica Teoria e Prática


Robótica Teoria e Prática

Se P1 <= 0 escolha o pixel Ay e incremente P1 = P1 + 2 dY


Se P1 > 0 escolha o pixel Ay + 1 e incremente P1=P1 + 2 dY – 2 dX.

O programa considerando as oito possibilidades é dado abaixo:

#include <gl\glut.h>
#include <stdio.h>
//=============================================================
=======
// b r e s l i n e . c
//
// VERSION 1: draws only from one end and calculates both x and y.
//
// Programmer: Kenny Hoff
// Date: 10/25/95
// Purpose: To implement the Bresenham's line drawing algorithm
for
// all slopes and line directions (using minimal
routines).
//=============================================================
======
// EXTERNALLY DEFINED FRAMEBUFFER AND FRAMEBUFFER
DIMENSIONS (WIDTH))
// extern int WIDTH;
//=============================================================
=======
=
// Fills the intermediate points along a line between the two given
// endpoints using Bresenham's line drawing algorithm. NOTE: this
// routine does no clipping so the coordinate values must be within
the
// FrameBuffer bounds.
// NOTE: USE (Ax,Ay) as the starting point (values that are
// incremented)
//=============================================================
=======
void BresLine(int Ax, int Ay, int Bx, int By)
{
//--------------------------------------------------------------
-
// INITIALIZE THE COMPONENTS OF THE ALGORITHM THAT ARE NOT
// AFFECTED BY THE SLOPE OR DIRECTION OF THE LINE
//--------------------------------------------------------------
int dX = abs(Bx-Ax); // store the change in X and Y of the
// line endpoints
int dY = abs(By-Ay);
//--------------------------------------------------------------
// DETERMINE "DIRECTIONS" TO INCREMENT X AND Y (REGARDLESS OF
// DECISION)
Robótica Teoria e Prática
Robótica Teoria e Prática

//--------------------------------------------------------------
-
int Xincr, Yincr;
if (Ax > Bx) { Xincr=-1;} else { Xincr=1;}//which direction in
X?
if (Ay > By) { Yincr=-1;} else { Yincr=1;}//which direction in
Y?
//--------------------------------------------------------------
// DETERMINE INDEPENDENT VARIABLE (ONE THAT ALWAYS
INCREMENTS BY
// 1 (OR -1) )AND INITIATE APPROPRIATE LINE DRAWING ROUTINE
// (BASED ON FIRST OCTANT ALWAYS). THE X AND Y'S MAY BE FLIPPED
//IF Y IS THE INDEPENDENT VARIABLE.
//--------------------------------------------------------------

{
int dPr = dY<<1; // amount to increment decision
// if right is chosen (always)
int dPru = dPr - (dX<<1); // amount to increment
// decision if up is chosen
int P = dPr - dX; // decision variable start
value
for (; dX>=0; dX--) // process each point in the line
// one at a time (just use dX)
{
glBegin(GL_POINTS);
glVertex2d(Ax, Ay); // plot the pixel
glEnd();
if (P > 0) // is the pixel going right AND up?
{
Ax+=Xincr; // increment independent variable
Ay+=Yincr; // increment dependent variable
P+=dPru; // increment decision (for up)
}
else // is the pixel just going right?
{
Ax+=Xincr; // increment independent variable
P+=dPr; // increment decision (for right)
}
}
}
else // if Y is the independent variable
{
int dPr = dX<<1; // amount to increment decision if
// right is chosen (always)
int dPru = dPr - (dY<<1); // amount to increment
// decision if up is chosen
int P = dPr - dY; // decision variable start value
for (; dY>=0; dY--) // process each point in the line
// one at a time (just use dY)
Robótica Teoria e Prática
Robótica Teoria e Prática

{
glBegin(GL_POINTS);
glVertex2d(Ax, Ay); // plot the pixel
glEnd();
if (P > 0) // is the pixel going up AND right?
{
Ax+=Xincr; // increment dependent variable
Ay+=Yincr; // increment independent variable
P+=dPru; // increment decision (for up)
}
else // is the pixel just going up?
{
Ay+=Yincr; // increment independent variable
P+=dPr; // increment decision (for right)
}
}
}
}
void display()
{
int i;
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f(1.0,0.0,0.0);
BresLine(0,0,400,400);
glFlush();
glutSwapBuffers();
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
glOrtho(0,399,0,399,-1,1);
glutDisplayFunc(display);
glutMainLoop();
}

Retas no Opengl

O OpenGL dispõe em sua biblioteca interna de um comando que plota uma reta por dois
pontos dados.
Este comando é descrito abaixo:

void display()
{
float x,y;
glClearColor(0.0,0.0,0.0,0.0);
Robótica Teoria e Prática
Robótica Teoria e Prática

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINES);
glVertex2f(x0,y0);
glVertex2f(x1,y1);
glEnd();
glFlush();
}

Exemplo: Plotar o gráfico de uma função


Vamos começar com uma versão bem simplificada, para plotar o gráfico de uma função
y=f(x).

#include <gl\glut.h>
#include <stdio.h>
float funcao(float x)
{
return(x*x);
}
void display()
{
float x,y;
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f(1.0,0.0,0.0);
for(x=-1;x<1;x+=0.01)
{
y = funcao(x);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
}
glFlush();
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
gluOrtho2D(-1,1,-1,1);
glutDisplayFunc(display);
glutMainLoop();
}

Vamos melhorar este programa:


1) Acrescentando os eixos.
2) Criando uma variável pontos que permita melhorar a discretização.
3) Separa os programa em dois módulos:
Robótica Teoria e Prática
Robótica Teoria e Prática

funcao01.cpp: funções básicas de inicialização e controle do glut.


funcao02.cpp: funções gráficas definidas com a tarefa específica de plotar o gráfico da
função.

/* * * * * * * * * * * * * */
/* Modulo: Funcao01.cpp */
/* * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "funcao02.h"
void redesenha()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_eixo();
plota_funcao();
glFlush();
glutSwapBuffers();
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Funcao");
glutDisplayFunc(redesenha);
gluOrtho2D(-5,5,-5,5);
glutMainLoop();
}

/* * * * * * * * * * * * * */
/* Modulo: funcao02.cpp */
/* * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
#define PI 3.1415926535897932384626433832795
float xmin = -5.0;
float xmax = 5.0;
float ymin = -5.0;
float ymax = 5.0;
int pontos = 400;
/* -------------------------------- */
float funcao(float x)
/* -------------------------------- */
{
return(sin(x));
}
Robótica Teoria e Prática
Robótica Teoria e Prática

/* -------------------------------- */
void plota_eixo()
/* -------------------------------- */
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
}
/* -------------------------------- */
void plota_funcao()
/* -------------------------------- */
{
int i ;
float dx ;
float x,y;
dx = (xmax - xmin)/pontos;
glColor3f(1.0,0.0,0.0);
x = xmin;
for(i=0;i<pontos;i++)
{
y = funcao(x);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
x = x + dx;
}
}
/* funcao02.h */
float funcao(float x);
void plota_eixo();
void plota_funcao();

TECLADO E MOUSE (Callbacks)


Introdução

O usuário pode interagir com o programa de duas formas principais: através do Mouse
ou Teclado. Para isso o GLUT dispõe de dois tipos de funções (que denominamos
Callbacks) específicas para habilitar a utilização do teclado e do mouse. Vamos
descrevê-las a seguir.

Teclado
Para registrar ocorrências no teclado o GLUT dispõe da função:
void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) , Esta função
determina que quando uma tecla for pressionada, o controle do programa deve passar a
função definida no campo (*func) e esta função receberá como parâmetros de entrada, a
Robótica Teoria e Prática
Robótica Teoria e Prática

tecla pressionada (unsigned char key), e a posição do mouse (int x, int y). O exemplo
abaixo exemplifica uma aplicação para o programa funções.

Exemplo: Utilização do teclado no programa funções.


Como exemplo vamos acrescentar no programa funções a possibilidade de alterarmos o
domínio da função durante a execução do programa. Assim podemos estabelecer que
quando o usuário pressionar a tecla “D” ou “d”, o programa interrompe e solicita na
janela DOS as novas informações sobre o domínio da função. Vamos reorganizar o
programa, modularizando as principais rotinas do programa em arquivos diferentes.

Nosso programa terá dois módulos principais:

- funcao010.cpp: Mantém as rotinas de visualização do OpenGL


- funcao011.cpp: Mantém as rotinas relativas ao desenho da função.

Teremos ainda o módulo:

- funcao011.h: Este módulo deve ter apenas o cabeçalho das funções do programa
funcao011.cpp.
A seguir apresentamos o código de cada um destes módulos.

Módulo funcao011.h

/* * * * * * * * * * * * * * */
/* Modulo: funcao011.h */
/* * * * * * * * * * * * * * */
float funcao(float x);
void plota_eixo();
void plota_funcao();
void entra_dominio();

Módulo funcao010.cpp
Este módulo contém as rotinas básicas do OpenGL e a abertura do programa (void
main()). Observe que a função glutKeyboardFunc(le_tecla); informa que quando
alguma tecla é pressionada o controle do programa deve passar a rotina void
le_tecla(unsigned char key, int x, int y).

/* * * * * * * * * * * * * * */
/* Modulo: funcao010.cpp */
/* * * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "funcao011.h"
void display()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Robótica Teoria e Prática
Robótica Teoria e Prática

plota_eixo();
plota_funcao();
glFlush();
}
void le_tecla(unsigned char key, int x, int y)
{
switch(key)
{
case 'D':
case 'd':
entra_dominio();
display();
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
glutDisplayFunc(display);
glutKeyboardFunc(le_tecla);
glutMainLoop();
}

Módulo funcao011.cpp
Neste módulo separamos as rotinas que trabalham com a função ser desenhada.

/* * * * * * * * * * * * * * */
/* Modulo: funcao011.cpp */
/* * * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
float xmin,ymin,xmax,ymax,incremento;
float funcao(float x)
{
return(sin(x));
}
void plota_eixo()
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
Robótica Teoria e Prática
Robótica Teoria e Prática

}
void plota_funcao()
{
float x,y;
glColor3f(1.0,0.0,0.0);
for(x=xmin;x<xmax;x+=incremento)
{
y = funcao(x);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
}
}
void entra_dominio()
{
int pontos;
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Total de pontos =");
scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

Mouse

O GLUT é capaz de obter três tipos de ocorrências diferentes a partir do mouse. Vamos
descrevê-las a seguir.

glutMouseFunc

void glutMouseFunc(void (*func)(int button, int state, int x, int y)) Este evento detecta
quando algum botão do mouse foi pressionado. Quando isto ocorre, o programa executa
a rotina definida em void (*func). Os parâmetros desta rotina podem receber os
seguintes valores:
- button : informa qual botão do mouse foi pressionado, sendo atribuído com um dos
seguintes valores: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON,
GLUT_RIGHT_BUTTON.
- state: informa quando o botão foi pressionado e quando o botão foi solto, sendo
atribuído com dois possíveis valores: GLUT_DOWN ou GLUT_UP.
- X,y: informa a posição do mouse na janela quando o botão foi pressionado.
Como exemplo, vamos alterar o programa função anterior, e acrescentar outra forma de
interrupção para alterar o domínio. Assim se o usuário pressionar o botão esquerdo do

Robótica Teoria e Prática


Robótica Teoria e Prática

mouse, o programa solicita na janela DOS o novo domínio de visualização. Para


implementar esta alteração só precisamos mudar o programa funcao010.cpp. Seu novo
código é apresentado a seguir:

/* * * * * * * * * * * * * * */
/* Modulo: funcao010.cpp */
/* * * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "funcao011.h"
void display()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_eixo();
plota_funcao();
glFlush();
}
void le_tecla(unsigned char key, int x, int y)
{
switch(key)
{
case 'D':
case 'd':
entra_dominio();
display();
break;
}
}
void le_botao_mouse(int b,int state,int x, int y)
{
switch(b) {
case GLUT_RIGHT_BUTTON:
switch(state) {
case GLUT_DOWN:
entra_dominio();
display();
break;
case GLUT_UP:
printf(" x = %d y = %d \n",x,y);
break;
}
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);

Robótica Teoria e Prática


Robótica Teoria e Prática

glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
glutDisplayFunc(display);
glutKeyboardFunc(le_tecla);
glutMouseFunc(le_botao_mouse);
glutMainLoop();
}

glutMotionFunc
void glutMotionFunc(void (*func)(int x, int y))
Este evento detecta o movimento do mouse enquanto algum botão do mouse está
pressionado. Quando isto ocorre, o programa executa a rotina definida em void (*func)
e informa em x,y a posição do mouse na janela. No exemplo abaixo, a rotina
le_botao_movimento_mouse(int x, int y) imprime a posição do mouse enquanto
mantemos um de seus botões pressionados.

/* * * * * * * * * * * * */
/* Programa mouse01.cpp */
/* * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
void display()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glFlush();
}
void le_botao_movimento_mouse(int x, int y)
{
printf("Botao+movimento x = %d y = %d \n",x,y);
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Mouse");
glutDisplayFunc(display);
glutMotionFunc(le_botao_movimento_mouse);
glutMainLoop();
}

glutPassiveMotionFunc

void glutPassiveMotionFunc(void (*func)(int x, int y))


Este evento detecta o movimento do mouse quanto nenhum botão do mouse está
pressionado. Quando isto ocorre, o programa executa a rotina definida em void (*func)
e informa em x,y a posição do mouse na janela. No exemplo abaixo, a rotina

Robótica Teoria e Prática


Robótica Teoria e Prática

le_movimento_mouse(int x, int y) imprime a posição do mouse quando movimentamos


o mouse dentro da janela OpenGL.

/* * * * * * * * * * * * */
/* Programa mouse02.cpp */
/* * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
void display()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glFlush();
}
void le_movimento_mouse(int x, int y)
{
printf("Movimento x = %d y = %d \n",x,y);
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Mouse");
glutDisplayFunc(display);
glutPassiveMotionFunc(le_movimento_mouse);
glutMainLoop();
}

CURVAS PARAMÉTRICAS

Introdução

Considere uma curva C representando a trajetória de uma partícula P, de tal forma que a
posição P(x,y) da partícula é conhecida em cada instante de tempo t. Assim as
coordenadas x e y são conhecidas como funções da variável t de modo que:
x = x(t)
y = y(t)
Estas são as equações paramétricas da curva C e t é denominado parâmetro. Como
exemplo de curvas temos:
a) Circunferência de centro na origem e raio 1:
x = cos(t)
y = sen(t) onde 0 <= t <= 2*Pi
b) Ciclóide (curva traçada por um ponto da circunferência quando o círculo rola sobre
uma reta):
x = t - sen(t)
y = 1 - cos(t)

Exemplo: Visualização de Curvas Paramétricas

Robótica Teoria e Prática


Robótica Teoria e Prática

Vamos implementar um programa que visualize curvas paramétricas. Observe que a


diferença principal para o programa funções é que tanto a variável x, quanto y devem
ser calculadas em função do parâmetro t. Vamos aproveitar uma boa parte da estrutura
já implementada no programa função. O programa está dividido em dois módulos
principais:
- curvas010.cpp: Mantém as rotinas de visualização do OpenGL
- curvas011.cpp: Mantém as rotinas relativas ao desenho da curva.
Temos ainda o módulo:
- curvas011.h: Este módulo deve ter apenas o cabeçalho das funções do programa
curvas011.cpp.
Módulo curvas010.cpp

Este módulo é idêntico ao módulo funcao010.cpp. A única diferença é que as chamadas


são feitas para as novas funções de desenho das curvas.

/* * * * * * * * * * * * * */
/* Modulo: Curvas010.cpp */
/* * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "curvas011.h"
void display()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_eixo();
plota_curva();
glFlush();
}
void le_tecla(unsigned char key, int x, int y)
{
switch(key)
{
case 'D':
case 'd':
entra_dominio();
display();
break;
}
}
void le_botao_mouse(int b,int state,int x, int y)
{
switch(b) {
case GLUT_RIGHT_BUTTON:
switch(state) {
case GLUT_DOWN:
entra_dominio();
display();
Robótica Teoria e Prática
Robótica Teoria e Prática

break;
case GLUT_UP:
break;
}
break;
}
}
void main(int argc, char **argv)
{
22
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
glutDisplayFunc(display);
glutKeyboardFunc(le_tecla);
glutMouseFunc(le_botao_mouse);
glutMainLoop();
}

Módulo curvas011.cpp
Neste módulo implementamos o desenho do gráfico das curvas paramétricas. As
funções plota_eixo e entra_domínio não sofrem alterações.

/* * * * * * * * * * * * * */
/* Modulo: Curvas011.cpp */
/* * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
#define PI (4.0*atan(1.0))
float xmin = -1.0;
float ymin = -1.0;
float xmax = 1.0;
float ymax = 1.0;
float incremento = 0.01;
/* -------------------------------- */
void curva(float t,float *x,float *y)
/* float t (entrada) */
/* float *x (saida) */
/* float *y (saida) */
{
*x = cos(t);
*y = sin(t);
}
void plota_eixo()
{
glColor3f(0.0,1.0,0.0);

Robótica Teoria e Prática


Robótica Teoria e Prática

glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
}
void plota_curva()
{
float x,y,t;
glColor3f(1.0,0.0,0.0);
for(t=0;t < 2*PI; t+=incremento)
{
curva(t,&x,&y);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
}
}
void entra_dominio()
{
int pontos;
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Total de pontos =");
scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

Módulo curvas011.h

Float curva(float t,float *x,float *y);


Void plota_eixo();
Void plota_curva();
Void entra_dominio();

Exercício
Como exercício implemente:
1) Curva ciclóide (t assume qualquer valor real).
2) x(t) = 3*t*t, y(t)=4*t*t*t (t assume qualquer valor real).
3) x(t) = cos(2*t), y(t)= sin(2*t) (0 <= t <= 2*PI) (Qual a diferença para a curva do
programa ?)

Robótica Teoria e Prática


Robótica Teoria e Prática

4) x(t) = cos(t), y(t)= sin(2*t)


5) x(t) = 2 * cos(t), y(t)= 3 * sin(t) (0 <= t <= 2*PI) .
6) Como você poderia visualizar gráficos de funções em uma variável y = f(x) com este
programa
? Visualize y=x*x, y = sin(x), y = ln(x).

Curvas na forma Polar

Para formar as coordenadas polares considere um ponto fixo O, denominado origem (ou
polo) e um eixo partindo de O, denominado eixo polar. A cada ponto P do plano
podemos associar uma par de coordenadas polares (r,theta) onde:
r: distância orientada da origem ao ponto P.
theta: ângulo entre o eixo polar e o segmento OP.

As coordenadas polares podem ser relacionadas com as coordenadas retangulares (ou


cartesianas) através de expressões abaixo:

Como exemplo de curvas na forma polar temos:

a) Circunferência de centro na origem e raio 1:


r=1
b) Reta passando na origem com coeficiente angular m:

0=m

c) Circunferência com centro em P(0, 0.5) e raio 1:

r = sin0

d) Cardióide

r = a(1+ cos(0))

e) Espiral

r = a0

f) Rosácea

r = asen(n0 )

Visualização de Curvas Polares

Robótica Teoria e Prática


Robótica Teoria e Prática

Para visualizar as curvas polares, podemos utilizar o mesmo programa das curvas
paramétricas. Para isso, considere uma curva dada na forma polar:

r = f (0)

Em coordenadas cartesianas temos:

Substituindo r nas duas equações obtemos:

Assim temos uma curva na forma paramétrica. Como exemplo vamos visualizar a curva
do cardióide, alterando apenas a rotina curva do programa anterior:

/* -------------------------------- */
void curva(float t,float *x,float *y)
/* float t (entrada) */
/* float *x (saida) */
/* float *y (saida) */
/* -------------------------------- */
/* -------------------------------- */
{
*x = (1+cos(t))*cos(t);
*y = (1+cos(t))*sin(t);
}

Exercícios
1) Como exercício visualize as demais curvas dadas em coordenadas polares.
2) Visualize a curva dada em coordenadas polares por r = sec(theta).

RETAS E POLÍGONOS NO OPENGL


Retas e Polígonos

Além de pontos e retas, o OpenGL possui no total 10 tipos de primitivas úteis. Todos os
modelos da tabela abaixo devem ser utilizados iniciando com glBegin(...) e finalizando
com glEnd(...),
por exemplo para o GL_LINES temos:
glBegin(GL_LINES);
glVertex2f(1.0,1.0);
glVertex2f(1.0,2.0);
glVertex2f(2.0,-2.0);
...
glEnd();
GL_POINTS Pontos individuais.
GL_LINES Reta entre dois pontos.
GL_POLYGON Polígono convexo .
GL_TRIANGLES Tripla de vértices é interpretado como um

Robótica Teoria e Prática


Robótica Teoria e Prática

triângulo.
GL_QUADS Conjunto de quatro vértices interpretado como
quadrilátero.
GL_LINE_STRIP Sequência de retas.
GL_LINE_LOOP Idêntico ao anterior, porém com uma reta unindo o
primeiro e último vértice.
GL_TRIANGLE_STRIP Lista de triângulos.
GL_TRAINGLE_FAN Lista de triângulos com o primeiro vértice em
comum.
GL_QUAD_STRIP Lista de quadriláteros.

Exemplo: Visualização dos Métodos Numéricos de Integração

Como exemplo de aplicação dos novos objetos vamos visualizar alguns métodos
numéricos de integração: ponto à direita, ponto à esquerda e trapézio.

Nosso programa terá três módulos principais:


- Intvis01.cpp: Mantém as rotinas de visualização do OpenGL
Robótica Teoria e Prática
Robótica Teoria e Prática

- Intvis02.cpp: Mantém as rotinas relativas ao esboço do gráfico da função.


- Intvis03.cpp: Mantém as rotinas de visualização dos métodos numéricos de integração.
A seguir apresentamos o código de cada um destes módulos.

Módulo Intvis01.c

/* * * * * * * * * * * * * * */
/* Modulo: Intvis01.c */
/* * * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "Intvis02.h"
#include "Intvis03.h"
extern int tipo,visual;
void display()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_eixo();
plota_funcao();
plota_integral();
glFlush();
glutSwapBuffers();
}
void le_tecla(unsigned char key, int x, int y)
{
switch(key)
{
case 'D':
case 'd':
entra_dominio();
display();
break;
case 'I':
case 'i':
entra_limites();
display();
break;
case '0':
tipo = 0;
display();
break;
case '1':
tipo = 1;
display();
break;
}
}

Robótica Teoria e Prática


Robótica Teoria e Prática

void le_botao_mouse(int b,int state,int x, int y)


{
switch(b) {
case GLUT_RIGHT_BUTTON:
switch(state) {
case GLUT_DOWN:
visual = (visual + 1) % 2;
display();
break;
case GLUT_UP:
break;
}
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
glutDisplayFunc(display);
glutKeyboardFunc(le_tecla);
gluOrtho2D(-10.0,10.0,-10.0,10.0);
glutMouseFunc(le_botao_mouse);
glutMainLoop();
}

Módulo Intvis02.cpp
/* * * * * * * * * * * * * * */
/* Modulo: Intvis02.cpp */
/* * * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
float xmin = -10.0;
float ymin = -10.0;
float xmax = 10.0;
float ymax = 10.0;
float incremento = 0.01;
float funcao(float x)
{
return(sin(x));
}
void plota_eixo()
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
Robótica Teoria e Prática
Robótica Teoria e Prática

glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
}
void plota_funcao()
{
float x,y;
glColor3f(1.0,0.0,0.0);
for(x=xmin;x<xmax;x+=incremento)
{
y = funcao(x);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
}
}
void entra_dominio()
{
int pontos;
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Total de pontos =");
scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

Módulo Intvis03.cpp
Neste módulo separamos as rotinas que responsáveis pela visualização dos numéricos
métodos de integração.

/* * * * * * * * * * * * * * */
/* Modulo: Intvis03.cpp */
/* * * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include "Intvis02.h"
float a = 0;
float b = 1;
int tipo = 0;
int visual = 0;
int divisoes = 5;
Robótica Teoria e Prática
Robótica Teoria e Prática

void Integral_retangulo()
{
int i ;
float x,y;
float dx;
dx = (b-a)/divisoes;
for(i=0; i < divisoes; i++)
{
x = a+ i*dx;
y = funcao(x);
glColor3f(1.0,1.0,0.0);
if (visual == 0)
glBegin(GL_LINE_LOOP);
else
glBegin(GL_POLYGON);
glVertex2f(x,y);
glVertex2f(x+dx,y);
glVertex2f(x+dx,0);
glVertex2f(x,0);
glEnd();
}
}
void Integral_trapezio()
{
int i ;
float x,y1,y2;
float dx;
dx = (b-a)/divisoes;
for(i=0; i < divisoes; i++)
{
x = a+ i*dx;
y1 = funcao(x);
y2 = funcao(x + dx);
glColor3f(1.0,1.0,0.0);
if (visual == 0)
glBegin(GL_LINE_LOOP);
else
glBegin(GL_POLYGON);
31
glVertex2f(x,y1);
glVertex2f(x+dx,y2);
glVertex2f(x+dx,0);
glVertex2f(x,0);
glEnd();
}
}
void plota_integral()
{
switch(tipo) {
case 0:
Robótica Teoria e Prática
Robótica Teoria e Prática

Integral_retangulo();
break;
case 1:
Integral_trapezio();
break;
}
}
void entra_limites()
{
printf("Limites de Integracao \n");
printf("a = ");
scanf("%f",&a);
printf("\nb = ");
scanf("%f",&b);
printf("\ndivisoes = ");
scanf("%d",&divisoes);
}

Exemplo: Realizando Zoom do gráfico

No processo de visualização das funções, ou mesmo da integração numérica, muitas


vezes desejamos alterar o domínio do nosso gráfico. Para isso selecionamos a tecla “D”
e “d” como uma interrupção do teclado para que pudéssemos informar o novo domínio.
Uma forma mais ágil seria selecionar com o mouse interativamente um retângulo que
gostaríamos de visualizar. É o que faremos no próximo programa. Para isso
utilizaremos a função glutMotionFunc(funcao) para selecionarmos a região desejada.
Quando o botão direito do mouse é pressionado, marcamos o ponto inicial da região.
Enquanto o mouse está em movimento (com o botão direito pressionado), desenhamos o
retângulo desejado. Quando o botão do mouse é solto, obtemos o ponto final da região e
atualizamos o domínio da função. Vamos incorporar ao programa Funcao.cpp a nova
ferramenta de zoom.

/* * * * * * * * * * * * * * * * * */
/* Modulo: Funcao.cpp (com zoom) */
/* * * * * * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "plota.h"
int mov = 0; /* Detecta o movimento do mouse */
int xv1,xv2,yv1,yv2; /* Domínio da nova janela */
void redesenha()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_eixo();
plota_funcao();
if (mov == 1)
plota_retangulo(xv1,yv1,xv2,yv2);
glFlush();
Robótica Teoria e Prática
Robótica Teoria e Prática

glutSwapBuffers();
}
void le_botao_movimento_mouse(int x,int y)
{
xv2 = x;
yv2 = y;
redesenha();
}
void le_botao_mouse(int b,int state,int x,int y)
{
switch(b) {
case GLUT_LEFT_BUTTON:
switch(state) {
case GLUT_DOWN:
xv1 = x;
yv1 = y;
mov = 1;
break;
case GLUT_UP:
mov = 0;
xv2 = x;
yv2 = y;
recalcula_dominio(xv1,yv1,xv2,yv2);
redesenha();
break;
}
break;
}
}
void le_tecla(unsigned char key, int x, int y)
{
switch(key)
{
case 'D':
case 'd':
entra_dominio();
redesenha();
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Funcao");
glutDisplayFunc(redesenha);
glutKeyboardFunc(le_tecla);
glutMouseFunc(le_botao_mouse);
Robótica Teoria e Prática
Robótica Teoria e Prática

glutMotionFunc(le_botao_movimento_mouse);
glutMainLoop();
}
/* * * * * * * * * * * * * * * * */
/* Modulo: plota.cpp (com zoom) */
/* * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
#include "funcao.h"
#define PI 3.1415926535897932384626433832795
float xmin = -1.0;
float ymin = -1.0;
float xmax = 1.0;
float ymax = 1.0;
int pontos = 400;
/* -------------------------------- */
float funcao(float x)
/* -------------------------------- */
{
return(sin(50*PI*x));
}
/* -------------------------------- */
void plota_eixo()
/* -------------------------------- */
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
}
/* -------------------------------- */
void plota_funcao()
/* -------------------------------- */
{
int i ;
float dx ;
float x,y;
dx = (xmax - xmin)/pontos;
glColor3f(1.0,0.0,0.0);
x = xmin;
for(i=0;i<pontos;i++)
{
y = funcao(x);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
Robótica Teoria e Prática
Robótica Teoria e Prática

x = x + dx;
}
}
/* -------------------------------- */
void plota_retangulo(int x,int y,int xv1,int yv1)
/* -------------------------------- */
{
float t;
float retxmin,retxmax,retymin,retymax;
t = (float)xv1 / 400.0;
retxmin = xmin + t * (xmax-xmin);
t = (float)x / 400.0;
retxmax = xmin + t * (xmax-xmin);
t = (float)y / 400.0;
retymin = ymax - t * (ymax-ymin);
t = (float)yv1 / 400.0;
retymax = ymax - t * (ymax-ymin);
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINE_LOOP);
glVertex2f(retxmin,retymin);
glVertex2f(retxmin,retymax);
glVertex2f(retxmax,retymax);
glVertex2f(retxmax,retymin);
glEnd();
}
/* -------------------------------- */
void entra_dominio()
/* -------------------------------- */
{
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Total de pontos =");
scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
}
/* --------------------------------------------------------------- */
void recalcula_dominio(float xv_1,float yv_1,float xv_2,float yv_2)
/* --------------------------------------------------------------- */
{
float t;
float xmin1,xmax1;
float ymin1,ymax1;
t = (float)xv_1 / 400;
Robótica Teoria e Prática
Robótica Teoria e Prática

xmin1 = xmin + t * (xmax-xmin);


t = (float)xv_2 / 400;
xmax1 = xmin + t * (xmax-xmin);
xmin = xmin1;
xmax = xmax1;
t = (float)yv_2 / 400;
ymin1 = ymax - t * (ymax-ymin);
t = (float)yv_1 / 400;
ymax1 = ymax - t * (ymax-ymin);
ymin = ymin1;
ymax = ymax1;
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
redesenha();
}

CURVAS IMPLÍCITAS

Introdução
Já aprendemos na seção 3 como representar curvas na forma paramétrica. Vamos
discutir agora outro tipo de representação muito utilizada para curvas: a representação
implícita. A equação implícita de uma curva descreve uma relação entre as coordenadas
x e y dos pontos que pertencem a curva. Assim no plano xy a equação implícita de uma
curva tem a forma :

f (x, y) = 0

Como exemplo a representação implícita de uma circunferência de raio 1 centrado na


origem é dado por:

Na forma paramétrica a mesma curva é representada por:

Qual das duas representações é mais vantajosa em termos computacionais ? Na verdade


ambas representações têm vantagens e desvantagens em comparação uma com a outra.
Por exemplo, é muito simples determinar se um ponto ( , ) 0 0 P x y dado pertence ou
não a uma curva dada na forma implícita. Já na forma paramétrica é simples determinar
pontos que pertençam a curva, para que se possa fazer uma representação gráfica da
curva (como foi feito na seção anterior). Vamos agora resolver este último problema
para uma curva dada na forma implícita, ou seja, vamos representar graficamente a
curva implícita.

Visualização de Curvas Implícitas

Vamos implementar um programa que visualize curvas implícitas. Partindo por


exemplo da equação:

Robótica Teoria e Prática


Robótica Teoria e Prática

Observe que não é simples exibir um conjunto de pontos que pertençam a esta curva.
Vamos definir uma função de duas variáveis z = f (x, y) utilizando a equação acima, da
seguinte forma:

Assim a curva inicial desejada, será a curva de nível f (x, y) = 0 .


A estratégia para obter esta curva será a seguinte:
- Vamos estabelecer um domínio [−2,2]×[−2,2] no plano como partida (a priori não
sabemos se existem ou não pontos da curva nesse domínio).
- Em seguida discretizamos este domínio, determinando uma matriz de 10x10 pontos
por exemplo.
- A cada três pontos, definimos um triângulo como na figura abaixo.

- Para cada ponto calculamos .


- Para cada triângulo, observamos os sinais obtidos em cada vértice e
temos as seguintes situações:

- Se V1 * V2 < 0, então a função se anula em um ponto entre V1 e V2. Este ponto pode
ser
aproximado linearmente.
- Se V1 * V3 < 0, então a função se anula em um ponto entre V1 e V3.
- Se V2 * V3 < 0, então a função se anula em um ponto entre V2 e V3.
- Se V1 = 0, então a função se anula exatamente sobre o vértice V1.
- Se V2 = 0, então a função se anula exatamente sobre o vértice V2.
- Se V3 = 0, então a função se anula exatamente sobre o vértice V3.
- Considerando que exatamente duas das condições acima se verificaram
simultaneamente, aproximamos a curva nesse triângulo por um segmento de reta unindo
os dois pontos obtidos.

Programa Curva Implícita

O programa está dividido em dois módulos principais:


- impl010.cpp: Mantém as rotinas de visualização do OpenGL
- impl011.cpp: Mantém as rotinas relativas ao desenho da curva.

Temos ainda o módulo:


- impl011.h: Este módulo deve ter apenas a declaração das funções do programa
impl011.cpp.
Módulo impl010.cpp
Este módulo é idêntico ao módulo funcao010.cpp. A única diferença é que as chamadas
são feitas para as novas funções de desenho das curvas.

/* * * * * * * * * * * * * */

Robótica Teoria e Prática


Robótica Teoria e Prática

/* Modulo: impl010.cpp */
/* * * * * * * * * * * * * */
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "impl011.h"
extern float xmin,xmax,ymin,ymax;
void display()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_eixo();
plota_curva_implicita();
glFlush();
glutSwapBuffers();
}
void le_tecla(unsigned char key, int x, int y)
{
switch(key)
{
case 'D':
case 'd':
entra_dominio();
display();
break;
}
}
void le_botao_mouse(int b,int state,int x, int y)
{
switch(b) {
case GLUT_RIGHT_BUTTON:
switch(state) {
case GLUT_DOWN:
break;
case GLUT_UP:
printf(" x = %d y = %d \n",x,y);
break;
}
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400,400);
glutInitWindowPosition(50,50);
glutCreateWindow("Ponto");
glutDisplayFunc(display);
gluOrtho2D(xmin,xmax,ymin,ymax);
Robótica Teoria e Prática
Robótica Teoria e Prática

glutKeyboardFunc(le_tecla);
glutMouseFunc(le_botao_mouse);
glutMainLoop();
}

Módulo impl011.cpp
Neste módulo implementamos o desenho do gráfico das curvas implícitas. As funções
plota_eixo e entra_domínio não sofrem alterações.

/* * * * * * * * * * * * * */
/* Modulo: impl011.cpp */
/* * * * * * * * * * * * * */
#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
float xmin = -2.0;
float ymin = -2.0;
float xmax = 2.0;
float ymax = 2.0;
float incremento = 0.1;
float funcao(float x,float y)
{
return(sqrt(x*x+y*y)-((x*x-y*y)/(x*x+y*y))+sin(x*y));
}
void plota_eixo()
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
}
void triangulo(float x1,float y1,float x2,float y2,float x3,float y3)
{
int i = 0;
float t;
float x[3],y[3];
float s1,s2,s3;
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINE_LOOP);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glVertex2f(x3,y3);
glEnd();
s1 = funcao(x1,y1);
s2 = funcao(x2,y2);
s3 = funcao(x3,y3);
if ((s1 * s2) < 0) {
Robótica Teoria e Prática
Robótica Teoria e Prática

t = -s1/(s2-s1);
x[i] = x1 + t * (x2-x1);
y[i] = y1;
i++;
}
if ((s1 * s3) < 0) {
t = -s1/(s3-s1);
x[i] = x1 ;
y[i] = y1 + t * (y3-y1);
i++;
}
if ((s2 * s3) < 0) {
t = -s2/(s3-s2);
x[i] = x2 + t * (x3-x2);
y[i] = y2 + t * (y3-y2);
i++;
}
if (s1 == 0) {
x[i] = x1;
y[i] = y1;
i++;
}
if (s2 == 0) {
x[i] = x2;
y[i] = y2;
i++;
}
if (s3 == 0) {
x[i] = x3;
y[i] = y3;
39
i++;
}
if (i == 2) {
glLineWidth(2.0);
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINES);
glVertex2f(x[0],y[0]);
glVertex2f(x[1],y[1]);
glEnd();
glLineWidth(1.0);
}
}
void plota_curva_implicita()
{
float x,y;
glColor3f(1.0,0.0,0.0);
for(x=xmin;x<xmax;x+=incremento)
{
for(y=ymin;y<ymax;y+=incremento)
Robótica Teoria e Prática
Robótica Teoria e Prática

{
triangulo(x,y,x+incremento,y,x,y+incremento);
triangulo(x+incremento,y+incremento,x,y+incremento,x+incremento,y);
}
}
}
void entra_dominio()
{
int pontos;
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Divisoes =");
scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

Módulo impl011.h
void plota_eixo();
void plota_curva_implicita();
void entra_dominio();

FRACTAIS

Conjuntos auto semelhantes

Definição: Um subconjunto fechado e limitado , é dito ser auto-semelhante se


pode ser expresso na forma:

Onde são conjuntos não sobrepostos e cada um deles é congruente a


S por mesmo fator de escala s ( 0 < s < 1).

Exemplo 1: Um triângulo pode ser expresso como a união de quatro triângulos


congruentes e não sobrepostos. Cada um dos triângulos é congruente ao original por um

fator e o triângulo é um conjunto auto-semelhante com k = 4.

Robótica Teoria e Prática


Robótica Teoria e Prática

Exemplo 2 (Triângulo de Sierpinski) : Este exemplo foi apresentado pelo matemático


Waclaw Sierpinski (1882-1969). Neste exemplo, partindo de um triângulo, temos a
união de três triângulos não sobrepostos (portanto k = 3), cada um dos quais é
congruente ao original com um fator de escala . Em seguida, o processo se repete
para cada um dos três triângulos, e assim sucessivamente.

Dimensão Hausdorff e o conceito de fractal

Definição: A dimensão Hausdorff de um conjunto auto-semelhante é definido por:

Robótica Teoria e Prática


Robótica Teoria e Prática

Observe que no exemplo 1, a dimensão Hausdorff, coincide com a dimensão topológica


usual, uma vez que uma região em tem dimensão 2. Porém no exemplo 2,
obtemos uma dimensão não inteira para o triângulo de Sierpinski. Partindo desta
observação, Mandelbrot sugeriu em 1977 a seguinte definição:
Um fractal é um subconjunto do espaço euclidiano cuja dimensão Hausdorff é diferente
da dimensão topológica.

Exemplos de fractais
Alguns dos principais exemplos que apresentaremos nesta seção foram gerados
utilizando composição de transformações de rotação e escala seguido de uma possível
translação. O formato geral da função é dado por:

Triângulo de Sierpinski
Para obter o triângulo de Sierpinski, utilizaremos uma aplicação que a partir de um
triângulo, obtém três novos triângulos conforme a figura abaixo:

Robótica Teoria e Prática


Robótica Teoria e Prática

O programa está dividido em dois módulos principais:


- frac010.cpp: Mantém as rotinas de visualização do OpenGL
- frac011.cpp: Mantém as rotinas relativas a implementação do triângulo de Sierpinski.
Temos ainda o módulo:
- frac011.h: Este módulo deve ter apenas a declaração das funções do programa
frac011.cpp.

Módulo frac010.cpp
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include "fract011.h"
extern float xmax,xmin,ymax,ymin;
extern float incremento;
extern int pontos;
int xp[2],yp[2];
int tamx = 400;
int tamy = 400;
int st = -1;
void display()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_funcao(0.0,0.0,1.0,0.0,0.0,1.0,6);
glFlush();
glutSwapBuffers();
}
void le_tecla(unsigned char key, int x, int y)
{
switch(key)
{
case 'I':
case 'i':
entra_dominio();
break;
}
}
void botao_mouse(int b,int state,int x, int y)
{

Robótica Teoria e Prática


Robótica Teoria e Prática

float t;
float xmin1,xmax1,ymin1,ymax1;
switch(b) {
case GLUT_LEFT_BUTTON:
switch(state) {
case GLUT_DOWN:
xp[0] = x;
yp[0] = y;
st = 0;
printf("down %d %d ",x,y);
break;
case GLUT_UP:
xp[1] = x;
yp[1] = y;
printf("up %d %d ",x,y);
t = (float)xp[0] / tamx;
xmin1 = xmin + t * (xmax-xmin);
t = (float)xp[1] / tamx;
xmax1 = xmin + t * (xmax-xmin);
xmin = xmin1;
xmax = xmax1;
t = (float)yp[1] / tamy;
ymin1 = ymax - t * (ymax-ymin);
t = (float)yp[0] / tamy;
ymax1 = ymax - t * (ymax-ymin);
ymin = ymin1;
ymax = ymax1;
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
display();
break;
}
break;
}
}
void mov_mouse(int x, int y)
{
float t;
float xmin1,xmax1,ymin1,ymax1;
t = (float)xp[0] / tamx;
xmin1 = xmin + t * (xmax-xmin);
t = (float)x / tamx;
xmax1 = xmin + t * (xmax-xmin);
t = (float)y / tamy;
ymin1 = ymax - t * (ymax-ymin);
t = (float)yp[0] / tamy;
ymax1 = ymax - t * (ymax-ymin);
display();
glDrawBuffer(GL_FRONT);
Robótica Teoria e Prática
Robótica Teoria e Prática

glColor3f(1.0,1.0,1.0);
glBegin(GL_LINE_STRIP);
glVertex2f(xmin1,ymin1);
glVertex2f(xmin1,ymax1);
glVertex2f(xmax1,ymax1);
glVertex2f(xmax1,ymin1);
glVertex2f(xmin1,ymin1);
glEnd();
glDrawBuffer(GL_BACK);
glFlush();
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(tamx,tamy);
glutInitWindowPosition(50,50);
glutCreateWindow("Funcao");
glutDisplayFunc(display);
gluOrtho2D(xmin,xmax,ymin,ymax);
glutKeyboardFunc(le_tecla);
glutMouseFunc(botao_mouse);
glutMotionFunc(mov_mouse);
glutMainLoop();
}

Módulo frac011.cpp

#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
float xmin = -2;
float ymin = -2;
float xmax = 2;
float ymax = 2;
float incremento = 0.01;
int pontos = 1000;
void funcao(float *x,float *y,float e,float f)
{
*x = *x/2 + e;
*y = *y/2 + f;
}
void plota_eixo()
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
Robótica Teoria e Prática
Robótica Teoria e Prática

glVertex2f(0,ymax);
glEnd();
}
void plota_funcao(float x0,float y0,
float x1,float y1,
float x2,float y2,
int n)
{
int i,j;
float x[3][3],y[3][3];
float e[3] = {0.0, 0.5, 0.0};
float f[3] = {0.0, 0.0, 0.5};
for(i=0;i<3;i++) {
x[i][0] = x0;
y[i][0] = y0;
x[i][1] = x1;
y[i][1] = y1;
x[i][2] = x2;
y[i][2] = y2;
}
for(i=0;i<3;i++)
for (j=0;j<3;j++)
funcao(&(x[j][i]),&(y[j][i]),e[j],f[j]);
if (n == 0) {
for (i=0;i<3;i++) {
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex2f(x[i][0],y[i][0]);
glVertex2f(x[i][1],y[i][1]);
glVertex2f(x[i][2],y[i][2]);
glEnd();
}
return;
}
else {
for(i=0;i<3;i++)
plota_funcao(x[i][0],y[i][0],x[i][1],y[i][1],
x[i][2],y[i][2],n-1);
}
}
void entra_dominio()
{
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
Robótica Teoria e Prática
Robótica Teoria e Prática

printf("\n Total de pontos =");


scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

Módulo frac011.h
void funcao(float *x,float *y,float e,float f);
void plota_eixo();
void plota_funcao(float x0,float y0,float x1,float y1,
float x2,float y2,int n);
void entra_dominio();

Triângulo de Sierpinski utilizando Monte Carlo


Este método utiliza iterações randômicas para gerar fractais utilizando o seguinte
processo:
1 - Defina as k transformações T k que descrevem o objeto a ser gerado.

2- Escolha um ponto arbitrário

3- Escolha arbitrariamente uma das k transformações e aplique no ponto escolhido:

4- Prossiga escolhendo aleatoriamente uma das k transformações e aplique no ultimo


ponto obtido:

O programa proposto está dividido em dois módulos principais:


- frac020.cpp: Mantém as rotinas de visualização do OpenGL
- frac021.cpp: Mantém as rotinas relativas a implementação do triângulo de
Sierpinski.
Temos ainda o módulo:
- frac021.h: Este módulo deve ter apenas a declaração das funções do programa
frac021.cpp.
Módulo frac020.cpp
Este módulo é idêntico ao módulo frac010.cpp, com apenas duas linhas de alteração
como descrito abaixo:

…….
#include <math.h>
#include "fract021.h"
........

Robótica Teoria e Prática


Robótica Teoria e Prática

void display()
{
........
plota_funcao(1.5,-1.8);
........
}
.........

Módulo frac021.cpp

/* * * * * * * * * * * * * * * * * **/
/* Triangulo Sierpinski Monte Carlo */
/* fract021.cpp */
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <gl\glut.h>
float xmin = -2;
float ymin = -2;
float xmax = 2;
float ymax = 2;
float incremento = 0.01;
int pontos = 1000;
void funcao(float *x,float *y,float e,float f)
{
*x = *x/2 + e;
*y = *y/2 + f;
}
void plota_eixo()
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
}
void plota_funcao(float x0,float y0)
{
int i,j;
float x[3][4],y[3][4];
float e[3] = {0.0, 0.5, 0.0};
float f[3] = {0.0, 0.0, 0.5};
srand( (unsigned)time( NULL ) );
for(i=0;i<20000;i++) {
j = (int) (3.0 * ((float)rand())/ RAND_MAX);
j = ( j > 2) ? 2 : j;
funcao(&x0,&y0,e[j],f[j]);
glColor3f(1.0,0.0,0.0);
Robótica Teoria e Prática
Robótica Teoria e Prática

glBegin(GL_POINTS);
glVertex2f(x0,y0);
glEnd();
}
}
void entra_dominio()
{
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Total de pontos =");
scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

utilizando Monte Carlo


- Módulo frac030.cpp

…………
#include "fract031.h"
…………………
void display()
{
int i;
float x[4] = {0.0,1.0,1.0,0.0};
float y[4] = {0.0,0.0,1.0,1.0};
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_funcao(x,y,8);
glFlush();
}
....................

Módulo frac031.cpp
/* * * * * * * * * * * */
/* Fractal Fern */
/* fract031.cpp */
#include <stdio.h>
#include <math.h>
#include <gl\glut.h>
float xmin = -0.2;
float ymin = -0.2;
float xmax = 2;

Robótica Teoria e Prática


Robótica Teoria e Prática

float ymax = 2;
float incremento = 0.01;
int pontos = 1000;
void T(float a11,float a12,float a21,float a22,float e,float f,float
*x1,float *y1)
{
float xx;
float yy;
49
xx = a11 * *x1 + a12 * *y1 + e;
yy = a21 * *x1 + a22 * *y1 + f;
*x1 = xx;
*y1 = yy;
}
void plota_funcao(float *x,float *y,int n)
{
int i,j;
float xx[4][4],yy[4][4];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
xx[i][j] = x[j];
yy[i][j] = y[j];
}
if (n == 0) {
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINE_LOOP);
glVertex2f(x[0],y[0]);
glVertex2f(x[1],y[1]);
glVertex2f(x[2],y[2]);
glVertex2f(x[3],y[3]);
glEnd();
return;
}
else {
for(i=0;i<4;i++) {
T( 0.20,-0.26, 0.23, 0.22,0.400,
0.045,&(xx[0][i]),&(yy[0][i]));
T( 0.85, 0.04,-0.04, 0.85,0.075,
0.180,&(xx[1][i]),&(yy[1][i]));
T( 0.00, 0.00, 0.00, 0.16,0.500,
0.000,&(xx[2][i]),&(yy[2][i]));
T(-0.15, 0.28, 0.26, 0.24,0.575,-
0.086,&(xx[3][i]),&(yy[3][i]));
}
plota_funcao(xx[0],yy[0],n-1);
plota_funcao(xx[1],yy[1],n-1);
plota_funcao(xx[2],yy[2],n-1);
plota_funcao(xx[3],yy[3],n-1);
}
Robótica Teoria e Prática
Robótica Teoria e Prática

}
void entra_dominio()
{
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Total de pontos =");
scanf("%d",&pontos);
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

Curva de Koch
Módulo frac040.cpp
#include <gl\glut.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include "fract041.h"
extern float xmax,xmin,ymax,ymin;
extern float incremento;
extern int pontos;
int xp[2],yp[2];
int tamx = 400;
int tamy = 400;
int st = -1;
void display()
{
int i;
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_eixo();
for(i=0;i<7;i++) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
plota_funcao(-1.0,1.0,1.0,1.0,i);
plota_funcao( 1.0,1.0,0.0,-1.0,i);
plota_funcao(0.0,-1.0,-1.0,1.0,i);
glFlush();
glutSwapBuffers();
getch();
}
glFlush();
glutSwapBuffers();
}
Robótica Teoria e Prática
Robótica Teoria e Prática

void le_tecla(unsigned char key, int x, int y)


{
switch(key)
{
case 'I':
case 'i':
entra_dominio();
break;
}
}
void botao_mouse(int b,int state,int x, int y)
{
float t;
float xmin1,xmax1,ymin1,ymax1;
switch(b) {
case GLUT_LEFT_BUTTON:
switch(state) {
case GLUT_DOWN:
xp[0] = x;
yp[0] = y;
st = 0;
printf("down %d %d ",x,y);
break;
case GLUT_UP:
xp[1] = x;
yp[1] = y;
printf("up %d %d ",x,y);
t = (float)xp[0] / tamx;
xmin1 = xmin + t * (xmax-xmin);
t = (float)xp[1] / tamx;
xmax1 = xmin + t * (xmax-xmin);
xmin = xmin1;
xmax = xmax1;
t = (float)yp[1] / tamy;
ymin1 = ymax - t * (ymax-ymin);
t = (float)yp[0] / tamy;
ymax1 = ymax - t * (ymax-ymin);
ymin = ymin1;
ymax = ymax1;
glLoadIdentity();
gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
display();
break;
}
break;
}
}
void mov_mouse(int x, int y)
{
Robótica Teoria e Prática
Robótica Teoria e Prática

float t;
float xmin1,xmax1,ymin1,ymax1;
t = (float)xp[0] / tamx;
xmin1 = xmin + t * (xmax-xmin);
t = (float)x / tamx;
xmax1 = xmin + t * (xmax-xmin);
t = (float)y / tamy;
ymin1 = ymax - t * (ymax-ymin);
t = (float)yp[0] / tamy;
ymax1 = ymax - t * (ymax-ymin);
display();
glDrawBuffer(GL_FRONT);
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINE_STRIP);
glVertex2f(xmin1,ymin1);
glVertex2f(xmin1,ymax1);
glVertex2f(xmax1,ymax1);
glVertex2f(xmax1,ymin1);
glVertex2f(xmin1,ymin1);
glEnd();
glDrawBuffer(GL_BACK);
glFlush();
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(tamx,tamy);
glutInitWindowPosition(50,50);
glutCreateWindow("Funcao");
glutDisplayFunc(display);
gluOrtho2D(xmin,xmax,ymin,ymax);
glutKeyboardFunc(le_tecla);
glutMouseFunc(botao_mouse);
glutMotionFunc(mov_mouse);
glutMainLoop();
}

Módulo frac041.cpp
/* * * * * * * * * * * */
/* Fractal Curva Koch */
/* fract041.cpp */
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <gl\glut.h>
float xmin = -2;
float ymin = -2;
float xmax = 2;
float ymax = 2;
Robótica Teoria e Prática
Robótica Teoria e Prática

float incremento = 0.01;


int pontos = 1000;
void plota_eixo()
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(xmin,0);
glVertex2f(xmax,0);
glVertex2f(0,ymin);
glVertex2f(0,ymax);
glEnd();
}
void plota_funcao(float x0,float y0,float x1,float y1,int n)
{
int i,j;
float v[2];
float xx0,yy0,xx1,yy1;
xx0 = x0+1.0/3*(x1 - x0);
yy0 = y0+1.0/3*(y1 - y0);
xx1 = x0+2.0/3*(x1 - x0);
yy1 = y0+2.0/3*(y1 - y0);
if (n == 0) {
glColor3f(1.0,1.0,0.0);
glBegin(GL_LINES);
glVertex2f(x0,y0);
glVertex2f(x1,y1);
glEnd();
}
else {
v[0]=(y0-y1)/(2*sqrt(3.0));
v[1]=(x1-x0)/(2*sqrt(3.0));
plota_funcao(x0,y0,xx0,yy0,n-1);
plota_funcao(xx0,yy0,(x0+x1)/2.0+v[0],(y0+y1)/2.0+v[1],n-1);
plota_funcao((x0+x1)/2.0+v[0],(y0+y1)/2.0+v[1],xx1,yy1,n-1);
plota_funcao(xx1,yy1,x1,y1,n-1);
}
}
void entra_dominio()
{
printf("xmin = ");
scanf("%f",&xmin);
printf("\nymin = ");
scanf("%f",&ymin);
printf("\nxmax = ");
scanf("%f",&xmax);
printf("\nymax = ");
scanf("%f",&ymax);
printf("\n Total de pontos =");
scanf("%d",&pontos);
glLoadIdentity();
Robótica Teoria e Prática
Robótica Teoria e Prática

gluOrtho2D(xmin,xmax,ymin,ymax);
incremento = fabs(xmax-xmin)/pontos;
}

Bibliografia:
Estrato de aulas do curso de Mecatrônica da Escola Politécnica de Minas Gerais
POLIMIG – Matéria Robótica Industrial Prof. Orlando Laoboissier

Mecatrônica uma abordagem Multidisciplinar: W. Bolton 4 Edição

Princípios de Mecatrônica: João Maurício Rosário

Apostila Robótica Universidade Braz Cubas: Carrara, Valdemir

Technology in Action Intermediate Robot Building Segund Edition: David Cook

Sites:

www.robotrom.com
www.nasa.gov
www.bionix.com
www.rogeriodumba.com.br

Robótica Teoria e Prática

Você também pode gostar