La IA que sueña poesía con imágenes sintéticas

Desque que aparecieron los grandes modelos de tipo GPT-3, asistimos a una revolución en la generación de contenidos sintéticos. La aceleración del proceso creativo y la exploración de nuevas formas de arte ya es una realidad. Amenaza para algunos, oportunidad para otros, lo que está claro es que esta nueva herramienta cognitiva ha venido para quedarse.

Anteriormente vimos como generar retratos de Lorca, o como generar una historia con openai. Incluso probamos como escribir un pequeño ensayo sobre el metaverso. Vamos a experimentar con la generación de imágenes sintéticas para evaluar su aplicación para ilustrar poemas usando como entrada el texto de cada verso junto con alguna indicación del estilo de las imágenes a generar.

NOCHE DEL AMOR INSOMNE

(Federico García Lorca)

Noche arriba los dos con luna llena,
yo me puse a llorar y tú reías.
Tu desdén era un dios, las quejas mías
momentos y palomas en cadena.

Noche abajo los dos. Cristal de pena,
llorabas tú por hondas lejanías.
Mi dolor era un grupo de agonías
sobre tu débil corazón de arena.

La aurora nos unió sobre la cama,
las bocas puestas sobre el chorro helado
de una sangre sin fin que se derrama.

Y el sol entró por el balcón cerrado
y el coral de la vida abrió su rama
sobre mi corazón amortajado.

Retratos de Lorca sintetizados digitalmente

Retrato de Federico García Lorca

El arte siempre ha estado muy ligado a la tecnología del momento influyendo en las artes plásticas. El arte en la prehistoria ha perdurado hasta nuestros días en los dibujos y marcas realizados en cuevas. Las matemáticas influyeron en la creación de pinturas con perspectiva durante El Renacimiento y desde que se inventó la fotografía, de nuevo, la pintura, con el impresionismo se reinventó mostrando nuevas formas de mostrar la realidad.

Ahora, con la aparición de los grandes modelos de Inteligencia Artificial, quizás nos toque volver a vivir un nuevo movimiento creativo, en el que los contenido sintéticos se mezclan con las ideas creativas de los artistas, en el que la técnica se libera de las limitaciones que impone el hecho de dominar una serie de destrezas que no todo el mundo puede o ha podido desarrollar.

Ya no es necesario saber dibujar para iniciarse en el proceso creativo. Las ideas pueden hacerse realidad en cuestión de segundos, utilizando las herramientas que hoy están a disposición de todos. Open AI, Dall-e 2, Stable Diffusion y muchos otros que surgirán en los próximos meses o incluso semanas, viendo al ritmo que están proliferando.

Veamos el resultado aplicado a la generación de retratos del poeta con más influencia y popularidad de la literatura española del siglo XX, Federico García Lorca.

Todos estos retratos han sido generados por el modelo de Inteligencia Artificial Stable Diffusion utilizando el siguiente prompt:

prompt = «portrait Anime Federico García Lorca cute-fine-face, pretty face, realistic shaded Perfect face, fine details. realistic shaded lighting by Ilya Kuvshinov Giuseppe Dangelico Pino and Michael Garmash and Rob Rey, IAMAG premiere, aaaa achievement collection, elegant freckles, fabulous machine»

Texto utilizado para generar los retratos de Lorca con el modelo Stable Diffusion

Como habrás podido ver, no todas las imágenes tienen un parecido con el poeta granadino, pero sí que todas ellas tienen una serie de rasgos característicos, el pelo oscuro y las cejas abundantes. Tengamos en cuenta que estas imágenes no existían antes de ejecutar el modelo.

Las hemos creado a partir de un texto con el que expresamos que queremos un retrato del también dramaturgo Federico, siguiendo un estilo pictórico determinado (Picasso, Anime, Digital Art, impresionismo romántico…). En pocos minutos podemos generar decenas de imágenes para seleccionar las que se adapten mejor a lo que estemos buscando para luego afinar mejor nuestra idea o proyecto.

Esto es, sencillamente, espectacular.

Sistema de riego con arduino

Vamos a construir un sistema de riego automático con Arduino controlado por voz a través de Alexa.

Imagen artística de arduino generada por una IA
Imagen artística de arduino generada por una IA

Gracias a todo el contenido que muchas personas comparten en Internet, he podido introducirme en el mundo del IoT. Quiero agradecer con mi humilde contribución, la generosidad de todos aquellos que ayudan a los demás compartiendo su conocimiento.

¿En qué consiste el proyecto?

La mejor forma de aprender en esto del IoT es marcarse un reto y empezar a buscar soluciones, investigando y leyendo sobre todas las materias que necesitas para llevarlo a cabo.

El reto que vamos a abordar, es el de construir un sistema de riego automático para unas jardineras. El sistema consiste en unos sensores de humedad de suelo, un dispositivo ESP8266 y una pequeña bomba de agua que se acciona cuando la humedad del suelo es muy baja.

El sistema está conectado a Internet a través de WiFi, de forma que podamos consumir un servicio MQTT con el que poder controlar los parámetros básicos del sistema de forma remota. Además escribimos en una base de datos de ThingSpeak todas las lecturas de los sensores de humedad para poder visualizar en todo momento el estado del sistema de riego.

Finalmente configuramos Alexa para poder accionar el riego y pararlo en cualquier momento o incluso usar las skills de Alexa para programar el horario y la duración de los períodos de riego.

Los sensores de humedad son muy poco fiables y tienen muchas variaciones en las medidas. Esto complica enormemente encontrar el valor correcto con el que determinar cuando la tierra no tiene humedad para activar la bomba de agua. Un valor muy alto implicará que la bomba no se activará nunca y un valor demasiado bajo podría llevarnos a que la bomba riegue demasiado.

Para evitarlo, usamos 4 sensores distribuidos por la jardinera de forma que calculamos la media de las 4 medidas. Para tomar las medidas de cada sensor, realizamos a su vez varias lecturas cada pocos milisegundos para minimizar el efecto del ruido de este tipo de sensores.

La lectura de la humedad del suelo varía incluso en función de la humedad relativa del aire o en función de la incidencia del sol en la tierra. Esto también dificulta encontrar el valor correcto de humedad en el que se debe disparar la bomba de agua. Fijar este valor en el código es bastante tediosa, ya que cada vez que tengas que cambiarlo te obliga a compilar y cargar de nuevo el código en el ESP8266.

La solución a este problema la encontramos usando un servidor MQTT. En mi caso he usado Adafruit por ser gratuito. Implemento un feed para definir el límite de humedad por encima del cual se debe accionar la bomba de agua y otro para implementar el tiempo de riego medido en segundos. Con estos dos valores puedo controlar el funcionamiento de todo el sistema.

Componentes

Empecemos por recopilar los componentes que necesitamos para desarrollar el sistema:

  • 1 módulo ESP8266 (aliexpress / amazon)
  • 1 relé (aliexpress / amazon)
  • 1 multiplexor CD74HC4067 (aliexpress / amazon)
  • 4 Sensores de humedad (aliexpress / amazon). Os recomiendo este tipo de sensor, hay otros que tienen dos patillas que se estropean muy rápido.
  • 1 bomba de agua (aliexpress / amazon)
  • 1 placa de islas para hacer las conexiones (aliexpress / amazon)
  • 1 transformador AC/DC de 5V (en mi caso es reciclado de un electrodoméstico viejo)
  • Combo de Amazon (1 Canal 5V Relé Módulo + Sensor de Humedad del Suelo + Mini Bomba de Agua DC 3V 5V + 1M Tubería de Agua de PVC)
Componentes
Componentes

Adicionalmente a los componentes electrónicos, necesitaremos tubo de riego, conectores, goteros y un depósito de agua.

Diseño

En el siguiente diseño esquemático puedes ver las conexiones del sistema. La alimentación a 5V está proporcionada por un cargador reciclado.

Diseño para riego automático en arduino
Diseño para riego automático en arduino

Aunque el diseño es sencillo, es aconsejable probar por partes el circuito.

Antes de usar el multiplexor, puedes probar el diseño configurando un solo sensor de humedad, que deberá ir en la única entrada analógica que dispone el ESP8266.

Configuración de la conexión con ThingSpeak

ThingSpeak™ es un servicio de plataforma de análisis de IoT que le permite agregar, visualizar y analizar flujos de datos en tiempo real en la nube. ThingSpeak proporciona visualizaciones instantáneas de los datos publicados por sus dispositivos en ThingSpeak. Con la capacidad de ejecutar código MATLAB® en ThingSpeak, puede realizar análisis y procesamiento en línea de los datos a medida que ingresan. ThingSpeak se usa a menudo para la creación de prototipos y la prueba de concepto de sistemas IoT que requieren análisis.

Empecemos con la creación del canal:

  1. Una vez que te hayas registrado, ve a la sección My Channels para crear una canal nuevo.
Creación de un canal en ThingSpeak
Creación de un canal en ThingSpeak

2. Escribe el nombre que quieras para tu canal junto con una pequeña descripción. A continuación indican los campos que vamos a rellenar desde nuestro sistema de riego. Es importante que mantengas estos nombres. En el caso de que quieras cambiarlos, deberás ajustar el código en consecuencia.

Configuración de un canal en ThingSpeak
Configuración de un canal en ThingSpeak

3. Una vez creado el canal, ve a la sección API Keys y copia los valores del Channel ID y de la Write API Key. Los necesitarás para configurar el código más adelante.

API Key del canal de ThingSpeak
API Key del canal de ThingSpeak
// Variables para definir la conexión con ThingSpeak
unsigned long myChannelNumber = 1234567; //Código de canal de Things Speak
const char * myWriteAPIKey = "API_KEY"; // Indicar aquí el código de escritura de ThingSpeak

4. Por último, ve a la sección privada para componer la visualización de los datos según tus preferencias.

Composición del Dashboard en ThingSpeak
Composición del Dashboard en ThingSpeak

Configuración de la conexión con Adafruit IO

Para poder manejar nuestro sistema de riego, vamos a usar un servidor MQTT publicado con Adafruit.

Vamos a definir dos variables, una a la que llamaremos humedad y que nos permitirá configurar el nivel de humedad con el que queremos activar la bomba. Recuerda que valores altos, indican una humedad más baja.

La otra variable, que llamaremos tiempo_de_riego, la usaremos para poder configurar el tiempo de riego antes de parar la bomba y volver a consultar los valores de humedad. Esto veréis que os dará mucho juego para poder configurar el riego como queráis. Es importante que no pongas un tiempo de riego muy elevado para evitar que se queme la bomba.

Creación de feeds en Adafruit IO
Creación de feeds en Adafruit IO

Una vez que tengas creadas las dos variables (las variables, se llaman Feed en Adafruit), busca la información acerca del MQTT Key, que lo necesitarás también en el código.

Parámetros MQTT del feed creado en Adafruit IO
Parámetros MQTT del feed creado en Adafruit IO

Una vez tengas las cadenas de MQTT Key, pulsa sobre el icono de la llave sobre fondo amarillo para activar el token de acceso seguro. Recuerda mantener estos valores en un lugar seguro. Copia de esta pantalla, el username y la active key.

Adafruit IO Key
Adafruit IO Key

Por último configura un dashboard para poder configurar las dos variables de humedad y tiempo_de_riego de forma fácil.

Truco: Puedes hacerte un acceso directo a este dashboard en tu móvil para poder ajustar los valores del sistema de riego cuando quieras.

Dashboard en Adafruit IO
Dashboard en Adafruit IO

Con esto lo tendremos todos para probar el código. Lo que haremos será suscribirnos a estos dos canales MQTT de forma que nuestro sistema lea los valores de configuración para humedad y tiempo de riego.


Código

A continuación tienes el código completo, pero recuerda que es mejor que vayas montándolo por partes, para asegurarte que todo va encajando bien, el hardware y las conexiones con ThingSpeak y Adafruit.

#include <ESP8266WiFi.h>; // Para la conexión WiFi
#include "ThingSpeak.h" // Para enviar los datos a ThingSpeak
#include <DHT.h> 
#include "Adafruit_MQTT.h" // Para conectar con 
#include "Adafruit_MQTT_Client.h"
// Definición de parámetros para servidor MQTT de Adafruit
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT  1883
#define AIO_NAME "AIO_NAME" // Sustituir por vuestra cuenta de Adafruit IO
#define AIO_KEY "/feeds/humedad"
#define AIO_PASS "AIO_PASS" // Sustituir por la password de Adafruit IO
#define MAXSUBSCRIPTIONS 5
WiFiClient  client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_NAME, AIO_PASS);
Adafruit_MQTT_Subscribe limite_humedad = Adafruit_MQTT_Subscribe(&mqtt, "JacoboAriza/feeds/humedad");
Adafruit_MQTT_Subscribe tiempo_de_riego = Adafruit_MQTT_Subscribe(&mqtt, "JacoboAriza/feeds/tiempo_de_riego");
Adafruit_MQTT_Publish humedad_mqtt = Adafruit_MQTT_Publish(&mqtt, "JacoboAriza/feeds/humedad/get");
Adafruit_MQTT_Publish riego_mqtt = Adafruit_MQTT_Publish(&mqtt, "JacoboAriza/feeds/tiempo_de_riego/get");
// Usuarios y claves para la conexión WiFi
char ssid[] = "NOMBRE_WIFI_01"; //SSID - Red WiFi a la que me conecto
char pass[] = "PASSWORD_WIFI_01"; // Passowrd de la red WiFi
String ssis2 = "NOMBRE_WIFI_02"; //SSID - Red WiFi a la que me conecto
String pass2 = "PASSWORD_WIFI_02"; // Passowrd de la red WiFi
String ssid3 = "NOMBRE_WIFI_03"; //SSID - Red WiFi a la que me conecto
String pass3 = "PASSWORD_WIFI_03"; // Passowrd de la red WiFi
// Variables para definir la conexión con ThingSpeak
unsigned long myChannelNumber = 1234567; //Código de canal de Things Speak
const char * myWriteAPIKey = "API_KEY"; // Indicar aquí el código de escritura de ThingSpeak
// Variables a definir según la configuración deseada
const int numero_de_sensores = 4; // Número de sensores de humedad
const int numero_de_medidas = 10; // Número de medidas para hacer la media
int motorPin = 14;
int limite_medida = 900;
int tiempo_de_riego_maximo = 60; 
int entrada_sensor_humedad = A0; // Entrada analógica con las entradas de los sensores de humedad.
int multiplexor[4] = {5,4,0,2};
int sensores[4][numero_de_sensores] = {{0,0,0,0},{1,0,0,0},{0,1,0,0},{1,1,0,0}};
float medidas[numero_de_sensores];
String texto = "";
float value_1 = 0;
float valor = 0;
String value = "";
// --------------------------------------------------------------------------------------------- //
// Descripción: Parametrización inicial                                                          //
// --------------------------------------------------------------------------------------------- //
void setup() {
  pinMode(entrada_sensor_humedad, INPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(multiplexor[0], OUTPUT);
  pinMode(multiplexor[1], OUTPUT);
  pinMode(multiplexor[2], OUTPUT);
  pinMode(multiplexor[3], OUTPUT);
  Serial.begin(9600);
  digitalWrite(motorPin, HIGH);
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);
  internet();
  mqtt.subscribe(&limite_humedad);  
  mqtt.subscribe(&tiempo_de_riego);
}
// --------------------------------------------------------------------------------------------- //
// Descripción: Función principal                                                                //
// --------------------------------------------------------------------------------------------- //
void loop() {
  // Nos conectamos al servidor MQTT donde tenemos los parámetros de configuración que regulan el riego: 
  // 1. Límite de humedad para accionar la bomba.
  // 2. Número de segundos en los que se activa la bomba en cada ciclo.
  MQTT_connect();
  // Este bloque de código sirve para forzar que la lectura posterior siempre se realice. 
  Serial.println ("Leyendo variables...");
  if (! humedad_mqtt.publish(0)) {
    Serial.println(F("Failed"));
  } else {
    Serial.println(F("OK!"));
  }
  // Leemos el último valor publicado
  Adafruit_MQTT_Subscribe * subscription;
  while (subscription = mqtt.readSubscription(5000)) {
    if (subscription == &limite_humedad)
    {
      Serial.print("Límite: ");
      texto = ((char *) limite_humedad.lastread);
      limite_medida = texto.toInt();
      Serial.println(texto);
    }
  }
  // Este bloque de código sirve para forzar que la lectura posterior siempre se realice.
  if (! riego_mqtt.publish(0)) {
    Serial.println(F("Failed"));
  } else {
    Serial.println(F("OK!"));
  }
  while (subscription = mqtt.readSubscription(5000)) {
    if (subscription == &tiempo_de_riego)
    {
      Serial.print("Tiempo de riego: ");
      texto = ((char *) tiempo_de_riego.lastread);
      tiempo_de_riego_maximo = texto.toInt();
      Serial.println(texto);
    }
  }
  
  // Ping al servidor para mantener la conexión mqtt activa
  if (!mqtt.ping())
  {
    mqtt.disconnect();
  }
 
  Serial.println("___________");
  
  // Comenzamos con las lecturas de los sensores y con el cálculo de cada medida
  float medida = 0;
  float media_de_las_medidas = 0;
  for (int i = 0; i < numero_de_sensores; i++){
    for (int j = 0; j < 4; j++){
      digitalWrite(multiplexor[j],sensores[i][j]); // Escribimos la codificación asociada a cada sensor para solicitar la medida al multiplexor.
    }
    medida = 0; // inicializamos la medida
    for (int m = 0; m < numero_de_medidas; m++){ // Para establecer cada medida, hacemos 10 lecturas y calculamos la media
      valor = analogRead(entrada_sensor_humedad);
      medida = medida + valor;
    }
    medida = medida / numero_de_medidas;
    media_de_las_medidas = media_de_las_medidas + medida;
    medidas[i] = medida; // vamos escribiendo en la matriz de medidas todas los valores calculados
    Serial.print("i:");
    Serial.print(i);
    Serial.print(", valor:");
    Serial.println(medida);
    delay(2000);    
  }
  // Esperamos 8 segundos antes de subir los datos a ThingSpeak, de forma que no saturemos al servidor.
  delay(8000);
  subir_datos(medidas);
  // Calculamos la medida de las medidas de los sensores
  media_de_las_medidas = media_de_las_medidas / numero_de_sensores; 
  
  // A continuación verificamos las variables definidas en el servidor MQTT
  Serial.print ("Verificando límite de humedad. Límite de medida: ");
  Serial.println (limite_medida);
  
  // Si la media de las medidas es mayor que el límite fijado en el servidor MQTT, accionamos la bomba por el tiempo definido. 
  if (media_de_las_medidas > limite_medida){
    Serial.print ("Iniciando el riego durante ");
    Serial.print (tiempo_de_riego_maximo);
    Serial.println (" segundos...");
    digitalWrite(motorPin, LOW); // Activamos el relé que acciona la bomba.
    delay(tiempo_de_riego_maximo*1000);
  }
  digitalWrite(motorPin, HIGH); // Desactivamos el relé de la bomba.
  if (WiFi.status() != WL_CONNECTED){ // Si el módulo se desconecta de la red WiFi, lo intentamos de nuevo.
    internet();
  }
}
// --------------------------------------------------------------------------------------------- //
// Descripción: Función para conectarse a la red WiFi                                            //
// Nota: Durante las pruebas observé desconexiones frecuentes. Por este motivo he añadido la     //
// opción de ir alternando entre dos de las redes WiFi que tengo en casa. Por favor ajustar      //
// esta función según las necesidades particulares de cada uno.                                  //
// --------------------------------------------------------------------------------------------- //
void internet()
{
  int intentos = 0;
  int intercambia = 0;
  Serial.println("Iniciando conexión: ");
  if (WiFi.status() != WL_CONNECTED)
  {
    while (WiFi.status() != WL_CONNECTED)
    {
      WiFi.begin(ssid, pass);
      delay(5000);
      Serial.print(".");
      if (intercambia == 0){
        char ssid[] = "MIWIFI_2G_TJYY_EXT"; //SSID - Red WiFi a la que me conecto
        char pass[] = "DR32Uy6T"; // Passowrd de la red WiFi
        intercambia = 1;
      }else{
        char ssid[] = "devolo-029"; //SSID - Red WiFi a la que me conecto
        char pass[] = "WYKPYBLHGUASQNFA"; // Passowrd de la red WiFi
        intercambia = 0;
      }
    }
    Serial.println("");
    Serial.println("WiFi conectado");
  }
}
// --------------------------------------------------------------------------------------------- //
// Descripción: Función para subir los datos al servidor de ThingSpeak. Subimos las 4 medidas    //
// de los sensores de humedad más la media de dichas medidas.                                    //
// --------------------------------------------------------------------------------------------- //
void subir_datos(float medidas[numero_de_sensores]){
  int canal = 0;
  float media = 0;
  media = 0;
  for (int i=0; i < numero_de_sensores; i++){ // En los canales del 1 al 4 almacenamos las medidas de los sensores
    canal = i+1;
    media = media + medidas[i];
    ThingSpeak.setField(canal,medidas[i]);
  }
  media = media / numero_de_sensores;
  ThingSpeak.setField(5,media); // Calculamos la media de las medidas
  // Hacemos un primer intento de subir los datos. Al usar una cuenta gratuita tenemos limitación sobre la velocidad a la que podemos subir información. 
  // En el caso de que falle, probamos pasados 2 segundos.
  int mensaje = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  
  if (mensaje == 200){
    Serial.println("Canal actualizado correctamente.");
  }
  else{
    delay(2000);
    if (mensaje == 200){
      Serial.println("Canal actualizado correctamente.");
    }
    else{
      Serial.println("Problema actualizando el canal. Código de error HTTP " + String(mensaje));
    }
  }
}
// --------------------------------------------------------------------------------------------- //
// Descripción: Función para conectarse al servicio MQTT de Adafruit IO                          //
// --------------------------------------------------------------------------------------------- //
void MQTT_connect() 
{
  int8_t ret;
  // Si ya estamos conectados, salimos de la función.
  if (mqtt.connected())
  {
    return;
  }
  Serial.print("Conectándose al servidor MQTT... ");
  uint8_t retries = 3; // definimos un número máximo de 3 intentos
  while ((ret = mqtt.connect()) != 0)
  { 
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Reintentando la conexión con el servidor MQTT en 5 segundos...");
    mqtt.disconnect();
    delay(5000);  // espera de 5 segundos
    retries--;
    if (retries == 0) 
    {
      // basically die and wait for WDT to reset me
      while (1);
    }
  }
  Serial.println("MQTT conectado!");
}

Montaje

Así es como queda finalmente:

Montaje final del sistema de riego
Montaje final del sistema de riego

El montaje de las cajas estancas es gracias a Ángel y a su impresora 3D. Os animo a visitar su página que contiene proyectos muy interesantes sobre Arduino y con la Alhambra FPGA.

Caja para proteger al sensor
Caja para proteger al sensor

Configuración de la conexión con Alexa

Ya lo tenemos todo funcionando y ahora, ¿por qué no conectar nuestro sistema con Alexa? De esa forma podremos controlar por voz nuestro sistema de riego.

Para ello necesitaremos configurar un pequeño servicio con IFTTT y con el a su vez podremos configurar las skills de Alexa según nuestras necesidades. Yo lo utilizo para poder regar cuando lo necesite simplemente diciendo «Alexa, riega las plantas». También para configurar el riego de forma automática en los días que quiera, por la duración que necesite y a la hora deseada.

Básicamente nos conectaremos con Alexa a nuestro servidor MQTT definido en Adafruit IO a través de IFTTT, de forma que cambiemos el valor de humedad con el que se activa el riego. Por ejemplo, bajando el nivel de humedad a 0, estaremos asegurando que la bomba se active y empieza a regar. Del mismo modo, cuando queremos que deje de regar, enviaremos al servidor MQTT un valor alto de humedad y nuestra bomba se parará.

Vamos primero a configurar el servicio IFTTT activando la integración con Alexa y con Adafruit:

Publicamos dos applets, uno para iniciar el riego y otro para pararlo. Estos dos applet los podrás utilizar después desde Alexa para definir las skills.

Applets publicados en IFTTT
Applets publicados en IFTTT

Los dos applets siguen el siguiente esquema. Si en Alexa dices una frase en particular, entonces enviamos un valor al servicio MQTT humedad definido en Adafruit:

Esquema del applet en IFTTT
Esquema del applet en IFTTT

Enviamos el valor 0 para empezar a regar:

Parametrización del applet en IFTTT
Parametrización del applet en IFTTT

Y el valor 900 para dejar de regar:

Parametrización del applet en IFTTT
Parametrización del applet en IFTTT

Una vez lo tengas conectado solo tendrás que definir la rutina que quieras:

Definición de rutina en Alexa
Definición de rutina en Alexa

Consejos

Durante las pruebas, me he encontrado muchos problemas. Uno de ellos aunque ahora me parece obvio es el de los vasos comunicantes. Después de cada ciclo de riego empecé a observar que el agua del depósito se vaciaba muy deprisa y siempre que comprobaba los niveles me encontraba el depósito medio vacío. Empecé a sospechar que podría ser algún problema con el código y que se me quedaba en algunas situaciones el motor encendido.

Pero no, simplemente cuando dejaba de activar la bomba, la goma de riego estaba completamente llena y según el dichoso principio de los vasos comunicantes, el agua tendía a equilibrar los niveles. Cosa que significaba que el depósito se me vaciaba justo hasta el nivel del gotero que se encontraba a mayor altura.

Es decir la bomba, aunque esté apagada no corta la conexión con el tubo del riego. ¿Cómo lo he resuelto? He colocado esta conexión en el circuito de riego, entre el depósito y las jardineras, ubicada a una altura mayor que el nivel máximo del depósito. Regulando el gotero para que salgan apenas unas gotas (lo he colocado justo encima de una de las jardineras y así no desperdicio agua), consigo romper la estanqueidad del circuito y problema resuelto.

Truco para romper los vasos comunicantes
Truco para romper los vasos comunicantes

Otro de los problema ha sido con las cajas estancas. Al estar selladas con silicona, cuando hace demasiado calor, el aire que contienen se calienta mucho y se expande, llegando a romper algunas de las juntas. Para este problema te recomiendo aplicar dos medidas: la primera es no usar una pistola de silicona caliente, sino algún otro material que resista mejor los cambios de temperatura, como silicona apta para exteriores o cualquier otro pegamento que puedas encontrar en el mercado.

La segunda medida es pintar de blanco las carcasas, de esa forma reduces mucho el calor, sobre todo si el color del hilo utilizado en la impresora 3D es de algún color muy oscuro.

Sensor de humedad
Sensor de humedad

Después de varios meses, es posible que el agua pudiera generar algún tipo de algas. Aprovecha cuando tengas el bidón vacío para limpiarlas, ya que pueden llegar a atorar la bomba.

Por otro lado, es posible que el cable de la bomba sea muy corto y te quede alguna soldadura sumergida debajo del agua. En este caso, si que puedes usar una pistola de silicona líquida para sellar la soldadura.

Algas en el depósito de agua
Algas en el depósito de agua

Referencias

Os dejo algunas referencias que he consultado en Internet para ir componiendo el proyecto, cachito a cachito:


https://learn.adafruit.com/adafruit-io-basics-esp8266-arduino/arduino-io-library

https://learn.adafruit.com/

https://learn.adafruit.com/adafruit-io-basics-esp8266-arduino/arduino-io-library

Guía para conectar tu ESP8266 con Google Assistant usando IFTTT (solectroshop.com)

Intro to Adafruit_MQTT | MQTT, Adafruit IO & You! | Adafruit Learning System

MQTT using AdafruitIO and ESP8266 | LEARN @ CIRCUITROCKS

Adafruit_MQTT_Library/adafruitio_time_esp8266.ino at master · adafruit/Adafruit_MQTT_Library (github.com)

MQTT using AdafruitIO and ESP8266 | LEARN @ CIRCUITROCKS

Conclusiones finales

En este proyecto hemos aplicado muchos conceptos que no es fácil encontrar juntos. Hablamos de conexión de un dispositivo Arduino a través de Internet, envío de información para su explotación en ThingSpeak, conexión con un servidor MQTT y control por voz a través de Alexa.

Aquí os dejo el fruto (nunca mejor dicho) de este proyecto, un montón de cosas aprendidas y una pequeña cosecha de tomates cultivados en casa. Rico, rico.

Tomates
Tomates

Estas imágenes tampoco las he creado yo

Ya hemos visto como una máquina puede generar textos con sentido de forma automática. Ahora Openai, ha liberado su nuevo modelo que se denomina dalle2 y que permite generar imágenes a partir de descripciones en lenguaje natural.

Probando Dalle 2

«Un cubo de Rubik en 4k hecho de fruta

«Running in an apocalyptic landscape in Madrid. Digital art»

«Una pájaro tomando una cerveza en la playa en arte digital»

«Elefantes paseando en la Alhambra»

La generación de contenidos sintéticos ya es una realidad y en breve veremos como se pueden generar secuencias animadas o videos.

La generación de contenidos sintéticos combinada con el metaverso abre un campo infinito para nuevas aplicaciones y usos. Lo que vemos, oímos o leemos puede ser o no ser contenido generado por un ser humano.

Sensores

El mundo del Internet de las cosas, IoT por sus siglas en inglés (Internet of Things) está al alcance de todo el mundo. Basta un poco de electrónica que se puede conseguir por pocos euros y conexión a Internet.

Con un ESP8266 y algunos sensores puedes empezar a jugar. Puedes monitorizar en tiempo real la temperatura y la humedad. En los siguientes gráficos puedes ver en tiempo real las oscilaciones de temperatura y la humedad del suelo:

Este artículo no lo he escrito yo

black and white photo of human hand and robot hand
Photo by Tara Winstead on Pexels.com

Muchas personas piensan que la Inteligencia Artificial es una amenaza para nuestros puestos de trabajo. Estamos ante una nueva herramienta, que necesita por supuesto de normativas de control, pero que más que una amenaza, es un instrumento que potencia nuestras capacidades. No solo las capacidades físicas, como era el caso de las herramientas a las que estamos tan acostumbrados, como pueden ser una excavadora o una cosechadora, sino que ahora podemos potenciar nuestras capacidades cognitivas.

El siguiente ejemplo vamos a ver como un artículo completo puede ser elaborado por una Inteligencia Artificial. Simplemente he partido de la siguiente instrucción:

Instrucciones proporcionadas al modelo de openai

A partir de aquí, todo el contenido está generado por una máquina solo con la instrucción que le he indicado en lenguaje natural.

Texto generado automáticamente hablando del metaverso

«El metaverso es una realidad virtual en la que los usuarios pueden interactuar y experimentar de manera inmersiva.

A diferencia de otros mundos virtuales, el metaverso está conectado a una red global de computadoras, lo que permite que los usuarios de todo el mundo se encuentren y colaboren en el mismo espacio.

A corto plazo, el metaverso podría ofrecer una gran cantidad de oportunidades para el aprendizaje, la investigación y el desarrollo de nuevas tecnologías.

También podría ser utilizado como una plataforma para la creación de nuevos mundos virtuales, que podrían ser utilizados para el entretenimiento, la educación o el trabajo. En el futuro, el metaverso podría convertirse en la principal forma en la que la gente interactúa con la tecnología, y podría transformar la forma en la que se lleva a cabo el comercio, la educación y la investigación.

El metaverso es una idea que ha sido explorada por la ciencia ficción durante muchos años, y ahora está comenzando a convertirse en una realidad. A medida que avanzan las tecnologías de realidad virtual, se está haciendo cada vez más posible la creación de mundos virtuales inmersivos y realistas.

La clave para el éxito del metaverso será su capacidad para atraer y mantener a un gran número de usuarios, y se espera que se convierta en una plataforma muy utilizada en los próximos años.»

¿No os parece fascinante?

Conoce a Cylon y habla con una inteligencia artificial

Robot cylon

Robot cylon

¿Pueden pensar las máquinas?

Podemos decir categóricamente que por ahora no. Lo único a lo que podemos aspirar de momento es a simular algunas características para crear respuestas que se parezcan a las que daría un humano. En este contexto, surgen los bots, chatbots o asistentes virtuales que nos permiten interactuar con una máquina utilizando nuestro propio idioma. Más abajo podrás hablar con una inteligencia artificial.

Cuando tenía unos 5 años, vi una serie que me marcó para siempre. Se trata de Galáctica Estrella de Combate. En esa sería salían unos robots que se llamaban Cylon que se rebelaron contra sus creadores. Es el típico argumento de muchas historias de ciencia ficción, lo sé, pero de cosas sencillas como estas, se van construyendo los sueños y las aficiones. Os dejo un enlace con algunos vídeos sobre esta fantástica serie:

He programado este asistente Cylon para que puedas jugar con él.

En el siguiente frame puedes chatear en español con la inteligencia artificial cylon. Responde a preguntas sencillas como a ¿Qué tiempo hace en Madrid?, ¿Qué es una Galaxia? o ¿Quién es Cristiano Ronaldo?. Recientemente le he incorporado el modelo GPT-3 de open.ai que muestra un comportamiento muy interesante al mantener conversaciones sobre cualquier tema.

Puedes ver otras aplicaciones de GPT-3 en este artículo (este modelo se puede usar para escribir historias sintéticas).

¡Recuerda ser amable con él!, todavía está aprendiendo. 🙂

También lo puedes usar en telegram. Escanea este código QR y prueba conversaciones interesantes con el asistente.

Asistente Cylon para Telegram

Asistente Cylon para Telegram

Ramas de la Inteligencia Artificial

¿Qué es la Inteligencia Artificial?

Pues la verdad es que una pregunta difícil de responder en pocas palabras. Podemos decir es una rama de las Ciencias de la Computación que abarca un gran número de disciplinas y de técnicas. Y como una imagen vale más que mil palabras…

Ramas de la Inteligencia Artificial
Ramas de la Inteligencia Artificial

GPT-3, la Inteligencia Artificial que escribe relatos

Recientemente pude acceder a probar el modelo GPT-3 desarrollado por openai. Se trata de un modelo de lenguaje autorregresivo que usa Deep Learning para generar texto coherente y contextualizado similar al que podría producir un humano. Sus siglas en inglés significan Generative Pre-trained Transformer 3. El modelo ha sido entrenado con diversas fuentes de información disponibles en Internet con una capacidad de 175.000 millones de parámetros de aprendizaje. Se publicó en mayo de 2020 y desde entonces ha generado una gran expectación.

Haciendo algunas pruebas preliminares, resulta fascinante ver cómo es capaz de generar texto a partir de las entradas que se le proporcionan. Es verdad que no siempre obtiene resultados precisos, sobre todo en diálogos prolongados, pero no deja indiferente la fluidez y la «creatividad» con la que genera el texto. Yo me quedé impresionado.

He intentado comprobar la capacidad que tiene el modelo en generar relatos cortos de ficción. Lo primero que hay tener en cuenta es no generar textos demasiado largos para que no empieza a divagar. Además es importante hacer un ajuste equilibrado entre creatividad y conservación del contexto. Si fuerzas demasiado la creatividad, puedes observar cómo pasados algunas párrafos, el texto generado pierde coherencia con respecto a lo escrito en precedencia. En cambio, si fijas valores demasiado rígidos con los que respetar el contexto, a veces se repite demasiado.

La siguiente historia ha sido escrita de forma autónoma por el modelo GPT-3 partiendo de la siguiente frase: «Nuestra historia empezó en Sierra Nevada

A partir de ahí el modelo empieza a escribir el relato que os dejo a continuación sin editar. Por cierto, no tengo ni idea de lo que es «la Jamaspiña». Si alguien se entera por favor comentar, 🙂

Historia generada por GPT-3 sin editar

Nuestra historia empezó en Sierra Nevada. Desde Granada se veía la nieve imponente intermitentemente iluminada por los rayos del Sol. Había que escaparse de la Jamaspiña y los hollín de la Santa Fe foráneos, extirpar con urgencia el agujero negro en donde caíamos sin cesar y ponerse bien al sol de Sierra Nevada.Nada más estar en el pueblo trabajando nos dio por ir a las montañas. Había empezado el invierno. En los primeros días de enero ya había tres paladas de nieve. Lo vieron como una buena opción para disfrutar de las montañas del interior, además de tener dos días francos y poderse llevar el coche hacia allá. Cuatro coches emprendieron la marcha en dirección al pueblo de Pampaneira, a la altura de Granada.Una vez llegados, ya que no era posible que todos pudieran aparcar por la nieve, los sufragistas fueron a buscar un camino alternativo al que tomaran los demás. Montaron las bicis en la parte trasera, tan contentos, pensando que nos divertiríamos un montón. Las tres horas y media de viaje sonaba bien hasta que con la primera carga de nieve a cuestas se desató el problema.Para los amantes de las rutas deportivas de alta dificultad, así como para corredores profesionales, no deja de ser un problema de índole práctica. La situación era que llevaban un buen coche para dos personas. En aquel momento se lesionaron mis pequeñas neuronas. Yo es que soy incapaz de pensar mientras manejo. Ni siquiera puedo mirar hacia el radio y, por tanto, no tengo manos libres para escribir. La idea es que si mi cabeza no pensaba ya, mis rodillas tampoco. Sin embargo, a pesar de todo lo así evidente, me mandé una pregunta del carajo: – ¿Cómo hacemos para llevar a cuatro personas en este coche?A pesar de buscar entre cientos de posibilidades nos quedó la opción más sencilla: nos cogeríamos de las faldas de los sacos de dormir. Sin apenas darse cuenta, comenzaron a soltar faldas y nos cogimos a dos de ellas, con lo que quedaba una que estaba por el suelo, sobre la nieve. ¿Y si hiciera el amor con un saco de dormir? – ¡Coño! ¿Uh? ¿Cómo qué pasa? Para cualquier enfermo mental, el cara a cara con lo que se ve en la foto seguiría siendo un motivo más para pedir su ingreso inmediato.De ese modo salimos del pueblo y nos dirigimos rumbo a la Sierra Nevada. La nieve estaba nevando con mucha fuerza y además teníamos que hacer piloto automático porque había bastante hielo en la carretera. Bajar puntito de velocidad nos quedaba mal, así que en los momentos en que no había manera de avanzar más teníamos que frenar. Con la nieve caída parecía que el cielo cubre la Sierra Nevada con un gran cojín blanco y, estando ya muy cerca, llegamos a una altura en la que empezaron a verse las sierras nevadas y ese paisaje se agradece enormemente. Esas sierras te hacen pensar si es verdad lo que dicen de los árabes. No sé por qué, pero pensé que si tenían un poquito de influencia en alguna patochada del mundo le habría tocado a la nieve su turno.Así empieza otro sueño a seis manos. Al poco de iniciar el descenso nos detuvimos porque cambiamos entre mi hermana y yo los sitios porque se comunicó que, desde el asiento de atrás, podía pilotear bicicleta por la Sierra Nevada con bastante eficacia. A mitad del trayecto nos dimos cuenta de que la gente estaba un poco más rellena de lo normal pero los encontramos divertidísimos. Se nos había quedado lo mismo el primer refugio por el que pasamos, a pesar de que acabábamos de entrar en la Sierra Nevada con la nieve recién cayendo y llevábamos dos sacos de dormir para cuatro personas. ¿Para qué vamos a opinar si nos dan comida gratis?



No perdáis de vista que este texto lo ha generado una máquina a partir de una simple frase. Como podéis ver, aunque puede ser una buena base para escribir una historia, le faltan los retoques y el ajuste que por ahora solo un humano puede hacer. Por lo que no os preocupéis, Skynet queda todavía un poco lejos.

Os dejo ahora como quedaría la historia modificando algunas cosillas.


Historia generada por GPT-3 con algún retoque

Nuestra historia empezó en Sierra Nevada. Desde Granada se veía la nieve imponente intermitentemente iluminada por los rayos del Sol. Había que escaparse de Santa Fe, extirpar con urgencia el agujero negro en donde caíamos sin cesar y salir libres al sol de Sierra Nevada. Desde los primeros días que llegamos al pueblo a trabajar nos dio por ir a las montañas. Había empezado el invierno. En los primeros días de enero en algunos lugares ya había tres metros de nieve. Lo vimos como una buena opción para disfrutar de la naturaleza y cada vez que conseguíamos un par de días libres nos montábamos en el coche para salir a la montaña. En esta ocasión cuatro coches emprendieron la marcha en dirección al pueblo de Pampaneira, en las Alpujarras granadinas. Cuando llegamos, no era posible que todos los coches pudieran aparcar por la nieve, así que fuimos a buscar por otro camino alternativo al que tomaran los demás.

El resto, que si consiguió aparcar, estaban tan contentos, pensando que nos divertiríamos un montón. Las tres horas y media de viaje sonaban bien hasta que arreció el temporal de nieve y se desató el problema. Para los amantes de las rutas deportivas de alta dificultad, así como para corredores profesionales, no deja de ser un problema solo de índole práctica. La situación era que llevábamos un buen coche apto para circular por la nieve solo para dos personas. En aquel momento se lesionaron mis pequeñas neuronas. Yo es que soy incapaz de pensar mientras conduzco. Sin embargo, a pesar de la situación evidente en la que nos encontrábamos, me hice en voz alta la pregunta del carajo: – ¿Cómo hacemos para llevar a cuatro personas en este coche? A pesar de buscar entre cientos de posibilidades nos quedó la opción más sencilla: descenderíamos por la ladera nevada agarrados a los sacos de dormir. Sin apenas darnos cuenta, estábamos los dos deslizándonos a toda velocidad por la pendiente. El saco quedaría destrozado. Y yo que me lo había traído para poder hacer el amor con intimidad. – ¡Coño! ¿Uh? ¿Cómo? Para cualquier enfermo mental, la imagen que se proyectaba en mi mente como si de una foto real se tratara, seguiría siendo un motivo más para pedir su ingreso inmediato.

De ese modo tan expeditivo salimos de la montaña nevada y nos dirigimos rumbo al pueblo. La nieve caía con mucha fuerza y además teníamos que conducir muy despacio porque había bastante hielo en la carretera. Bajar un puntito de velocidad no era una opción, teníamos unas ganas locas de llegar a la casa rural.   Hasta que hubo un momento en el que no había manera de avanzar más y tuvimos que parar. Con la nieve caída parecía que el cielo cubre Sierra Nevada con un gran cojín blanco y, estando ya muy cerca de la casa rural, llegamos a una altura en la que empezaron a verse todos los picos nevados y ese paisaje se agradece enormemente. Esas sierras te hacen pensar si es verdad lo que dicen de los árabes. No sé por qué, pero pensé que si tenían un poquito de influencia en alguna patochada del mundo le habría tocado a la nieve su turno. Así empieza otro sueño sin sentido. Al poco de iniciar de nuevo el descenso nos detuvimos para intercambiarnos los sitios.


El siguiente reto es descubrir que usos reales podría tener y en que escenarios se podría crear un producto o servicio que incorpore estas capacidades cognitivas. Esta tecnología no encierra ningún peligro, pero sí que se tiene que aplicar con criterios éticos y siempre en favor de las personas. Seguiremos atentos a la evolución de este espectacular modelo de Deep Learning.

Una inteligencia artificial de «verdad»

¿Cómo sería un sistema nervioso artificial? Normalmente pensamos en desarrollar una inteligencia artificial, igual a la inteligencia que podemos exhibir los seres humanos, es decir, contenida en algún objeto antropomorfo, donde todos los elementos están presentes en un mismo cuerpo. Nosotros, por ejemplo, tenemos un cerebro que se encarga de tomar decisiones y analizar la información que le proporcionan nuestros sentidos. Actuamos en nuestro entorno a través de nuestro sistema motor y utilizamos la voz para relacionarnos con otras personas.

Sistema nervioso artificial

Una inteligencia artificial que contenga todos estos elementos integrados en un solo objeto y que no tenga conexión con ningún sistema exterior de apoyo es, por ahora, ciencia ficción. Lo que sí podría ser más fácil de conseguir, es lo que podríamos llamar un sistema de IA globalizado. Este ente sería la agregación de multitud de sistemas repartidos por todo el planeta donde la capacidad de computación equivalente al sistema nervioso central estaría en grandes servidores que consumen además una gran energía. Cómo sentidos podríamos hablar de cualquier dispositivo IoT o interfaz con el mundo físico que permita la captura de información.

Internet actuaría como los nervios que conectan los sentidos con la capacidad cognitiva. Sería el vertebrador de esa IA global.

Ya disponemos de algunos servicios y aplicaciones que actúan de forma similar, como por ejemplo los servicios cognitivos de Microsoft, la plataforma de IBM o algunas de las aplicaciones de Google. Podemos analizar una imagen, un texto o la voz para extraer información y tomar alguna decisión de clasificación o de actuación.

De forma aislada hemos conseguido empaquetar muchas funciones cognitivas que en actividades puntuales mejoran con creces la eficiencia que podemos adquirir las personas. Aplicando fuerza bruta y los redescubiertos algoritmos de aprendizaje automático somos capaces de clasificar imágenes con un nivel de precisión impensable para un humano. Podemos analizar la voz y transcribirla a texto para después traducir el texto a otro idioma y somos capaces de generar una cantidad de información difícil de imaginar.

Sin embargo un niño de 3 años ve unas cuantas imágenes de un gato y es capaz de reconocer en poco tiempo y sin costosos procesos de entrenamiento cualquier otro gato y quizás hasta dibujar alguno. En cambio, una máquina necesita ser entrenado con miles o millones de imágenes para conseguir el mismo resultado. Obviamente una vez superada está fase de entrenamiento la máquina podrá clasificar mucho más rápido y mejor cualquier imagen. El símil sería como si un humano antes de reconocer un objeto tuviera que ser enseñado visualizando millones de imágenes. ¿Qué mecanismos entran en juego en el cerebro de un niño para poder aprender tanto en tan poco tiempo? Parece que la estrategia pasa por sacrificar precisión y rapidez por flexibilidad y adaptación.

Las últimas grandes fronteras del conocimiento que nos quedan por explorar son a nivel macroscópico, el cosmos y su origen y a nivel infinitesimal el mundo de la física cuántica y la descripción de la materia y la energía con las que se construye el mundo en el que vivimos. Resulta paradójico que el conocimiento de algo tan íntimo y ligado a nosotros como es nuestro cerebro, albergue todavía tantas lagunas de conocimiento. Posiblemente derivado del conocimiento de nuestro cerebro se descubra algún nuevo enfoque o heurística para llegar a recrear un estado de consciencia artificial o llegar a producir hilos discursivos de pensamiento. Hasta ahora almacenamos y procesamos información haciendo un uso de recursos brutal en comparación con lo que hace nuestro cerebro con unos pocos gramos de materia gris y usando solo la energía que somos capaces de extraer de los alimentos que ingerimos.

Los próximos avances tendrán que venir como consecuencia de la inversión en investigación fundacional sobre el funcionamiento de nuestro cerebro, con la que poder, una vez más, emular a la naturaleza. Esperamos ansiosos a ver cuál será el siguiente gran salto en nuestro camino de descubrimiento y en nuestro voraz apetito por conocer.

Hace ya algunos años, en la Universidad de Granada pude aprender sobre los algoritmos genéticos, una técnica algorítmica inspirada en las leyes de la evolución y que reproduce el mecanismo genético para resolver problemas de optimización y búsqueda en espacios de soluciones que por su complejidad no son calculables por otras soluciones algorítmicas.

Imaginemos ahora un sinfín de capacidades cognitivas aplicadas a contextos muy limitados . En esta situación, ¿qué es lo que determina el éxito o la bondad de las respuestas o soluciones de cada una de esas capacidades? Actualmente ese criterio se obtiene de forma externa a la propia capacidad cognitiva a través de la voluntad del programador que la ha implementado. No hay voluntad, criterio o digámoslo de otro modo, conciencia o motor vital para actuar o dirigir acción alguna.

¿Podríamos llegar a aplicar el mecanismo de la evolución usando las mismas técnicas usadas en los algoritmos genéticos? Para ello tendríamos que comprender que función objetivo gobierna la propia evolución de la vida. En problemas sencillos es fácil buscar la formulación matemática para calcular como de bueno es el código genético que representa cada solución. Pero si tratamos de explicar si existe algún patrón que explique la aparición de la vida, solo llegamos a justificaciones probabilísticas en las que no llegamos a comprender o a tener evidencias de si existe alguna propiedad o ley universal que facilite la formación de vida.

Si vamos un poco más atrás, ¿qué es exactamente la vida? En la definición que nos dieron en la escuela, es todo aquello que nace, crece, se reproduce y muere. Con esa definición, ¿no están acaso las ideas vivas? Con el pensamiento clásico diríamos, que no pueden ser vida, puesto que para poder vivir, las ideas, necesitan de otros organismos para poder vivir y reproducirse, y eso se acerca más a la definición de parásito o virus.

Darwin estableció que la función objetivo de la vida y por lo tanto su motor dinamizador, no es más que la capacidad de perdurar en el tiempo. A eso lo conocemos como las leyes de la evolución.

Si queremos hablar de vida artificial y no solo de meros artificios o herramientas creadas por  el hombre, tendríamos que dotar a esa vida artificial de libertad y la capacidad de implementar la función objetivo equivalente a las leyes de la evolución. En cambio las leyes de la robótica de Isaac Asimov hacen justo lo contrario, limitan esa libertad subyugándola a los intereses de los humanos. Esto nos lleva a decir que con este enfoque lo que estamos haciendo es limitando la capacidad de que surja una verdadera vida artificial. Quizás sea lo más sensato para todos que siga siendo así.