Autor Tema: Copiar matriz tridimensional en C  (Leído 385 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2783
Re:Copiar matriz tridimensional en C
« Respuesta #15 en: 05 de Diciembre de 2017, 21:13:59 »
sizeof(wpc_planes2) te da el tamaño del puntero que va a ser dependiente de la arquitectura, como es de 32 bits, sólo te va a copiar los primeros 4 bytes. Tienes que hacerlo de la siguiente forma sizeof(*wpc_planes2)

Lo probaré, gracias, tiene pinta de ser eso.

Citar
Me imagino que
PLANE_SIZE * PLANE_COUNT  = ROW_COUNT * ROW_LENGTH



#define ROW_COUNT 32
#define COL_COUNT 128
#define ROW_LENGTH  (COL_COUNT / 16)
#define COLOR_DEPTH 24
#define PLANE_COUNT 4
#define PLANE_SIZE ROW_COUNT * ROW_LENGTH

Cada imagen son 32 lineas x 128 columnas, y en la matriz se meten 3 ó 4  imágenes (planos).
« Última modificación: 05 de Diciembre de 2017, 21:18:12 por planeta9999 »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2783
Re:Copiar matriz tridimensional en C
« Respuesta #16 en: 11 de Diciembre de 2017, 06:31:22 »
sizeof(wpc_planes2) te da el tamaño del puntero que va a ser dependiente de la arquitectura, como es de 32 bits, sólo te va a copiar los primeros 4 bytes. Tienes que hacerlo de la siguiente forma sizeof(*wpc_planes2)



Ya lo he probado, y no funciona bien. El cliente se queja de que la imagen le sale muy tenue, y eso es porque de los 3 planos de la matriz, seguramente solo se ha copiado el primero, la imagen se crea mezclando tres frames (planos), según un punto esté en 1, 2 o los 3 planos, sale con más o menos intensidad, si le sale todo muy tenue es porque se han perdido planos.

Con esto no copia nada.
memcpy(wpc_planes2, wpc_planes, sizeof(wpc_planes2));

Con esto, parece que solo copia uno de los 3 planos de la matriz multidimensional
memcpy(wpc_planes2, wpc_planes, sizeof(*wpc_planes2));


Creo que voy a probar a hacer una copia con bucles anidados, no me queda otra, aunque seguro que se puede hacer con memcpy y será más rápido.


O trato de hacerlo igual que lo hacen en la función SwapBuffers, que tenía la aplicación original para otras cosas.

// waits until previous swap is complete
// waits until current swap is complete if copy is enabled
template <typename RGB, unsigned int optionFlags>
void SMLayerBackground<RGB, optionFlags>::swapBuffers(bool copy) {
    while (swapPending);

    swapPending = true;

    if (copy) {
        while (swapPending);
        copyRefreshToDrawing();
    }
}


template <typename RGB, unsigned int optionFlags>
void SMLayerBackground<RGB, optionFlags>::copyRefreshToDrawing() {
    memcpy(currentDrawBufferPtr, currentRefreshBufferPtr, sizeof(RGB) * (this->matrixWidth * this->matrixHeight));
}


template <typename RGB, unsigned int optionFlags>
SMLayerBackground<RGB, optionFlags>::SMLayerBackground(RGB * buffer, uint16_t width, uint16_t height) {
    backgroundBuffer = buffer;
    this->matrixWidth = width;
    this->matrixHeight = height;

    currentDrawBufferPtr = &backgroundBuffer[0 * (this->matrixWidth * this->matrixHeight)];
    currentRefreshBufferPtr = &backgroundBuffer[1 * (this->matrixWidth * this->matrixHeight)];

}



« Última modificación: 11 de Diciembre de 2017, 06:34:44 por planeta9999 »

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 168
Re:Copiar matriz tridimensional en C
« Respuesta #17 en: 12 de Diciembre de 2017, 12:35:12 »
Vamos a analizar tu código:

Código: [Seleccionar]
uint16_t planes[PLANE_SIZE * PLANE_COUNT];
typedef uint16_t wpc_plane[ROW_COUNT][ROW_LENGTH];
wpc_plane* wpc_planes = (wpc_plane*) planes;

Donde

Código: [Seleccionar]
#define ROW_COUNT 32
#define COL_COUNT 128
#define ROW_LENGTH  (COL_COUNT / 16)
#define COLOR_DEPTH 24
#define PLANE_COUNT 4
#define PLANE_SIZE ROW_COUNT * ROW_LENGTH

Según tu código

Código: [Seleccionar]
uint16_t planes[PLANE_SIZE * PLANE_COUNT];

planes es una arreglo de
Código: [Seleccionar]
PLANE_SIZE*PLANE_COUNT = ROW_COUNT*ROW_LENGTH * PLANE_COUNT = 32*8*4 = 1024

Código: [Seleccionar]
typedef uint16_t wpc_plane[ROW_COUNT][ROW_LENGTH];

wpc_plane tiene un  tamaño de

Código: [Seleccionar]
ROW_COUNT*ROW_LENGTH = 32*8 = 256

De ahí que cuando coloqué que si  PLANE_SIZE*PLANE_COUNT == ROW_COUNT*ROW_LENGTH

sizeof(*wpc_planes2) sólo abarca el primer plano ya que 256 != 1024. No puedes esperar a que

Código: [Seleccionar]
wpc_plane* wpc_planes = (wpc_plane*) planes;

Automáticamente te genere un arreglo de 1024 elementos.

wpc_planes es un puntero que no se entera de lo que hay más allá de su espacio de memoria que abarcan sólo 256 elementos.

No requieres de bucles anidados, sólo requieres que ambas tengan el mismo tamaño y eso lo puedes asegurar con

Código: [Seleccionar]
sizeof(*wpc_planes2)*PLANE_COUNT

Código: [Seleccionar]
sizeof(wpc_planes2) = 8
sizeof(*wpc_planes2) = 512
sizeof(*wpc_planes2)*PLANE_COUNT = 2048
sizeof(planes2) = 2048

O con que ambos tengan el mismo tamaño, de tal forma que sizeof(*wpc_planes2) = sizeof(planes2)

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2783
Re:Copiar matriz tridimensional en C
« Respuesta #18 en: 12 de Diciembre de 2017, 14:31:39 »

Ok, gracias tsk, entendido.

El comportamiento del programa me dejaba claro que solo se había copiado uno de los planos de la matriz, que aunque esté definida con un tamaño de 4 planos, para esta aplicación en concreto se usan solo 3.

Voy a cambiarlo y le paso al cliente la actualización, yo creo que ahora ya tiene que ir perfecto.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2783
Re:Copiar matriz tridimensional en C
« Respuesta #19 en: 13 de Diciembre de 2017, 03:43:26 »

Ya funciona bien, con el cambio del memcpy.

Tambien tiene otro problema, aunque no relacionado con el memcpy. Parece que pierde paquetes de datos, no se si es el propio UDP el culpable, o su programa no es capaz de procesar a la velocidad que yo le envío.  Voy a ponerle un delay de varios milisegundos entre paquetes, a ver si se resuelve.

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 168
Re:Copiar matriz tridimensional en C
« Respuesta #20 en: 13 de Diciembre de 2017, 12:07:50 »
En una red local está muy difícil que exista pérdida de datos en UDP.

¿Cuál es la frecuencia con la que pierde datos?
¿En tus pruebas hay perdida de datos?
¿Tienes un programa propio con el que puedas corroborar la pérdida de datos o en su defecto realizar pruebas de estrés al sistema?
¿Tienes el programa de tu cliente para que puedas probar?

He hecho pruebas para ver la tasa de transferencia máxima a la que se puede llegar y con un esp8266 con UDP y ha estado estable a cerca de los 8Mbps sin pérdida de datos y es por wifi.

La forma en que lo hago es que transmito 8832 bytes cada 9ms, lo que en teoría me debería de dar unos 7850.666 Kbps



Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2783
Re:Copiar matriz tridimensional en C
« Respuesta #21 en: 13 de Diciembre de 2017, 14:59:29 »

Ya está arreglado, el cliente en su programa estaba poniendo un retardo de 25ms entre paquetes, para procesarlos, y por eso no cazaba muchos de los paquetes que le envía mi placa.

Le he puesto en mi programa, el mismo retardo de 25ms entre paquetes, para enviarlos, y ya le va bien eso. Ahora tengo otro problema, pero este es de DMA, este si que me tiene mico total, porque es un tema que apenas empiezo a conocer.
« Última modificación: 13 de Diciembre de 2017, 15:01:40 por planeta9999 »


 

anything