Tecnologías de la Fabricación Digital – Escaneo 3D en dispositivos Móviles

Nuevos tiempos y nuevas formas de fabricar, con el tiempo pensar en una fabricación personalizada es cada vez menos descabellado, ya no hablamos de la segmentación y producción por perfiles agrupando a los usuarios por edad, ingresos, etc; sino por el conjunto de atributos que lo definen como tal y único y en consecuencia la serie de elecciones y transformaciones que puede realizar entre ellos los productos que pueda fabricar; a la corriente cultural que acercan al usuario a crear sus propios productos se ha denominado  cultura Maker, que es el símil en terrenos del hardware a lo que significó la apertura hacia el software libre en los terrenos de la informática, esta cultura maker se ha hecho tangible a través de la reducción del costo de adquisición de máquinas, acceso al conocimiento a su creación y a la fabricación de productos, dentro de las técnicas de fabricación, existe un conjunto de herramientas que se denominan fabricación digital, este tipo de fabricación tiene como flujo:

Átomos - Bits - Átomos

¿Qué es lo que muestra este flujo?, pues  que la fabricación de un producto puede darse desde el modelado del mismo a partir de la abstracción o la captura de un objeto físico ya existente, el primero es el diseño digital tal y como lo conocemos y que existen infinidad de programas para lograrlo, el segundo si bien es cierto tiene algo de tiempo en la escena tecnológica pero no ha sido muy popularizado, su principal representante es el escáner 3D   el cual por los altos costos que representó su adquisición no ayudó mucho a su difusión; sin embargo, con las mejoras de procesamiento y captura de imágenes (cámaras) de los teléfonos móviles, se abrió una posibilidad de acercar al usuario al escaneo 3D, así que en esta ocasión abordaremos las aplicaciones que nos permiten escanear objetos con nuestro teléfono móvil; ¿Qué deben tener en común las aplicaciones de escáner 3D? pues que puedan exportarse a un fichero STL que es el formato común entre diversas impresoras 3D y que además puede (no es obligatorio) permitir la manipulación en programas CAD, entonces empecemos:

Scann3D

unnamed

Es de descarga gratuita y solicita que te identifiques con tu cuenta de google, solicita acceso a la carpeta de fotos e imágenes ya que ha de hacer uso del espacio en memoria que dispongas, incluso te recomiendan que te hagas con espacio al usarlo. Los comentarios en la google play no son nada positivos, esto es quizá porque se espera mucho de una aplicación que de por sí se tiene que adaptar a todo tipo de arquitectura que compongan tu teléfono móvil, aunque hay que tomarlos un poco en cuenta. Su menú principal tiene 3 opciones:

  • Nuevo Modelo: Apertura indicaciones de como tomar las imágenes (tomar en cuenta mucho el tema de la luz, y eso aplica como norma incluso para los de tipo profesional), e incluso tiene un guía en tiempo real para la toma de imágenes.
  • Mis Modelos: Si en caso haz decidido guardar alguno de los modelos
  • Continuar (si ya estuviste realizando uno).

Al finalizar la secuencia de fotos, tienes la posibilidad de obtener tu modelo con todos los detalles o simplemente la básica, esta última es gratuita y las demás implican un coste de suscripción (versión PRO), de forma similar ofrece la posibilidad de exportar el modelo en el formato STL.

Nota Personal: Realicé pruebas con él en Huawei Mate 10 PRO, en la noche pero con fuerte iluminación, hice dos pruebas y no salieron como esperaba, hice pruebas en el día, y tampoco obtuve los resultados esperados, quizá sea sesgado pero puede que funcione solo con objetos grandes.

Qlone 3D Scanning & AR Solutions

qlone.png

Es otra de las aplicaciones populares, al igual que populares resultan las opiniones positivas y negativas en el centro de descarga, pero al menos hay opiniones positivas; sin embargo, aunque no es preponderante las opiniones nos sirven para darnos una idea de la adaptabilidad del software a las diversas arquitecturas que presentan los teléfonos móviles. El programa es de descarga gratuita, pide acceso a tu cámara mas no a tu memoria, así también te da indicaciones para la impresión de la hoja patrón de la cual hacen uso, esta hoja patrón puede ser redimensionada en función del tamaño del objeto que haz de escanear lo cual, definitivamente te da una idea que no es muy ideal para el escaneo de monumentos en plazas, por ejemplo. Aquí les dejo un vídeo de las impresiones con esta aplicación:

Nota Personal: Sinceramente lo restrictivo es la hoja de impresión para el registro del escaneo, lo que limita las dimensiones del objeto a escanear.

NOTA PERSONAL GENERAL

Las pruebas se realizaron en un Huawei Mate 10 PRO, y al menos en Android no funcionan de forma correcta las aplicaciones para escanear, he leído que en dispositivos Apple hay mejores resultados, esto dado porque la arquitectura está totalmente definida, lo que hace que ya no te preocupes de la versatilidad del software, lastimosamente no se pudo realizar pruebas al respecto al no tener un dispositivo de dicha marca.

¿Cuál es el principio en común?

El principio en común en muchas de las aplicaciones es la fotogrametría, así que me puse a revisar las diversas técnicas que implican su uso encontrando un vídeo muy explicativo de como realizar tu propio escaneo:

 

¿Cómo se hace en Perú? – o Al menos en algunos lados

Como tema experimental en Perú existen cursos que dentro de sus tópicos incluyen el desarrollo de asignaciones con el escaneo en 3 dimensiones, este curso se denomina fabacademy y es ofrecido por algunas universidades en Perú y en Latinoamérica.

 

 

Anuncios

Programación Dinámica Determinística – Investigación de Operaciones

Anteriormente:

Programación Dinámica

Ya hemos revisado las bases de la programación dinámica, una técnica empleada dentro de la ingeniería industrial para la optimización de procesos. Ahora vamos revisar la programación dinámica determinística, que se centra en los problemas que el estado de la siguiente etapa está determinado por completo por el estado y la política de la etapa actual. La programación determinística se puede describir por el siguiente gráfica:

pd_13

Siendo esto el único factor diferencial, todo el proceso y características posteriores se cumplen, entonces veamos algunos ejemplos de su aplicación para entender  bien su entendimiento.

AGENCIA DE PUBLICIDAD

Una agencia de publicidad está llevando a cabo una campaña de publicidad de una semana para una tienda local. La agencia ha determinado que es posible que la campaña más efectiva pudiera incluir la colocación de anuncios en cuatro medios. Un periódico diario, un periódico dominical, radio y televisión. Se tiene disponible $ 8,000 para esta campaña y la agencia le gustaría distribuir esa cantidad en incrementos de $1,000 en todos los medios, de manera que se maximice el índice de exposición a la publicidad. Investigaciones llevadas a cabo por la agencia permiten obtener las siguientes estimaciones de la exposición por cada $1,000 de gasto en cada uno de los medios.

pd_14

Determine cuánto debe invertir la agencia en cada uno de los medios para maximizar la exposición de los anuncios.

Resolución

Vemos que no se menciona de forma explícita las etapas, para ello debemos de ponernos a meditar sobre la toma decisión que ha de ocurrir, podemos decir que si empezamos de arriba hacia abajo en la tabla que se ha presentado, podríamos decir que nuestro estado inicial es S1=$8000 y tomaremos una decisión X1 que sería el valor de la inversión en uno de los medios informativos tal que nos lleve al  siguiente estado (el siguiente medio informativo) y en el siguiente estado tendremos S2=8000-X1, y así sucesivamente S3=S2-X2 tal que al final quedemos con 0, observemos la situación determinística que dicta que el estado n+1 está determinado enteramente por el estado anterior y su contribución , ahora bien bajo esto podríamos decir que los medios informativos son las etapas, ya que en ellos se concentran las tomas de decisiones, podemos entonces realizar la siguiente tabla:

pd_15.png

Sí cada etapa es cada medio informativo, observemos lo que sucede en la etapa 1; en la etapa 1 podemos elegir, invertir 0 a 8, no sabemos cuánto pero sabemos que esas son los valores posibles:

pd_16

Si encontramos una razón a ello podemos decir, sea:

  • Sea n el número de estados que es 4.
  • Sn: La cantidad actual para invertir en la etapa n
  • xn: La cantidad actual que se invertirá en la etapa n tal que xn ={0,1,2,3,4,5,6,7,8}
  • Sn+1: La cantidad restante de inversión en la etapa n+1.
  • Csn,sn+1: la contribución inmediata de ir de n a n+1.

Entonces:

Sn+1=Sn-Xn

Con estos datos podemos buscar la relación recursiva; nuestro objetivo es obtener la maximización de exposición en los medios, entonces en cada etapa se ha evaluado y obtenido un gn+1(Sn+1), entonces podemos decir que la maximización de exposición (Gmax) es:

Gmax=C(Sn,Sn+1)+gn+1(Sn+1) equivalente a C(Sn,Sn+1)+gn+1(Sn-Xn)

Entonces en la etapa 1, sea S1=8, si invertimos los 8 el cual es nuestro X1  en la etapa 1 nos quedamos con 0 el cual es nuestro Sn+1.Y la contribución de invertir esos 8 en la etapa 1 es  C(Sn,Sn+1)=82, según dato en tabla.Esto ocurre de forma similar con los otros posibles estados. Bajo esa misma lógica creamos los demás estados y etapas.

pd_17.png

Obtenemos una red de la forma en que se muestra, expliquemos un poco que es lo que está sucediendo:

pd_18

En la primera etapa el esfuerzo de invertir 6 trae como resultado 80 y me quedo con 2 que es el estado inicial para la etapa 2, luego yo puedo decidir invertir esos 2 en la etapa 2 y me quedaría con 0, el resultado de invertir 2 en la segunda etapa es 55, o podría solo invertir 1 y el resultado de invertir 1 es 15 en la segunda etapa o no podría invertir nada, quedándome con 2 y el resultado de no invertir nada es 0, no puedo invertir 3 ya que no poseo dicha cantidad, siguiendo esa misma lógica es que se ha desplegado toda la red. En la última etapa sea lo que quede se va a distribuir, entonces el último estado será de valor 0, con todo esto descrito pasamos a las tablas:

Etapa 4 (Televisión):

pd_19

Etapa 3 (Radio):

pd_20

 

Etapa 2 (Periódico dominical:

pd_21

Etapa 1 (Periódico diario):

Aquí se observa lo sucedido con el nodo de 8 a 2, existe una inversión 6, invertir 6 en la etapa 1 trae una exposición de 80, dejando esos 2 para la siguiente etapa, es ahí donde revisamos cual es la forma más óptima de distribuir 2, que en la siguiente etapa es de 40

pd_22

Finalmente la mayor exposición es de 167 y se logra a través de la distribución de inversión de:

2->3->1->2 o 2->2->1->3

Aquí nos detenemos por el momento, esperando que les haya sido de su agrado.

Programación Dinámica – Investigación de Operaciones

TEORÍA

La programación dinámica es un técnica muy útil para la toma de decisiones de problemas complejos que pueden ser discretizados y secuencializados, proporciona un procedimiento sistemático para determinar la combinación óptima de decisiones; este método no tiene una formulación estándar ya que las ecuaciones que se planteen responden al problema específico.

Esta técnica es muy útil para la reducción el tiempo de ejecución de un algoritmo mediante la utilización de subproblemas y subestructuras óptimas, todo ello haciendo uso del principio de optimalidad:

“Dada una secuencia óptima de decisiones, toda subsecuencia de ella es, a su vez, óptima”

Para la introducción de las características y terminologías de la programación dinámica se creo el problema de la diligencia por parte del profesor Harvey M Wagner:

Un cazafortunas mítico de Missouri que decide ir al oeste a sumergirse en la fiebre del oro que surgió en California a mediados del siglo XIX. Tiene que hacer ek viaje en diligencia a través de territorios sin ley, donde existen serios peligros de ser atacado por merodeadores. A pesar de que su punto de partida y su destino son fijos, tiene muchas opciones en cuanto a qué estados – o territorios – debe elegir como puntos intermedios (tomar en cuenta que el viaje es siempre de izquierda a derecha).

planos1

Para lograr el viaje se requieren de 4 etapas para ir desde el estado A a su destino en el estado J, este cazafortunas es un hombre prudente preocupado por su seguridad. Después de reflexionar un poco ideó una manera bastante ingeniosa para determinar la ruta más segura. Se ofrecen pólizas de seguros de vida a los pasajeros. Como el costo de la póliza de cualquier jornada en la diligencia está basado en una evaluación cuidadosa de la seguridad del recorrida, la ruta más segura debe ser aquella cuya póliza represente el menor costo total“.

El costo de la póliza estándar del viaje en diligencia, del estado i al estado j se denota como:

costo

Creamos las tablas asociadas a cada uno de estos costos tenemos:

pd_1

FORMULACIÓN

Vamos a dividir el problema en etapas, las etapas serán evaluadas en la solución más óptima y se agregarán en el análisis de la siguiente etapa hasta encontrar la solución más óptima general, entonces:

Sean Xn=El destino inmediato de la etapa n (el n-ésimo viaje que se hará en diligencia), tal que la ruta seleccionada final para este problema será:

A->X1->X2->X3->X4, donde X4=J

Sea fn(s,xn) el costo total de la mejor política global para enfrentar las etapas restantes, mientras el cazafortunas se encuentra en el estado “s“, listo para iniciar la etapa n y elige xn como destino inmediato. Dados s y n, sea yn el valor de xn – no necesariamente único – que minimiza fn(s,xn) y gn(s) el valor mínimo correspondiente de fn(s,xn). Entonces:

gn(s)=mínf(s,xn)=f(s,yn)

Donde:

 fn(s,xn)=costo inmediato (etapa n) + costo futuro mínimo (etapas n+1 en adelante)

Representado de la siguiente forma:

pd_3

Entonces nuestro objetivo es encontrar g1(A) y su ruta correspondiente, pero para encontrarlo debemos de resolver de forma sucesiva g4(s), g3(s), g2(s) para cada uno de los estados posibles de s y usar g2(s) para encontrar g1(A).  Entonces es una suerte de ir del fin hacia el inicio obteniendo el costo mínimo (para este caso) en cada una de las etapas.

PROCEDIMIENTO

Recordemos que hemos de ir de adelante hacia atrás, entonces partimos de la última etapa, en nuestro ejemplo esta es la etapa 4, la cual es la última etapa por recorrer, cuando esto sucede su ruta está perfectamente definida, sea por H o por I la ruta se dirige hacia J:

pd_1

Podemos entonces hacer lo siguiente:

pd_2

para el caso de la etapa 4 no existe un g(S) ya que es la última, podemos considerar entonces que este es cero, así que está solo calculado directamente con el costo que representa ir por cada una de las rutas H o I hacia J.

En la etapa 3 se nos representa que ahora se deben de recorrer 2 etapas, aquí debemos de tomar especial atención a lo siguiente; tomemos como base que desde F podemos ir sea hacia H o I:

pd_4

Sabemos por la resolución anterior que el g4(H)=3 y g4(I)=4, entonces si decidimos ir de F->H tendríamos un costo total 6+3=9, ya que estamos haciendo la ruta F->H->J; si hacemos F-I tendríamos un costo total de 3+4=7 siendo menor el costo  y haciendo que g3(F)=7, lo mismo ocurre con E y G, en consecuencia realizando la tabla:

pd_5

En cada una de las celdas hemos hecho la operación descrita para F.

Al resolver la segunda etapa, realizamos los mismos cálculos donde obtenemos la siguiente tabla:

pd_6

Solo podemos observar que el destino inmediato de B y D pueden ser E o F ya que minimizan el valor de “g“, ahora debemos de ocuparnos de la primera etapa:

pd_7

Resuelta la última etapa ya nos es  posible obtener la ruta o rutas óptimas para nuestro problema, tenemos entonces que:

A->C->E->H->J  o  A->D->E->H->J o A->D->F->I->J

Tenemos estas 3 rutas disponibles donde todas tienen el costo mínimo de 11.

CARACTERÍSTICAS

  • El problema se puede dividir por etapas, y cada una de las etapas requiere de una política de decisión.
  • Cada etapa tiene cierto número de estados, los estados son las distintas condiciones posibles en las que se puede encontrar el sistema en cada etapa.
  • El efecto de la política de decisión en cada etapa es transformar el estado actual en un estado asociado con el inicio de la siguiente etapa, entonces podemos decir que un estado es una columna de nodos, cada nodo representa un estado y cada rama una política de decisión.
  • El procedimiento de resolución de la programación dinámica está diseñado para encontrar una política óptima para cada etapa logrando así la política óptima general.
  • Dado el estado actual, una política óptima para las etapas restantes es independiente de la política adoptada en etapas anteriores, por ende la decisión inmediata óptima solo depende del estado actual y no de cómo se llegó ahí, esto es el principio de optimalidad de la programación dinámica.
  • Se dispone de una relación recursiva que identifica la política óptima para la etapa n, dada la política óptima para la etapa n+1. La relación recursiva en su forma difiere de un problema a otro, pero se puede emplear las notaciones que ya se han usado en el problema de la diligencia, tal que finalmente siempre será cuestión de hallar un máximo o un mínimo.
  • Cuando se hace uso de la relación recursiva, el procedimiento de solución comienza al final se mueve hacia atrás etapa por etapa hasta encontrar la política óptima en cada etapa hasta la etapa inicial.

APLICACIONES

La Ruta Crítica

Hallar la ruta crítica con programación dinámica:

pd_8

Resolución

Recordemos que debemos de dividir por etapas nuestra red, sabemos que una etapa es un conjunto nodos o estados y los arcos con su valor con las contribuciones directas; podemos notar que existe la particularidad que el estado 3 está conectado tanto al estado final como a un estado intermedio, este estado 3 en consecuencia estará presente en al menos 2 etapas, si hiciéramos un corte podríamos observar que nuestro problema puede segmentarse en 4 etapas, entonces:

La etapa 4 es la última etapa por recorrer, y el único estado siguiente es 7 y no existe un g5 por lo cual el esfuerzo o tiempo será solo la contribución directa del arco:

 

pd_9

La etapa 3, ahora son dos etapas que debemos de considerar, en este caso en particular, recuerda tomar en cuenta todos los estados previos que te permiten llegar a los estados futuros, para ello observemos el estado 4 que si bien se encuentra en un estado final para la etapa también es parte del estado actual ya que conecta con otros estados finales, se puede observar que por ejemplo en el estado 2 que va hacia el estado 6 y 4 la contribución inmediata de ir de 2 a 6 más el g4(6)  máximo que hasta el momento es 1, igualmente ocurre de 2 a 4, de entre ellos dos elegimos el máximo, ¿Por qué el máximo?, pues porqué estamos buscando la ruta crítica, la ruta crítica está representada por la ruta más larga que me permita ir de 1 a 7.

pd_10

La etapa 2, correspondería ubicar en los estados finales a 1, 2, 4 y 5, pero no tiene sentido colocar a 1 ya que no existe un estado previo para él, entonces solo colocaremos a 2, 4 y 5, hacemos la misma lógica que ya está sustentada en la relación recursiva que aplica para este caso:

pd_11

La etapa 1 y última etapa se consideran las 3 etapas anteriores, entonces tenemos:

pd_12

Hecho todo ello, ¿Cómo hallamos la ruta crítica?, debemos de seleccionar todos los valores máximos, si existe un estado (nodo) que se encuentre en más de una etapa debemos de seleccionar en cual de ellos es el mayor por ejemplo, revisemos la ruta de 1 a 2 y 1 a 3 aparentemente sea de 1 a 3 la ruta más larga; sin embargo, la ruta de 1 a 2 en la etapa 2  es mayor que la ruta de 1 a 3, es por ello que tomamos dicha ruta, luego, en la etapa 2 se obtuvo ese valor del estado 2 ya que provenía del estado 6 y de 6 a 7, entonces nuestra ruta crítica será:

1->2->6->7 longitud de 13

 

Arduino Ethernet Shield y Python – parte 2

Anteriormente

PROGRAMACIÓN EN PYTHON

En esta ocasión abordaremos el caso desde python, para así completar todo lo necesario de nuestro proyecto, recordemos que queremos obtener la data desde arduino a través del protocolo udp haciendo uso del ethernet shield y  el arduino, para ello en la primera etapa hemos implementado el servidor que despacha los datos sobre la temperatura.

esquema_general2

Bien, ahora lo que debemos hacer es implementar desde el lado de python el recibir esa información y esto lo vamos a realizar a través del uso de los sockets, un socket es una comunicación bidireccional que se establece en los procesos y estos procesos pueden ser en una misma máquina o en diferentes, así también pueden desplegarse en diferentes protocolos siendo los más emblemáticos tcp/ip y udp. Python nos brinda un módulo para la implementación de sockets, este módulo es socket (muchas vueltas al asunto ¿no?).

Para ello creamos un fichero python con el nombre que quieras en nuestro IDE favorito ( yo sé que quieres decir que es VSCODE), hecho esto importamos el módulo socket y el módulo time con el fin de realizar pausas en el pedido de datos:

from socket import *
import time

Ahora debemos de crear una instancia de socket, esto lo podemos hacer con la función socket() el cual recibe dos parámetros, el primer parámetro hace referencia a la familia de direcciones y el segundo hace referencia al protocolo específico a usar, en nuestro caso hemos de usar IPv4 y UDP respectivamente:

cliente_socket=socket(AF_INET,SOCK_DGRAM)

En una tupla agregamos tanto el ip como el puerto por el cual nos comunicamos al servidor, recordemos que es: 192.168.1.48 y 3000 respectivamente:

direccion=("192.168.1.48",3000)

Agregamos un segundo de espera en alguna respuesta de parte del arduino a través del método settimeout():

cliente_socket.settimeout(1)

Creamos un bucle infinito de solicitudes al servidor, esto lo haremos a través de un while, dentro de el  debemos de enviar la solicitud, para ello definimos un string llamado data y le asignamos un valor de 1 (recuerda que puede ser el valor que se te antoje), luego de ello debemos enviarlo con el método sendto, este método recibe como parámetros la data de tipo byte y  la dirección que es una tupla, pero nuestra data es un string, entonces debemos de realizar una casteo a byte y eso se realiza con el método encode quedando de la siguiente forma:

cliente_socket.sendto(data.encode(),direccion)

Cuando hemos enviado la información deberíamos poder recibir algún tipo de dato, aunque esto no siempre se cumple, es por ello que debemos de hacer la lectura de los datos recibidos por el servidor a través de una estructura try/except, dentro del try/except  recibimos el dato a través del método recvfrom() que recibe como parámetro el tamaño del buffer, este método nos devuelve un par de elementos que son tanto la data en bytes y la dirección de donde provino, esencialmente estamos interesados en la data que es la temperatura (rec_data), recibido ello podemos hacer un casteo y pasarlo a float y finalmente la impresión del dato, quedando de la siguiente forma:

try:

   rec_data,addr=cliente_socket.recvfrom(2048) 

   temperatura=float(rec_data) 

   print("La temperatura es: {0}".format(temperatura))

except:

   print("Algo anda mal")

En el except hemos colocado información de que algo anda mal, podríamos sí capturar el error que se produce y hacerle un seguimiento; sin embargo, para fines del ejemplo no lo haremos, finalmente hacemos que nuestro, agregamos un descanso para la solicitud de 2 segundos:

time.sleep(2)
Y finalmente todo el código del fichero queda de la siguiente forma:
from socket import *

import time

direccion=("192.168.1.48",3000)

cliente_socket=socket(AF_INET,SOCK_DGRAM)

cliente_socket.settimeout(1)

while(1):

   data="1" #la data que enviaremos

   cliente_socket.sendto(data.encode(),direccion) 

   try:

      rec_data,addr=cliente_socket.recvfrom(2048) 

      temperatura=float(rec_data) 

      print("La temperatura es: {0}".format(temperatura))

   except:

      print("Algo anda mal")

   time.sleep(2)
Ahora aquí una imagen de la data recibida, recordar que la data recibida deben de traducirla a la medida en centígrados en la que se encuentren:

 

datafinal

Arduino Ethernet Shield y Python – parte 1

En anteriores post he mencionado el espacio que Python se ha ido ganando a pulso en el mundo de la ingeniería y las matemáticas, ya sea por su sencillez de sintaxis donde más se preocupa en el fondo que en la forma, es así que si pretendes realizar algún tipo de  aplicación relacionada a la ingeniería, python es tu lenguaje ideal (siempre y cuando la aplicación sea para lenguajes de alto nivel). Paralelo a ello vemos el avance de las aplicaciones en IoT que es uno de los corolarios de la tercera revolución industrial y que está recibiendo un gran empuje, entusiastas (como yo) intentamos de entender y comprender el paradigma de su funcionamiento y de sus posibilidades, y como se dice en algunas películas de peleas:

Los hombres se entienden en la pelea

Pues los desarrolladores se entienden cuando desarrollan, entonces que nos trae en esta ocasión, algo relativamente simple, vamos a recibir datos desde un arduino a través de la red de internet y estos datos seamos capaces de enviarlo a una web o al menos poderlos sensar,  simple el enunciarlo pero que guarda cierta complejidad en su implementación; para ello necesitamos de:

  • Arduino UNO.
  • Placa Ethernet para Arduino.
  • La base shield de Arduino Grove (esto es opcional, pues podrías usar un protoboard y cables hembra – macho).
  • IDE de programación (Arduino IDE y VSCODE), también son opcionales, ya que al ser Ethernet una librería oficial de Arduino también se encuentra disponible en Arduino Web Editor y  en lugar de VSCODE puedes usar  un IDE más especializado como PyCharm.
  • Un sensor cualquiera (entre más simple mejor) de temperatura, pero verás, cualquier sensor será útil.

montaje

EL DILEMA DEL PROTOCOLO

¿Qué protocolo usar? de los muchos que existen y que se especializan en estas lides, podemos quizá para este experimento establecer una discusión entre  TCP y UDP, el primero ampliamente usado por todos pues es el que da soporte a las principales aplicaciones de internet como HTTP, FTP, SSH y SMTP, y el segundo empleado para transmisiones de audio o vídeo, leamos un poco de su funcionamiento:

Primero TCP

Las aplicaciones envían flujos de bytes a la capa TCP para ser enviados a la red. TCP divide el flujo de bytes llegado de la aplicación en segmentos de tamaño apropiado (normalmente esta limitación viene impuesta por la unidad máxima de transferencia (MTU) del nivel de enlace de datos de la red a la que la entidad está asociada) y le añade sus cabeceras. Entonces, TCP pasa el segmento resultante a la capa IP, donde a través de la red, llega a la capa TCP de la entidad destino. TCP comprueba que ningún segmento se ha perdido dando a cada uno un número de secuencia, que es también usado para asegurarse de que los paquetes han llegado a la entidad destino en el orden correcto. TCP devuelve un reconocimiento por bytes que han sido recibidos correctamente; un temporizador en la entidad origen del envío causará un timeout si el asentimiento no es recibido en un tiempo razonable, y el (presuntamente desaparecido) paquete será entonces retransmitido. TCP revisa que no haya bytes dañados durante el envío usando un checksum; es calculado por el emisor en cada paquete antes de ser enviado, y comprobado por el receptor“, Fuente.

Ahora vamos con UDP:

User Datagram Protocol (UDP) es un protocolo del nivel de transporte basado en el intercambio de datagramas. Permite el envío de datagramas a través de la red sin que se haya establecido previamente una conexión, ya que el propio datagrama incorpora suficiente información de direccionamiento en su cabecera. Tampoco tiene confirmación ni control de flujo, por lo que los paquetes pueden adelantarse unos a otros; y tampoco se sabe si ha llegado correctamente, ya que no hay confirmación de entrega o recepción. Su uso principal es para protocolos como DHCP, BOOTP, DNS y demás protocolos en los que el intercambio de paquetes de la conexión/desconexión son mayores, o no son rentables con respecto a la información transmitida, así como para la transmisión de audio y vídeo en tiempo real, donde no es posible realizar retransmisiones por los estrictos requisitos de retardo que se tiene en estos casos“, fuente: la misma de la anterior.

Comparativa TCP y UDP

UDP

Proporciona un nivel de transporte no fiable de datagramas, ya que apenas añade la información necesaria para la comunicación extremo a extremo al paquete que envía al nivel inferior. Lo utilizan aplicaciones como NFS (Network File System) y RCP (comando para copiar ficheros entre ordenadores remotos), pero sobre todo se emplea en tareas de control y en la transmisión de audio y vídeo a través de una red. No introduce retardos para establecer una conexión, no mantiene estado de conexión alguno y no realiza seguimiento de estos parámetros. Así, un servidor dedicado a una aplicación particular puede soportar más clientes activos cuando la aplicación corre sobre UDP en lugar de sobre TCP.

TCP

Es el protocolo que proporciona un transporte fiable de flujo de bits entre aplicaciones. Está pensado para poder enviar grandes cantidades de información de forma fiable, liberando al programador de la dificultad de gestionar la fiabilidad de la conexión (retransmisiones, pérdida de paquetes, orden en el que llegan los paquetes, duplicados de paquetes…) que gestiona el propio protocolo. Pero la complejidad de la gestión de la fiabilidad tiene un coste en eficiencia, ya que para llevar a cabo las gestiones anteriores se tiene que añadir bastante información a los paquetes que enviar. Debido a que los paquetes para enviar tienen un tamaño máximo, cuanta más información añada el protocolo para su gestión, menos información que proviene de la aplicación podrá contener ese paquete (el segmento TCP tiene una sobrecarga de 20 bytes en cada segmento, mientras que UDP solo añade 8 bytes).

Por eso, cuando es más importante la velocidad que la fiabilidad, se utiliza UDP. En cambio, TCP asegura la recepción en destino de la información para transmitir, fuente.

Finalmente podemos hacer esta analogía con algo de humor:

duv11av99nm11

POR CUAL NOS DECANTAMOS

Actualmente existe una total controversia en el aspecto de la seguridad en el IoT (otro ejemplo), es cierto que los protocolos actuales o el como se implementan les falta aún camino para recorrer en términos de seguridad; sin embargo, ello no puede limitar acercarnos a entender el paradigma de lo que significa el IoT, así que haciendo dicha observación de obviar en sentido estricto la seguridad, estableceremos el esquema de lo que deseamos implementar.

esquema_general

Cuando nuestro Arduino ha de enviar datos de lo que ha censado, estos datos son muy grandes, y por lo general no muy diferenciados (esto es porque la diferenciación se da con la variable tiempo), imaginemos pues que estamos censando la temperatura a lo largo del día, decir que a una hora específica se está a determinada temperatura es por la resultante de la media (teniendo en cuenta la problemática de los valores extremos); podemos decir que no nos importa la secuencia de los datos ni necesitamos asegurarnos de que todos los datos lleguen, sino la gran mayoría de datos independientemente de su secuencia, entonces queda casi por obviedad que apostaremos por el protocolo UDP que se adapta mejor a nuestro requerimiento.

Decidido el protocolo ahora pasemos a la parte de implementación, la implementación tiene dos componentes en el campo del desarrollo; el primero será la programación de nuestra placa arduino montada conjuntamente con la placa ethernet, y el segundo del lado del computador (servidor más adelante) que se encargará de recepcionar los datos y de ahí si es posible enviarlos a una web o leerlos en una consola.

PROGRAMACIÓN EN ARDUINO

Intentemos bosquejar todo lo que hemos de realizar:

df.png

Entonces, abrimos el Arduino IDE y creamos un nuevo proyecto. Lo que necesitamos es incluir las librerías necesarias:

#include <Ethernet.h> //librería de ethernet
#include <EthernetUdp.h> //librería de UDP
#include <SPI.h>

La librería Ethernet es la utilizada para el manejo de la placa ethernet y la conexión a internet,  Ethernet.Udp   es el encargado de manejar el protocolo UDP y SPI es la librería que se encarga de la gestión de transmisión de datos entre los circuitos, la placa Ethernet en su misma descripción hace referencia a que la comunicación se realiza a través del bus SPI en los pines 11, 12 y 13 (si quieres saber más).

Ya que hemos de registrar la temperatura del ambiente, debemos de crear una variable de tipo entera y el pin donde se ha de conectar el sensor y una variable donde se almacenará los valores que se obtengan del medio, entonces:

int sensor_pin=A0;
double valor_sensor=0

Para que nuestro Arduino pueda conectarse a internet debe poder ser identificado y que se le asigne una IP, la identificación se realiza a través de la dirección MAC y es un arreglo de tipo byte:

byte mac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0xEE};

El ip le asignamos a través de la clase IPAddress, este ip que le asignamos debe tener la misma configuración que el que tiene nuestra red de internet, de esa configuración debemos de coger uno tal que no lo esté usando otro dispositivo que esté conectado a nuestra red para que no existan conflictos, ¿Cómo saber la configuración de nuestra IP?, en windows es a través del CMD y digitando la instrucción ipconfig.

IPAddress ip(192,168,1,48);

Cuando enviamos un dato a través de internet nosotros debemos de indicar tanto el ip de destino como el puerto, el puerto definitivamente es un valor positivo y para no cometer errores vamos a restringirlo a ello usando la palabra reservada unsigned:

unsigned int puerto=3000;

CUESTIÓN OPCIONAL

Supongamos que tengamos cuando hagamos un requerimiento de datos este sea específico, es decir, sea que tengamos temperatura y presión, el cliente debe tener la facultad de elegir que tipo de dato desea observar, es así que debemos de almacenar dichos solicitudes en un arreglo y esto lo podemos hacer con lo que se describe a continuación.

Cuando Arduino tenga que leer los paquetes de datos y que esté sobre UDP debe ser almacenado en un arreglo de caracteres, la librería ethernet define una constante denominada UDP_TX_PACKET_MAX_SIZE equivalente a 24 y que asignaremos como tamaño del arreglo, entonces (más aquí):

char paqueteBuffer[UDP_TX_PACKET_MAX_SIZE];

Recordemos que la data que hemos recibido es de tipo Char, entonces necesitamos convertirlo a una cadena a través de un String, para ello creamos una variable que ha de recepcionar esta conversión ya que las cadenas son más sencillas de trabajar que un char o un arreglo:

String dataReq;

Así también debemos de crear la dimensión de ese paquete que se está leyendo:

int paquete_size;

FIN DE LA CUESTIÓN OPCIONAL

Finalmente creamos una instancia de ethernet UDP:

EthernetUDP udp;

Hechos todos los preparativos debemos de proceder a inicializar en la función setup.

#include <Ethernet.h> //librería de ethernet
#include <EthernetUdp.h> //librería udp
#include <SPI.h>

int sensor_pin=A0;
double valor_sensor=0;

byte mac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0xEE}; //dirección MAC
IPAddress ip(192,168,1,48);//ip que asignamos a nuestro arduino
unsigned int puerto=3000;//puerto que se le asigna
char paqueteBuffer[UDP_TX_PACKET_MAX_SIZE];//dimension del char 
String dataReq; //cadena para nuestro string
int paquete_size;//tamaño del paquete
EthernetUDP udp; //creamos un objeto UDP

Función Setup

Debemos de iniciar el puerto serial:

Serial.begin(9600);

Ahora debemos de inicializar la librería con las configuraciones que hemos asignado con el método begin de la clase Ethernet, ahora este método tiene sobrecarga, tal como sabemos los métodos solo se diferencian por la cantidad de parámetros cuando son sobre escritos, nosotros solo poseemos o hemos configurado una ip (el creado a través de la clase IPAddress y una dirección mac (que la tenemos en el arreglo de tipo byte), entonces usaremos el método que solo requiera de ellos:

Ethernet.begin(mac,ip);

De igual forma y con el mismo fin sucede con la librería UDP;sin embargo, esta librería requiere que como parámetro el paso de un puerto, que es el puerto por el cual se ha de comunicar  (recordar que hemos asignado un puerto, el puerto 3000:

udp.begin(puerto);

Establecemos una pausa  de 1.5 segundos en su equivalente 1500 mili segundos con el método delay:

delay(1500);

Con todo ello todos los elementos que necesitamos ya se encuentran inicializados, ahora debemos de observar que es lo que sucede en la siguiente función:

void setup() {
   Serial.begin(9600);
  Ethernet.begin(mac,ip);//inicializa el ethernet
  udp.begin(puerto);//inicializar el udp
  delay(1500);
}

Function Loop

¿Cómo ha de funcionar nuestra comunicación?, bueno nosotros debemos de enviar datos siempre que existan datos, es decir, debemos de asegurar que se hayan recibido correctamente los datos del sensor para que puedan ser enviados, la forma en la que se capturan estos datos es a través del método analogRead() el cual recibe como parámetro el pin donde se encuentra conectado el sensor:

 valor_sensor=analogRead(sensor_pin);

Muy bien, recordemos que nuestra máquina donde configuraremos nuestro fichero en python estará fungiendo como un cliente que solicitará constantemente los datos que arduino tenga en relación a la temperatura, esto se hará a través del protocolo UDP, entonces nosotros debemos de estar atentos a la solicitud de datos y cuando este se reciba proceder al envío de los mismos, para ello solo debemos hacer la siguiente inferencia: “Si el paquete de datos es mayor que cero, entonces existe una solicitud“, el paquete de datos en UDP se realiza a través del método parsePacket():

if(udp.parsePacket()>0){}

Ahora sabemos que existe una solicitud; sin embargo, no creo que sea tan apropiado leer que es lo que se está pidiendo, ya que lo único que haremos es despachar temperatura, es por ello que solo aseguramos que exista una solicitud sin saber que es lo que solicita porque lo único que obtendrá será temperatura, ¿En qué situación si nos interesa saber el contenido?, cuando por ejemplo tengamos más de un sensor, si te encuentras en dicha situación deberías primero leer el paquete con:

 udp.read(paqueteBuffer,UDP_TX_PACKET_MAX_SIZE);
 String datReq(paqueteBuffer); //convierte el array en un string

Y luego de ello reemplazar:

if(udp.parsePacket()>0){}

por:

if(datReq=="Condición 1"){}

Tal que condición 1 sea quizás la solicitud de temperatura o presión

Sin embargo, para este ejemplo no nos decantamos por la lectura, sino que nos basta con saber que existe una solicitud, bueno, entonces debemos de enviar este dato a través del protocolo udp y esto lo hacemos a través del método beginPacket(), este método recibe como parámetros tanto el ip como el puerto al que vamos a conectarnos, el ip y el puerto lo obtenemos dado que un cliente ya estableció un requerimiento a través de los métodos remoteIP() y remotePort(), entonces dentro del if:

udp.beginPacket(udp.remoteIP(),udp.remotePort());

Hecho eso, capturamos la data del sensor y la enviamos, esto lo hacemos con el método print() de la clase Server que tiene como parámetro la data que se desea enviar, en nuestro caso deseamos que lo que se envíe sea el valor del sensor, se debe acotar que cuando se envía una cadena, un número o lo que fuera este será enviado como un conjunto de caracteres (Si se envía 123 este será ‘1’ ‘2’ ‘3’.

udp.print(valor_sensor);

Ahora debemos de finalizar la escritura de los datos a través del método endPacket():

udp.endPacket();

Queda de la siguiente forma:

void loop() {
   valor_sensor=analogRead(sensor_pin);
   if(udp.parsePacket()>0){
        udp.beginPacket(udp.remoteIP(),udp.remotePort());
        udp.print(valor_sensor);
        udp.endPacket();

   }
}

Bien, hasta el momento hemos asegurado que nuestro servidor esté en funcionamiento, esto lo podemos comprobar haciendo un pin al ip asignado a nuestro arduino, el resultado debería ser el siguiente:

ping.png

Resolución de Casos de Valor Presente, futuro y anualidades

Teoría:

Ejercicio 1

¿Cuánto dinero puede desembolsar ahora Haydon Rheosystems Inc. , para un sistema de administración de energía, si el software ahorraría a la empresa $21,300 anuales durante los siguientes cincos años?. Use una tasa de interés de 10% anual.

Resolución:

Observemos como puede ser el diagrama de flujo de efectivo

cap2ex1flujo

El ejercicio nos pide obtener el valor presente (P) sabiendo las anualidades (A) que se reportan durante 5 periodos, donde cada periodo es de 1 año y siendo la tasa del 10%; como se observa los problemas de este tipo como mínimo deben proporcionar 3 datos siendo que por lo general la tasa y los periodos son otorgados, entonces nuestra ecuación sería:

P=A(P/A,i,n)=21,300(P/A,10%,5)

Reemplazamos en la ecuación 3:

cap2ex1form

Tenemos:

P=21,300(3,7908)=80,744

Entonces el monto a desembolsar es de $80,744.

 

Ejercicio 2

Un fabricante de vehículos todo terreno considera comprar inclinómetros de eje dual para instalarlos en una nueva línea de tractores. El distribuidor de los inclinómetros de momento tiene muchos en inventario y los ofrece con un descuento de 40% sobre su precio normal de $142. Si el comprador los obtiene hoy  y no dentro de 2 años, que es cuando los necesitará ¿Cuál es el valor presente de los ahorros por unidad?. La compañía pagaría el precio normal si lo comprara dentro de dos años. Suponga que la tasa de interés es de 10% anual.

Resolución:

Básicamente el problema nos propone una evaluación ¿Conviene comprarlos ahora o luego de 2 años?, si lo compro dentro de 2 años ¿Cuánto en dinero representaría actualmente? y sobre si ese valor presente seria menor que el descuento ofrecido actualmente y cuando dinero ganaríamos con ello. Entonces debemos de hallar el valor presente (P) sabiendo el valor futuro (F) que es  el precio normal sin descuento ($142), nos brindan además como dato la tasa (10%) y los periodos (2 años), entonces nuestra ecuación:

P=F(P/F,i,n)=142(P/F,10%,2)

Reemplazamos en la ecuación 2:

cap2ex2form

 

Obtenemos que P=117.35, entonces si compramos el productos con el 40% de descuento este sería 85.2, hacemos una resta entre comprarlo dentro de 2 años o ahora con el 40% de descuento: 117.35-85.2=32.15; entonces comprando ahora ahorraríamos $32,15 por producto en lugar de sí lo compramos dentro de 2 años.

Ejercicio 3

CGK Rheosystems fabrica viscosímetros de alto rendimiento capaces de superar pruebas de esfuerzo cortante estable en una superficie rugosa y compacta. ¿Qué cantidad debe dedicar la empresa ahora para adquirir un equipo nuevo, en vez de gastar $200,000 dentro de 1 año  y $300,000 dentro de 3 años, si la compañía utiliza una tasa de interés de 15% anual?.

Resolución:

Aunque el problema no da mucho detalle, sabemos que nos piden el valor presente (P) de adquirir un equipo hoy,  dado que cada 1 y 3 años debe realizar algún tipo de prueba para validar sus viscosímetros, entonces siempre se trata de evaluar que conviene más para la toma de una decisión tomando en cuenta que disponemos de los valores futuros, los periodos  y la tasa respectiva, note casi como una constante que entreguen los periodos y la tasa, entonces nuestra ecuación queda, sea Pt el valor presente total:

Pt=P1+P2 donde P1=F1(P1/F1,i,n11) y P2=F2(P2/F2,i,n2)

Tenemos entonces:

cap2ex3form

Donde P=$371,167, el cual sería el monto que debe de invertir la empresa actualmente.

Ejercicio 4

La oficina de servicios públicos (OSP) asignó dos contratos por un total combinado de $ 1.07 millones para mejorar (es decir profundizar) una presa de almacenamiento y reconstruir su vertedor que se dañó severamente en una inundación hace dos años. La OSP dijo que debido al estancamiento económico las propuestas fueron de $950,000,  inferiores de lo que esperaban los ingenieros. Si se supone que los proyectos tienen una vida útil de 20 años. ¿Cuál es el beneficio anual de los ahorros, con una tasa de interés de 6% anual?.

Resolución:

Tal como menciona el problema, la propuesta final fue valorizada en $950,000 el cual tomaremos como nuestro valor presente, la cantidad de periodos es 20 y la tasa es de 6%, y nos piden hallar el beneficio anual de ahorros que es la anualidad, entonces la ecuación queda:

A=P(A/P,i,n)=950,000(A/P,6%,20)

Reemplazando en la ecuación 4:

cap2ex4form

Entonces el beneficio anual de ahorros es de $82,825.

Evaluación de Proyectos a través del Análisis Económico Financiero – Conceptos – Parte 2

Anteriormente:

Parte 1

Continuando con los conceptos teóricos:

Ahora vamos revisar las definiciones de tasa de interés nominal y tasa de interés efectiva,  la relación que existe entre ellas es básicamente la misma que existe entre el interés simple y compuestos que consiste en que el interés compuesto incluye  el interés sobre el interés ganado en el periodo anterior, mientras que el interés simple no lo incluye, esta relación básica, permanece entre el interés nominal y efectivo. Comprender y emplear correctamente las tasas de interés efectivas es importante para la práctica de la ingeniería, dado que los proyectos de ingeniería se financian por medio de deuda o de capital propio; los intereses por préstamos se basan en tasas de interés compuesto por periodos menores a un año y en ingeniería siempre se deben tomar en cuenta sus efectos, entonces:

  • La tasa de interés nominal r, es una tasa de interés que no considera la capitalización de intereses, r = tasa de interés por periodo x número de periodos.
  • La tasa de interés efectiva  i es aquella en que se toma en cuenta la capitalización del interés. Por lo general se expresa como tasa anual efectiva, pero se puede utilizar cualquier periodo como base.

TASA DE INTERÉS NOMINAL 

Existen tres unidades de tiempo asociadas al enunciado de una tasa de interés:

  • Tiempo (o periodo) (t): es el periodo en que se expresa el interés. Esta es la t del enunciado de r% por periodo t; por ejemplo, 1% mensual. La unidad de tiempo de un año es por mucho la más común, de ahí que se suponga así cuando no se especifica otra unidad.
  • Periodo de capitalización (PC): es la unidad de tiempo más corta durante la que se paga o gana interés. Se identifica por el término capitalización en el enunciado de la tasa de interés, por ejemplo, 10% anual compuesto mensualmente. Si no es especifica, entonces se supone que es de un año.
  • Frecuencia de composición (m): es el número de veces que la capitalización ocurre dentro del periodo t. Si los periodos de capitalización PC y de tiempo t son los mismos, la frecuencia de capitalización es 1, por ejemplo, 1% mensual, compuesto mensualmente.

Si:

“Una tasa de interés de 6% por año, capitalizable en forma semanal”

Entonces: t=1 año, PC=1semana, por lo tanto m=52 semanas; podemos decir entonces:

tasa_interes3
tasa_interes4
Ingeniería Económica – Leland Blank – Anthony Tarquin -pág-98

TASA DE INTERÉS EFECTIVAS ANUALES

Se mencionó que las tasas nominales y efectivas son análogas al interés simple y compuesto, entonces podemos hacer lo siguiente, sea  ia el interés efectivo anual y que si tuviéramos que calcular el valor futuro (F) tal que P sea el valor presente podríamos hacerlo de la siguiente forma:

F=P+Pia

Pero F también es posible expresarlo en función del interés por periodo de capitalización, sea i la tasa por período y m sea el período, según la ecuación 1 del post 1:

F=P(1+i)m

Igualamos:

P(1+ia)=P(1+i)m

Pero i está en períodos e ia está anualmente, nosotros podemos decir que i=r/m siendo r la tasa nominal anual y m el número de períodos, entonces:

Ecuación 10:

ia=(1+r/m)m-1

Esta ecuación es válida para cualquier periodo.