Thursday, 29 October 2009

Cálculo de rutas de transporte parte IV

En ésta entrega, hago el primer desarrollo profesional de mi framework VLO sobre un ejemplo real para el cálculo de rutas. Como ya sabéis, el VLO framework es una plataforma de desarrollo desarrollada en Delphi 2010 que pretende obtener un vínculo gráfico con un Objeto. De ésta manera esa porción de memoria que estamos utilizando se está representado en pantalla utilizando una serie de conceptos gráficos. Llevo trabajando en éste proyecto unos 2 meses y medio y como podéis ver, si se planifica bien el trabajo, se tienen las ideas claras y partimos con un buen background en orientación a objetos y diseño utilizando patrones podemos crear herramientas increíbles.

Luego vino la implementación de la plataforma sobre ejemplos reales, al principio podía crear diagramas de grafos y calcular la ruta más corta utilizando Dijkstra. Después le di una parte mucha más gráfica y implementé un sistema multi capas para poder disponer de texto, imagen y caja en el mismo componente. A partir de ahí y con otras muchas ideas (gracias a los morning pages) apareció el cálculo de rutas. Hace ya bastantes años que me dedico al sector de la automatización industrial y la mayoría de aplicaciones que desarrollo son para cumplir los requisitos que necesitan éste tipo de industria.

Por lo tanto, continuando con ésta última versión de la aplicación, veréis que hay un pequeño cambio y es que ahora ya tengo implementado el algoritmo para reconocer scada's (Vijeo Citect) utilizando la Graphics Builder Automation Interface, y aquí ya vi un filón.

¿En qué consiste ésta última versión?. Pues bien, si disponemos de un diagrama real de Scada, por ejemplo como el siguiente:

Podemos ver una configuración típica donde se transporta el producto desde unos silos de origen a unos recipientes destino. Ahora lo que hay que hacer, es escanear la librería de "Genies" (Objetos del Vijeo Citect) con Thundax Genies Scanner y volcar los datos en la ubicación de los resources de Thundax Box Manager (para que disponga de todas las imagenes de la librería y así poder representar las boxes con la imagen correcta).

Una vez escaneada una librería como la presentada en la imagen, ya podemos iniciar Thundax Box Manager y escanear la pantalla del Scada con la aplicación utilizando la librería de automatización. Sobretodo antes, visualizar en las opciones de la aplicación Thundax Genies Scanner la ubicación de los resources:


Ahora, iniciamos Thundax Box Manager, y con la pantalla seleccionada del Scada, nos dirigimos al menú Citect -> Load Page Diagram, y en pocos segundos, tendremos cargada la misma estructura en mi aplicación (solo las genies, los símbolos no, porque no representan ninguna estructura de control, es decir, no tienen ninguna lógica dentro del proceso):

Ahora solo tenemos que perder 15 segundos en realizar las conexiones lógicas entre elementos o ítems y luego calcularemos las rutas:

Tenemos que acordarnos de marcar cuales son los orígenes y cuales los destinos:

Ahora entenderéis el concepto de "Bloqueo o Interlock" con la siguiente imagen:

Si os fijáis el producto pasa por la cinta superior, y hay 2 válvulas que sacan el producto. Pero tenemos que tener en cuenta que solo se puede abrir 1 a la vez, ya que sinó enviariamos producto a un destino diferente al requerido. Por lo tanto debe estar bloqueada la otra válvula y no abrirse durante la ejecución de la ruta seleccionada. De ahí que exista el objeto "interlock", y que se gestione en el cálculo de la ruta de transporte.

Ahora solo tenemos que ejecutar "Citect -> Calc Transport Routes" et voilà!, ya tenemos generadas las 100 rutas disponibles que hay en menos de 100 ms.


Además podemos ver la ruta seleccionada haciendo click en la ruta:

Aún quede mucho trabajo por delante, pero me lo tomo con mucha ilusión al ver que por fin el programa tiene una meta asequible: Crear rutas de transporte para que otro programa pueda trabajar con éstas y ejecutarlas. Lo interesante de todo ésto es que podemos ahorrar un montón de tiempo intentando averiguar la cantidad de rutas que tenemos y sobretodo intentar el poderlas implementar gráficamente manteniendo como expliqué hace 2 meses un mapa lógico sobre una estructura que carece de inteligencia.

Aquí os dejo las últimas versiones de mi aplicación:
He cambiado la privacidad de la aplicación y de momento la he hecho "trial de 30 días" esperando crear un paquete más completo con sus diferentes opciones. Espero que la lectura haya sido entretenida!.

Wednesday, 28 October 2009

Cálculo de rutas de transporte parte III

Continuando con los artículos sobre el tema del cálculo de rutas, aquí os dejo la última versión estable y mejorada sobre un ejemplo un poco más complejo y más real para diferentes destinos y con bloqueos entre elementos. El término bloqueo significa que no puede existir una ruta sin antes bloquear una serie de elementos. Éstos se tienen que vigilar, entre sí, ya sea por un equipo inteligente u otro tipo de algoritmo o aplicación. En éste ejemplo veréis como puede llegar a complicarse un sistema de rutas:

Si nos fijamos bien, existen muchos destinos y además existen bloqueos entre caminos (representados por un nuevo concepto de símbolo):


¿Ésto que indica?. Nos indica que los 4 elementos están bloqueados entre sí, y para no dibujar (n-1) flechas entre los diferentes objetos, creamos uno diferente que creará automáticamente el enlace con las demás cajas. De ésta manera cuando se cree el camino que pase por el elemento 4, éste llamará a la caja superior y recogerá los 3 elementos que tiene para introducirlos en la descripción de la ruta.

De ésta manera obtenemos lo siguiente:


Aquí os dejo la última versión de la aplicación más los ejemplos hasta ahora hechos. Éste último ejemplo lo he hecho en menos de 3 minutos, y el cálculo total de rutas en un total de 16ms.
PD: Ésta última versión está protegida con mxProtector y solo permitirá 10 ejecuciones. De momento tengo que poner ésto ya que no es una versión definitiva y no quiero que corra por la red sin antes tener montada una buena base. Además, ahora ya empieza a hacer cosas importantes.

Monday, 26 October 2009

Cálculo de rutas de transporte parte II

Continuando con mi anterior artículo, he mejorado el algoritmo de búsqueda de caminos, de tal manera que ahora permite la búsqueda de un sinfín de posibilidades con tiempos extremadamente pequeños. En la versión anterior me di cuenta de que había un problema con el diseño del algoritmo y era referente a que a la hora de buscar los nodos adyacentes, éstos tienen que estar ordenados por el número de conexiones entrantes que tienen. De ésta manera podemos calcular cosas tan complejas como éstas:

A simple vista parece ser bastante difícil el obtener el número de caminos disponibles pero al final acaba siendo un simple recorrido de nodos:

Como podéis ver en la última imagen, hay 31 rutas disponibles. Además, en ésta última versión, ya está resuelto el problema de multi-orígenes y multi-destinos de tal manera que el algoritmo ya es capaz de recorrerlos todos con un coste cuadrático. Hay que mejorar un poco el coste pero estamos hablando de hacer el cálculo de unas 30 rutas en unos 16 mili segundos.

Si nos fijamos en la siguiente imagen, podréis ver la resolución con múltiples orígenes y múltiples destinos:

Si os fijáis en la imagen también queda marcado el camino seleccionado en la grid, de ésta manera visualmente podemos reconocer la ruta seleccionada y comprobar que los cálculos estén correctamente realizados.

El cálculo ahora es bastante diferente de como se hacía en el artículo anterior. Se me ocurrió la idea de realizar la búsqueda a través de la tabla de adyacentes sin tener que hacer antes un barrido. De ésta manera realizando una serie de operaciones que ahora detallaré, tenemos resuelto el problema del cálculo de rutas de transporte.

Con el siguiente código realizamos el recorrido total de la lista de adyacentes:


fila := 1;
filas := 0;
columna := 1;
for i := 0 to length(AdjacentList) - 1 do
begin
if AdjacentList[i].isSource then
begin
grid[columna, fila] := Inttostr(AdjacentList[i].source);
grid[columna + 1, fila] := Inttostr(AdjacentList[i].destiny);
AdjacentList[i].visited := true;
filas := filas + 1;
fila := fila + 1;
end;
end;

bVisited := false;
while not bVisited do
begin
sum := 0;
for i := 1 to filas do
begin
columna := getLastColumn(i);
SetLength(Connector, 0);
GetList(Connector, AdjacentList, StrToInt(grid[columna - 1, i]));
if Length(Connector) <> 0 then
grid[columna, i] := IntToStr(Connector[0].destiny);
if Length(Connector) > 1 then
begin
newRows := CloneRow(i, Connector);
sum := sum + newRows;
end;
end;
filas := filas + sum;
bVisited := AllRowsFinished(filas, DestinoList);
end;


  • ¿Como funciona?
Primero buscamos los orígenes de la lista de adyacentes y los situamos en la grid, por ejemplo:
1 2
1 3
Luego recorremos ésta lista buscando los adyacentes de los últimos nodos, 2 y 3. Por lo tanto encontraremos que el 2 estará conectado con el 4 y el 5 y el 3 solo con el 6. En el momento que tenemos que añadir el valor 4 detrás del 2, si vemos que hay más conexiones, realizamos un clonado de la línea que estamos tratando y insertamos el siguiente valor en la línea clonada:
1 2 4
1 3
1 2 5 (clonado)
Continuamos con la siguiente fila:
1 2 4
1 3 6
1 2 5
Ahora, tenemos que volver a empezar y volver a añadir las conexiones de los nodos posteriores e ir clonando las diferentes filas hasta llegar al final:
1 2 4 8
1 3 6 7 8
1 2 5 8
1 3 6 8
De ésta manera tan fácil conseguimos construir la lista de rutas de transporte, siempre teniendo en cuenta los diferentes orígenes y destinos que nos podemos encontrar.

Podéis descargar la última versión de la aplicación con los ejemplos aquí:
PD : Para la ejecución del algoritmo correcto, hay que ir al menú Citect -> Calc Routes 2 una vez el diagrama está abierto.

Friday, 23 October 2009

Cálculo de rutas de transporte parte I

Después de unos días muy ajetreados y con mucho trabajo (y que no falte) he podido medio acabar la primera aplicación profesional sobre mi framework. Ésta se trata sobre el cálculo de rutas. He utilizado diversos tipos de algoritmos para su recorrido y búsqueda de diferentes caminos para obtener la ruta de un origen a un destino pasando por una serie de nodos. Luego vincularé la búsqueda de éstas rutas con mi anterior aplicación Thundax Genies Scanner y así poder crear mapas mentales de aplicaciones Scada para la búsqueda de caminos automáticos. En que consiste ésta idea?

Como podéis ver en la siguiente imagen:

Disponemos de un origen marcado en verde y un destino marcado en fucsia. Con mi framework he generado el diagrama y aplicado diversas propiedades a las diferentes cajas y conectores. El problema que se presenta, es el de calcular las diferentes rutas que hay de un punto a otro y guardarlas en algún sitio para poder utilizar éstos datos y evitar sobretodo el cálculo manualmente. Poco a poco, os iré explicando la utilizad de ésto y el propósito de su cálculo.

Por lo tanto, si nos fijamos en la imagen existen 2 rutas para ir del origen (1) al destino (19):

Así, calcularíamos:
RUTA1: 1-4-8-11-19 RUTA2: 1-5-9-11-19
  • ¿Dónde está la complicación aquí?
Parece fácil, no?. Pues no lo es. Es un problema bastante complicado a la que empiezan a haber cruzamientos entre nodos. Si aparecen diversas conexiones entre sí, el numero de combinaciones empieza a crecer exponencialmente.

Si observamos mi aplicación, veremos como se calculan las rutas automáticamente:

Ahora un ejemplo más real:

Como podéis comprobar, son los mismos nodos, pero ahora tenemos 7 rutas disponibles!.

El cálculo de sus rutas es el siguiente:

Aún estoy acabando de perfilar el algoritmo y calculando sus diferentes costes para una mejora en su rendimiento. Dentro de poco tendré disponible la versión para búsqueda de rutas con múltiples orígenes y múltiples destinos. Y poder realizar la búsqueda de rutas de diagramas como el siguiente:

Si os fijáis, incluso he creado un tipo de enlace nuevo con la imagen de una cadena. Éste enlace consiste en un enlace de bloqueo donde los nodos están fuertemente vinculados y también se tienen que tener en cuenta a la hora de escribir la ruta de transporte. Ésto significa que si queremos pasar por un nodo de éstos, el otro debe aparecer bloqueado (en términos de fluidos seria cerrar uno de los caminos).
  • ¿Cómo funciona el algoritmo?
El algoritmo que he creado es del tipo backtracking recorriendo los diferentes nodos y marcando las rutas visitadas. Lo que hago es crear una lista de adyacentes marcando la cantidad de conexiones que tiene cada nodo.

Primero calculo los orígenes y destinos en función del color de la caja:


for i := 0 to boxlist.count - 1 do
begin
if boxlist.items[i].properties.fillColor = clLime then
SetArrayValue(OrigenList, StrToInt(boxlist.items[i].properties.getText));
if boxlist.items[i].properties.fillColor = clFuchsia then
SetArrayValue(DestinoList, StrToInt(boxlist.items[i].properties.getText));
end;
Luego, nos centramos en calcular la lista de adyacentes en función del tipo de conexión. Además existe una lista de bloqueos en función del tipo de conector utilizado:


for i := 0 to connectorList.count - 1 do
begin
conn := connectorList.items[i];
pos1 := StrToInt(conn.SourceBox.properties.getText);
pos2 := StrToInt(conn.TargetBox.properties.getText);
if not conn.Line.ClassNameIs('TAbstractDottedDoubleLinkedArrowLine') and
not conn.Line.ClassNameIs('TAbstractSimpleDoubleLinkedArrowLine') then
SetAdjacentValue(AdjacentList, pos1, pos2)
else
begin
SetAdjacentValue(InterlockList, pos1, pos2);
SetAdjacentValue(InterlockList, pos2, pos1);
end;
end;


El siguiente paso es marcar los diferentes nodos con su peso marcado por la cantidad de nodos conectados a un nodo.


for i := 0 to length(AdjacentList)-1 do
begin
AdjacentList[i].weight := getWeight(AdjacentList, AdjacentList[i].source);
if AdjacentList[i].weight = 1 then
AdjacentList[i].unique := true;
end;


Esto nos permite crear un diagrama con la siguiente información:



function TfrmMain.ExamineNodes(firstNode: integer; lastNode: integer; AdjacentList: TAdjacentArray): string;
var
nodeVisited: integer;
res: TArrayInteger;
i: integer;
father: integer;
begin
nodeVisited := firstNode;
father := nodeVisited;
while (nodeVisited <> lastNode) do
begin
res := GetConnections(AdjacentList, nodeVisited);
if length(res) = 0 then exit;
for i := 0 to length(res) - 1 do
begin
nodeVisited := res[i];
if isVisited(AdjacentList, father, nodeVisited) then
begin
visit(AdjacentList, father, nodeVisited);
setRoute(nodeVisited, father);
ExamineNodes(nodeVisited, lastNode, AdjacentList);
end;
end;
end;
end;


Cómo podéis ver el algoritmo es bastante simple pero se puede mejorar bastante. El coste de calculo es O(n2) para visitar todos los nodos. Aquí os dejo la última versión de la aplicación ThundaxBoxManager v2.3.0 build 57 con los diagramas de ejemplo. Para si resolución hay que ir al menú Citect y allí ejecutar la opción Backtracking2.


Wednesday, 21 October 2009

Worlde

No me he podido resistir a la utilización de Worlde, una herramienta para crear nubes de etiquetas sobre un texto cualquiera. Lo he encontrada mientras leía los feeds del blog, en el blog de José manuel beas. Ésto es lo que he obtenido al introducir mi blog:

La verdad es que es muy bonito y sirve para destacar las diferentes palabras que podemos encontrar en los artículos escritos.

Monday, 19 October 2009

This is your brain!

"¡Nuestro cerebro es un desastre!", así empieza éste artículo en el que daré unos pequeños detalles y varios puntos de vista desde mi experiencia del órgano inteligente identificando las diversas partes del cerebro y su funcionamiento básico. El conocer éstos conceptos básicos nos ayudará a obtener un mejor aprendizaje sobre cualquier materia y utilizando las herramientas que todos tenemos a entrenarnos. Si nos fijamos bien, podríamos modelar nuestro cerebro en un modelo simple con 2 CPU's y un bus compartido para el acceso a memoria, como podéis ver en la imagen de la derecha. Disponemos de 2 partes diferenciables la izquierda y la derecha. Algunos de sus aspectos básicos son:



Left Side:

Es la parte con la que estamos habituados a tratar, es muy lenta (hablamos de unos 100 bps), es secuencial, verbal, analítica y lógica.
Right Side:
Esta parte es la gran desconocida, dispone de un bus compartido para acceder a la memoria y rescatar nuestros recuerdos, es no lineal y ultra rápida. Dispone de un motor de búsqueda muy potente con el que consigue recuperar los datos de memoria. Ésta es más interesante que la L.S y es la que deberíamos aprender a utilizar. Es no verbal, no racional, sintética, creativa e intuitiva.
La parte derecha procesa todos esos datos de los que no eres consciente. ¿No os ha pasado alguna vez que intentáis acordaros del nombre de alguien y no os sale? y al cabo de un rato os aparece de repente cuando no intentáis pensar en eso? pues bien, ésto es lo que hace la parte derecha. Otro ejemplo es el de intentar explicar lo que os ha ocurrido en un sueño, o sea, de ponerle palabras. El sueño se genera en la parte derecha del cerebro y cuando intentamos explicarlo nuestra parte izquierda recupera los datos de la memoria y no hay nada. Por eso es complicado explicar los sueños que tenemos.

Como podéis comprobar el entender la parte derecha es fundamental para nuestro avance en la adquisición de conocimientos. Dos de los temas que os recomiendo leer del libro son : "Don't dissect a frog. Build One!", y "learn from sintesis insteaf of analisis". Donde se nos muestra la importancia del cómo aprender. El primer problema que se presenta es el de no diseccionar una rana y crear una nueva (si no sabemos como algo funciona, no intentemos remover las entrañas de algo para saber como funciona, intenta crearlo desde cero, será mucho más fácil). El segundo nos cuenta que es mejor aprender de la síntesis que del análisis.

¿Cómo podemos trabajar con R-mode?
Lo principal es entender que la parte izquierda es la que siempre quiere tomar el control, nos manda símbolos y quiere que pongamos nombres a las cosas. La parte de control del tiempo también la domina la parte izquierda. Por lo tanto, debemos evitar todas éstas cosas para que la parte derecha trabaje mucho más. R-mode, no puede generar lenguaje, solo imágenes. Una de las acciones importantes que tenemos que tener en cuenta a la hora de resolver problemas en "Don't think so hard", es decir, si tenemos que resolver un problema complejo, introducimos los datos en nuestra cabeza y luego nos vamos a dar una vuelta o intentamos distraernos con otras cosas que no sean el problema en sí. Veréis que momentos más tarde el problema se resuelve solo "bang" y aparece el resultado en tu cabeza. Eso ocurre porque la parte derecha recibe los inputs i se pone a calcular a toda pastilla y cuando tiene el resultado te lo manda directamente. (El llegar a dominar ésta parte es complicado, pero solo necesitamos un poco de práctica).

Una de las prácticas más interesantes para que nuestra parte derecha salga, es realizar un ejercicio llamado morning pages. ¿En qué consiste? Pues en que cada mañana después de levantarnos (aún medio dormidos) tenemos que escribir 3 páginas de lo que sea, de lo que nos venga a la mente y durante 15 días por ejemplo. Yo os puedo comentar que lo he practicado, y la verdad es que muchas de mis últimas ideas han salido de ahí. A veces nos immersamos en diferentes proyectos, tocamos diferentes programas y muchas veces no somos capaces de ver relaciones entre ellos y al final "bang", aparecen cosas en tu cerebro (buenas ideas) que hay que anotar. Pensad que el 80% del cerebro no es lógico y que muchas de las ideas que tenemos no las tenemos en cuenta.

Otra de las prácticas interesantes es la de llevar siempre una libreta con nosotros y anotar todas las cosas que pensemos por insignificantes que sean. Hay un tema importante que me gustaría comentar y es el de memorizar cosas a corto plazo. Éste echo de memorizar cosas pequeñas (una cita con el médico, una reunión por la tarde, etc) son rutinas en segundo plano para nuestro cerebro y provocan un consumo de energía y recursos muy grande. Por lo tanto, hay que intentar no forzarlo acordándonos de cosas que no son importantes y que podemos anotar en una libreta de citas o en algún sitio que siempre tengamos disponible.

Es importante utilizar nuestro neocortex. En la pirámide de la derecha podemos ver la distribución típica de las ideas. Como veis, ideas tenemos todos y muchas, pero si no les sigues la pista o las guardas, empezarás a no tener más (muy importante). Por eso, si es importante, anotalo!. Aquí os paso también enlaces interesantes para apuntar vuestras notas por Internet: evernote.com y supermemo. Para forzar a nuestra memoria y memorizar mejor, debemos forzar rellamadas a nuestra memoria. Las cosas funcionan de ésta manera a nivel neuronal.

Saturday, 17 October 2009

Tool trap

No se si alguna vez habéis oído hablar sobre la trampa del mono, donde el mono intenta sacar un plátano de un jarrón donde la boca del jarrón es lo suficientemente grande para que entre la mano del mono pero que sea más pequeña que la longitud del plátano. Cuando el mono coge el plátano e intenta sacarlo ve que no puede, pero lo más gracioso es que no lo va a soltar y se va a quedar así un par de días atorado son poder extraer su comida. ¿Qué hace esto tan interesante? El mono está buscando una solución para su problema. Para quitar la mano es necesario completar una serie de pasos, primero debe soltar el plátano y luego sacar la mano, pero su cerebro busca una solución en "one step" que no existe y por eso se queda encallado. Éste mismo principio existe en el mundo de la informática y nuestras herramientas de trabajo.
Muchas veces nos quedamos estancados y anclados a herramientas que no podemos dejar ir de tal manera que acaban siendo "tool traps" donde al final nos acabamos casando con la tecnología que a medio-largo plazo no nos hará ningún bien. Tan importante es darse cuenta de éste fenómeno como darle solución. A veces nos aferramos tanto a algo que no lo podemos dejar ir.

Como dice Andy Hunt en el Pragmatic Programmer (los que me conocéis ya sabéis que éste libro es de obligada lectura) el programar es un "arte", ser programador es un trabajo creativo donde interaccionan la creatividad, la intuición y la invención.

¿Cómo podemos mejorar éstos aspectos? Pues utilizando unas reglas muy simples, primero utilizar modelos para ayudar a entender el problema (de la manera que te vaya bien a ti), segundo, practica a todas horas, utilizar el concepto IAI = Imitate, Assimilate, Innovate. Debes copiar lo que los gurús te cuentan y una vez aprendido intentar ir más allá. Practica a todas horas y poco a poco tu cerebro se irá acostumbrando a ésta manera de pensar, de ésta manera conseguirás pequeñas recompensas que te harán adentrarte mucho más en la práctica.

What's your level skill?

Continuando con el tópico del otro día sobre el modelo Dreyfus de adquisición de competencias, ¿dónde nos situamos en la escala? Tal como nos cuenta Dreyfus para llegar al nivel de experto hacen falta 10 años de estudio sobre un campo en particular o una series de miles horas, por lo tanto te puede llevar un tiempo el conseguirlo. Lo más interesante es que los expertos trabajan por intuición, es decir, ya no siguen las reglas que ellos mismos han creado.
Me gustó mucha la frase "Rules ruin Experts and lack of rules ruins novices", especificando que los expertos no trabajan sobre guiones y la gente con poca experiencia sí. Os recomiendo pasar por los capítulos donde se habla de "Don't try to race sheep and Don't try to herd race horses" y trata éstos temas sobre no saber enfocar bien a tu equipo según su experiéncia.

Otro de los temas hablados fue el modelo que tenemos para la adquisición de conocimientos en nuestros trabajos. Hay un libro muy interesante donde se muestra el modelo sobre diferentes tipos de trabajos, y normalmente donde se diferenciaban éstos era en los servicios médicos. En los hospitales tienen un buen sistema para la mejora de tu formación. Cuando alguien entra, normalmente tiene que pasar unos años de residente adquiriendo responsabilidades y capacidades de forma continua y tutelada. ¿Os imagináis como seria ésto de diferente no hiciera falta obtener toda ésta experiencia?. Es como si de repente saliesen de la carrera y te pudiesen operar directamente. Pues bien, eso mismo pasa con nosotros los ingenieros. Salimos de la universidad y cuando llegamos al entorno laboral no nos preparar adecuadamente. Y sin experiencia no puedes apreciar el contexto.

Para una buena adquisición de conocimientos es bueno de disponer una buena estructura de aprendizaje, de intentar aprender aquello que no sabes, de testear tus hipótesis y de empezar a manejar tu intuición. Os recomiendo un libro de Patricia Benner que trabaja todos éstos temas en profundidad: From novice to Expert.

Friday, 16 October 2009

Instalando VLO Framework

Aun estoy ultimando detalles del framework y he integrado éste en el IDE de Delphi. La plataforma consiste en un conjunto de librerías las cuales el usuario final no necesita como funcionan internamente. Simplemente se instala la plataforma de desarrollo en el IDE y se empiezan a utilizar las clases necesarias para el dibujado de los objetos sobre un canvas. Ahora cuando iniciamos el Delphi, podemos ver:

Aun tengo que mejorar el Icono, pero de momento es provisional y meramente informativo para indicar que existe el framework dentro del IDE. El aspecto interno es el siguiente:

Luego una duda que nos puede aparecer es, ¿Cómo puedo hacer para que aparezca el logotipo del package en el Splash screen del Delphi?. Muy fácil, aquí os lo explico:

Una vez tenemos creado nuestro package, tenemos que crear un fichero de recursos que contendrá el logo que queremos que se visualize en el splash del delphi. En mi caso lo he llamado ThundaxVLO.res y he utilizado el XN Resource Editor para crearlo:


Utilizando ésta herramienta gratuita y open source, podemos crear nuestros ficheros de recursos e insertar las imágenes que queramos. Para la conversión de ficheros BMP a ICO he utilizado una aplicación freeware llamada ImageIcon 3.0. Una vez tenemos todos los ficheros necesarios, creamos una nueva unidad en nuestro package que incluirá el procedimiento de registro de los recursos y forzará el incrustado de la imagen en el splash inicial:


unit ThundaxFramework;

interface

{$I JEDI.INC}

procedure Register;

implementation

uses DesignIntf, DesignEditors, Graphics, ToolsAPI;

{$R ThundaxVLO.res}

procedure Register;
{$IFDEF DELPHI10_UP}
var
lBitmap: TBitmap;
Service: IOTAAboutBoxServices;
{$ENDIF}
begin
{$IFDEF DELPHI10_UP}
ForceDemandLoadState(dlDisable);
lBitmap := TBitmap.Create;
try
lBitmap.LoadFromResourceName(hInstance, 'LOGO');
if Assigned(SplashScreenServices) then
SplashScreenServices.AddPluginBitmap('VLO Framework v1.0 ', lBitmap.Handle);
BorlandIDEServices.GetService(IOTAAboutBoxServices, Service);
if Assigned(Service) then
Service.AddPluginInfo('Thundax Software',
'VLO Framework v1.0 ' + sLineBreak + 'Thundax Software', lBitmap.Handle);
finally
lBitmap.Free;
end;
{$ENDIF}
end;

end.


El fichero {$I JEDI.INC} nos interesa para obtener la directiva DELPHI10_UP y saber si estamos ejecutando una versión superior o no, de esta manera se muestra o no el logo en el inicio.

De ésta manera podemos ver también el framework instalado en el About del Delphi:


Espero que os sirva de ayuda!.

Thursday, 15 October 2009

Tuesday, 13 October 2009

be more productive!

Uno de los topics que comenta el Pragmatic Thinking and Learning es el tema de aumentar la productividad. Y una de la maneras más rápida de aumentar ésta (hablo de alrededor de un 40% más) es utilizar 2 monitores (Si podemos con más pues mejor!). Hay varios estudios científicos que demuestran éste incremento de la productividad e incluso microsoft hizo el suyo. Si no podemos disponer de 2 monitores una buena solución es utilizar un escritorio virtual y poder disponer de 4 escritorios y cambiar a cada uno de éstos con una simple combinación de teclado.

Aquí os presento una aplicación interesante: VirtualWin una herramienta open source para la virtualización del escritorio (Virtual Desktops). Su instalación y configuración es bastante simple y el único problema que me he encontrado ha sido el de registrar sus hotkeys, que coinciden con mis hotkeys de la tarjeta gráfica. Una vez instalado, veréis en la barra de tareas en la zona de notificación el siguiente icono: el cual nos muestra el escritorio seleccionado. Con las hotkeys configuradas podemos navegar por éste escritorio virtual:

La verdad es que encuentro ésta aplicación muy útil y puedo disponer de varios entornos de trabajo con solo una combinación de teclas (zona de pruebas, redacción de informes, Internet, etc) y me puedo centrar en ése escritorio sin que nada me distraiga. Tengo que destacar el trabajo realizado por Johan Piculell, Steven Phillips y Eric Pierce que han realizado un trabajo increíble.

Context REALLY matters.

Ésta es una de mis primeras aportaciones sobre el certificado en "Pragmatic Thinking and learning". La verdad es que el curso está muy bien, muy bien estructurado y sobretodo vale la pena si te quieres llevar un libro dedicado por el mismísimo Andy Hunt (ésto no tiene precio aunque el curso es un poco caro...los primeros solían costar unos 800 dolares, éste que fui a hacer en Londres ronda las 400 libras). El único problema que tengo ahora, es que tengo 2 libros del "pragmatic thinking and learning" y si le interesa a alguien se lo dejo a buen precio!.

Andy empezó hablando de lo importante que es el "contexto". Cuando desarrollamos software siempre hay que fijarse en el contexto y en sus relaciones, de aquí la importancia y la referéncia que hace Andy sobre los mapas mentales:


También hizo hincapié en el Pair programming, una técnica muy útil y muy productiva pero que hoy en día las empresas no ponen en uso. Se suele utilizar el ejemplo de "driver" y "navigator" donde el driver es el que tipea el código y el otro piensa y reconoce los diversos patrones que pueden ir surgiendo dentro de la aplicación. De ésta manera se tiene una visión mucho más global sobre el problema.

Una de las partes que más me sorprendió, es que creó una relación entre el contexto, los patrones y la neuroplasticidad. ¿Y qué es esto de la neuroplasticidad?. Diversos estudios han demostrado que realmente si que podemos generar nuevas neuronas. Disponemos de más de 100.000 millones de neuronas y éstas se van degradando a lo largo de la vida, pero resulta que ahora podemos cambiar nuestro cerebro. Reconectar los enlaces neuronales depende en lo que tu piensas, por eso el contexto importa. "Always consider the context". Aquí os dejo una presentación entretenida sobre neuroplasticidad para quien quiera profundizar más en el tema:
Dreyfus Model:
Este modelo lo comenté en su día hace unos meses donde explicaba como funciona la adquisición de competencias. Hicimos un repaso sobre los diferentes tipos (Novice, Advance Beginner, Competent, Proficient and Expert) y vimos las diferencias entre éstos y donde nos ubicaríamos cada uno de nosotros. Cosas importantes que comentó: Si tienes un equipo de trabajo donde la mayoría son Advance Beginner y quieres sacar aún más provecho de éstos, alquila un Coach para hacer que tu personal suba un nivel más sobre la escala Dreyfus.

Un pequeño repaso sobre los diferentes niveles:

Novice:
Éstos son los que no tienen experiencia y realmente al principio no quieren aprender. Simplemente quieren seguir instrucciones y conseguir su objetivo. Quieren las cosas muy masticadas con toda la información posible para llevar a cabo su proyecto. De ahí la frase que pone en el libro: "Novice need recipes".
Advance Beginner:
Estan por encima de los novatos, pero al igual que ellos quieren toda la información masticada y solo la parte que les pertoca. No quieren una visión global del proyecto, solo de su módulo en questión. Además pueden empezar a hacer cosas por su cuenta.
Competent:
Éstos pueden empezar a modelar conceptos en su cabeza y sobretodo aceptar consejos de expertos como dicen ellos: "can troubleshoot"
Proficient:
Pueden manejar the big picture of the project. Se frustran rápidamente por unas especificaciones demasiado simplificadas y lo más importante es que pueden auto-corregirse y aplicar los máximos (test everything that can break) en su trabajo.
Expert:
Éstos representan entre el 1 y el 5% de la población humana. Son personajes que suelen escribir libros y tienen mucha fluidez resolviendo problemas. Pueden generar diversos prototipos en su cabeza y siempre están mirando de aplicar los mejores métodos. "They do use intuition", utilizan la intuición para resolver los problemas y suelen saber que cosas son relevantes y cuáles no. El ser experto no implica saber explicar bien, son diferentes funciones del cerebro y no suelen ir acompañadas, por eso podemos encontrarnos diversos expertos en diversos campos que son capaces de decirte que una cosa no funcionará pero no te dará una explicación. Simplemente lo sabe!. Utilizan mucho la identificación de patrones.

Hasta aquí el primer resumen de éste curso tan interesante. En mi opinión me ha gustado muchísimo, he aprendido un montón de técnicas interesantes para mejorar mi aprendizaje sobre las cosas y el poder cambiar de perspectiva rápidamente para ser aún mucho más productivo. O sea llegar a ser un pragmatic thinker!.

  • Enlaces de interés:
NeuroPlasticidad por Horacio Krell.

I'm a problem solver.

Bueno!, ya he vuelto después de un fin de semana muy intenso y largo (pero que al final se hizo muy corto) y ya obtuve mi certificado de "Andy Hunt Pragmatic Thinking and Learning". Un curso muy interesante con un montón de ideas innovadoras sobre como llegar a ser mucho más productivo en tu trabajo. La verdad que fue una oportunidad muy especial el poder asistir a éste primer curso disponible en Londres (The Old Session House) gracias a la empresa Skill Matters y sobretodo el conocer a Andy Hunt que desde que leo sus libros para mi se ha convertido en toda una fuente de inspiración. Tengo muchas cosas que contaros, muchas ideas, cosas nuevas, etc. (a lot of interesting stuff). El curso se basó en el libro que hace unos meses recomendé "Pragmatic Thinking and Learning - Refactor your wetware". Para adelantaros algo, aquí os dejo un vídeo muy interesante del cómo diseñaría microsoft el package del Ipod, no tiene desperdicio!.




Aún tengo que acabar de ordenar todos mis apuntes, pero éstos días prometo ir publicando mis anotaciones y mis diversas conclusiones sobre los temas expuestos. Como dice el título del artículo: "I'm a problem Solver" significa que el lenguaje con el que trabajamos realmente ahora ya no importa. Lo interesante es poder desarrollar tu cerebro para que sea fácil adaptarte a cualquier lenguaje que te pongan delante y no anclarte en un solo lenguaje de programación.

Friday, 9 October 2009

Plataforma de desarrollo : VLO Framework parte II

Ya he integrado formalmente el framework VLO 1.0 en mi aplicación Thundax Box Manager. Aun funciona de la misma manera pero el código está distribuido de otra forma. La aplicación utiliza la platforma VLO para poder trabajar con las diferentes cajas y conectarlas entre sí, o aplicar diferentes algoritmos sobre éstos para manejar diversos datos. He corregido varias cosas como la detección de múltiples conexiones sobre una caja y el posicionado correcto de las pantallas de propiedades, que al variar el esquema del observer no me había dado cuenta de que la posición de las pantallas de propiedades se ubican en función del canvas. Lo he modificado para que tenga en cuenta el parent y lo ubique en un lateral del formulario. Para la detección de la conexión solo he tenido que modificar el objeto conector y aplicar un esquema de búsqueda para ver si existen sus conectores:


function TConnectorList.exists(AObject: TConnector): Boolean;
var
i: integer;
found: boolean;
begin
i := 0;
found := false;
while (not found) and (i < self.Count) do
begin
found := (self.Items[i].HashSourceBox = AObject.HashSourceBox) and
(self.Items[i].HashTargetBox = AObject.HashTargetBox);
if not found then
found := (self.Items[i].HashSourceBox = AObject.HashTargetBox) and
(self.Items[i].HashTargetBox = AObject.HashSourceBox);
i := i + 1;
end;
result := found;
end;


Si intentamos realizar una operación no posible, nos aparecerá un mensaje indicando que las cajas ya están conectadas:


if not connectorList.Exists(conn) then
connectorList.Add(conn)
else
begin
FreeAndNil(conn);
ShowMessage('Box already connected!');
end;



También he puesto la información en el About indicando la versión del framework y un link a mi web: thundaxSoftware.org. Aunque no estén todas las aplicaciones allí, encontraréis otras. (tengo que unificar todas las aplicaciones y ordenarlo un poco).

Aquí os dejo la última versión de Thundax Box Manager para que podáis testear el framework.

Éste fin de semana intentaré postear algo más pero será complicado, ya que estaré en Londres asistiendo al seminario que da Andy Hunt sobre el pensamiento y aprendizaje pragmático. Vamos, que no tiene pérdida!.


Automation Object Library para Vijeo Citect con Delphi parte III

Aquí os dejo una aplicación interesante utilizando la Graphic Builder Automation Interface que trae Vijeo Citect. Ésta aplicación que he creado la utilizaré posteriormente con Thundax Box Manager para gestionar la librería que trae Citect. Mi idea es poder leer toda la librería de nuestro proyecto de citect y guardar también su imagen en la librería de imagenes de Thundax Box Manager. De ésta manera, al crear el mapa mental de la aplicación, podré incrustar la imagen que toque de la librería con ésta nueva aplicación que he creado. La aplicación se llama Thundax Genies Scanner y permite escanear una pantalla de vijeo citect, y a la vez permite incrustar una imagen del clipboard para ir recortando las diferentes imagenes de la librería e ir guardandolas en formato .bmp dentro de la librería de Thundax Box Manager. La cosa funciona de la siguiente manera, primero si disponemos de una pantalla con todos los elementos de nuestra librería emplastados en la página activa (Citect Graphic Builder):

Ahora solo tenemos que marcar la ventana activa y hacer ALT + PRINT SCREEN y se bolcará una copia de la imagen en el clipboard. Ahora iniciamos la aplicación Thundax Genies Scanner, y en el menú "Clipboard" hacemos "paste", y aparecerá la imagen de la aplicación Graphic builder dentro de Thundax Genies Scanner.

Ahora, desde la opción de menú File -> Scan Objects, veremos como el algoritmo busca el objeto en la pantalla del Vijeo Citect (Citect Graphic Builder) y extrae todas sus propiedades que se listarán en el árbol de la izquierda, y además se copiará el símbolo de la propia imagen incrustada en la aplicación, para crear una librería gráfica de símbolos.

Si ejecutamos, el resultado es el siguiente:

Ahora podemos disponer de toda nuestra librería de objetos de citect exportada para que la aplicación Thundax Box Manager con el VLO Framework pueda trabajar con ésta. En los siguientes artículos las cosas se irán poniendo mucho más interesantes ya que empezaré a implementar los algoritmos para trabajar con todos éstos datos.


Thundax Box Manager 2.3

Ya está disponible la versión 2.3 de mi aplicación utilizando mi framework VLO. En ésta versión las novedades son significativas y es que he modificado el tamaño del lienzo. Es decir, ahora podemos navegar por la ventana utilizando unos Scrollbar situados en la horizontal y la vertical del canvas. La manera fácil de implementar ésto es utilizando un TScroBox que permite incrustar una imagen dentro y visualizarla por completo. Pero el problema que se presenta aquí, es que al utilizar mi propio canvas (ThundaxCanvas) éste creará 2 ThundaxScrollBar y gestionarán la vista del lienzo. Lo que he hecho es modificar las coordenadas desde el punto de vista del observador de ésta manera el modelo se entera del cambio y redibuja otra vez toda la imagen posicionandola en la posición correcta. De igual manera podría implementar un zoom (ya lo haré más adelante) pero la estructura es la siguiente:

La visión del observador consiste en mostrar aquella región que es visible desde la aplicación. El lienzo tiene un tamaño de 1280 x 1024 pixels y no se puede mostrar todo por pantalla. Aquí está la razón del tener que implementar éste cambio de perspectiva.

La aplicación ahora tiene el siguiente aspecto:


La última versión no disponía de redimensionado de formulario, y ahora ya está disponible. También he corregido unos cuantos bugs del VLO framework sobre la eliminación de objetos, que no se eliminaban correctamente.


Si probáis de eliminar el nodo 9 en la penúltima versión veréis que aparece una excepción. En ésta última entrega ya no sucede.

Wednesday, 7 October 2009

Wetware Workshop on Monday

Bueno, los nervios ya empiezan a aflorar y es que el próximo lunes (12 de Octubre en Londres) asistiré al famoso evento "Pragmatic Thinking" dirigido por Andy Hunt. Aquí os dejo la última entrada reciente del blog de Andy y os dejo la publicidad del seminario que escribí hace pocos días. A ver si os animáis y nos vemos allí!.

El evento se realizará en Skills Matter, aquí os dejo la entrada original traducida para los que queráis asistir:

El desarrollo de software se crea en tu mente no en un editor, IDE o herramienta de diseño. Conocemos bien cómo trabajar con software y hardware, pero ¿qué pasa con el wetware, o nuestros cerebros?

Únete a Andy Hunt para echar una mirada a cómo funciona el cerebro de verdad (pista: es un procesador dual con diseño de bus compartido) y cómo utilizar la mejor herramienta para el trabajo aprendiendo a pensar diferente sobre los pensamientos. Andy mira la importancia del contexto y el papel de la intuición de expertos en el desarrollo de software.

Aprender a sacar partido del pole-bridgind y el pensamiento de integración. Comparar las diferentes funciones especializadas laterales, incluyendo la síntesis frente al análisis y el tratamiento secuencial frente la coincidencia de patrones. Descubre el sencillo hábito que separa a los genios de los principiantes.

Andy te ayudará a descubrir cómo aprender más deliberadamente por la gestión de tu propio conocimiento. Explorar con prácticas las técnicas de aprendizaje como los mapas mentales, técnicas de lectura, retroalimentación de situaciones, y la mejor manera de hacer frente al torrente de información nuevo que nos ataca a cada uno de nosotros.

¿Interesado?
Poneros en contacto! Escribir a info@skillsmatter.com con vuestros datos de contacto.

El programa, en inglés:

PROGRAMME

Journey from Novice to Expert

  • The Five Dreyfus Model Stages
  • Dreyfus at Work: Herding Racehorses and Racing Sheep
  • Using the Dreyfus Model Effectively

This Is Your Brain

  • Your Dual-CPU Modes
  • Linear and Rich Characteristics
  • DIY Brain Surgery and Neuroplasticity

Get in Your Right Mind

  • Draw on the Right Side
  • Engage an R-mode to L-mode Flow
  • Harvest R-mode

Debug Your Mind

  • Meet Your Cognitive Biases
  • Recognize Your Generational Affinity
  • Codifying Your Personality Tendencies
  • Exposing Hardware Bugs

Learn Deliberately

  • Create a Pragmatic Investment Plan
  • Use Enhanced Learning Techniques
  • Read Deliberately with SQ3R
  • Visualize Insight with Mind Maps
  • Learn by Teaching

Gain Experience

  • Play in Order to Learn
  • Embed Failing in Practice
  • Learn About the Inner Game
  • Sensory Overrides

Manage Focus

  • Increase Focus and Attention
  • Manage Your Knowledge
  • Control Context

Beyond Expertise

  • Effective Change
  • What to Do Tomorrow Morning
  • Beyond Expertise

También os recomiendo la lectura de su libro, el cuál también hice un pequeño comentario en mi blog: Dreyfus Model.



Monday, 5 October 2009

Automation Object Library para Vijeo Citect con Delphi parte II

Continuando con la primera parte de éste artículo, voy a seguir con la explicación dada en esa entrega y ver como va evolucionando la integración de la idea comentada en ese artículo sobre el nuevo framework VLO. Ésta parte es muy interesante y llevo trabajando en ésto casi todo el fin de semana, incluso ahora estoy dedicando un rato en crear unos vídeos para mostrar lo interesante de la aplicación, pero aún se me encallan un poquito.

En éste artículo voy a comentar los siguientes pasos que ha realizado mi aplicación "Thundax Box manager" para implementar el nuevo framework VLO (Visually Linked Objects) para poder escanear una pantalla del Scada (Vijeo Citect 7.0) y generar su símil en la aplicación Thundax Box Manager y así como dije en su día, crear un mapa mental de lo que realmente hay en la aplicación. Ésto nos servirá más adelante para hacer cosas mucho más potentes que ya os iré explicando.

En definitiva, la primera propuesta era encontrar la manera de obtener todos los objetos y sus propiedades utilizando la librería de automatización que lleva el Vijeo Citect que además es un TLB (type library Borland), por lo tanto si tengo una pantalla típica hecha con Vijeo Citect:

Puedo ver las genies "engine" y "valve" y el símbolo "tank". Pues bien, he creado un pequeño algoritmo que se encarga de escanear éstos objetos y devolverme sus propiedades (nombre, librería, tags, posición, etc).

El resultado de ejecutar éste algoritmo es lo siguiente:

Se muestra en éste formulario la información referente a cada genie, más la información de sus propiedades. Si consultamos en el Scada el punto de animación 35, podemos ver que es el motor y que las propiedades capturadas coinciden con las de la pantalla:


Aquí podréis descargar la aplicación utilizada para el escaneado de propiedades. Podéis comprobar vuestras aplicaciones y ver si devuelve bien o no los parámetros:
Lo más interesante ahora, es que puedo perfeccionar éste algoritmo y utilizar mi framework VLO para representar la información de la siguiente manera:

Y ahora que tengo los mismos objetos que en el Scada, puedo hacer lo siguiente:

¿Veis por dónde van los tiros, no?. Ahora puedo dar una cierta inteligencia a éstos objetos y empezar a generar mucha más información porqué de empezar siendo una imagen (elementos posicionados en un diagrama para simular algo), acaba siendo un diagrama en una plataforma que me permite crear un mapa mental de lo que existe.

¿Y ahora que?. Pues a seguir perfeccionadolo. Al final hay que conseguir poder dibujar ciertos procesos dentro de mi framework y luego empezar a generar diversa información más sutil, como rutas de transporte, enclavamientos entre equipos, etc, etc, etc. Todo ésto con la ayuda de Delphi, una buena base de OO y un buen diseño de patrones.

En mi opinión ésto es algo que creo yo que tendrá tirada. Aún no he visto nada de ésto en el mercado (que yo conozca), ya que no es como un control distribuido, sino que es algo más personalizable. Poco a poco iré implementando más funcionalidades hasta poder disponer de algo un poco global y que no cueste mucho su implementación y que sea muy escalable.