PanGestureRecognizer sporadic during drag - xamarin.forms

I'm creating a simple drag animation to an image using PanGestureRecognizer. However, when the drag is in progress the TotalX and TotalY values are not consistent, they seem to jump / flicker / flutter between 2 values as I drag. Below is a raw trace example of the values:
[0:] PanUpdated: StatusType: Started, GestureId: 0, TotalX: 0, TotalY: 0
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 11.1617584228516, TotalY: 11.9234619140625
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 2.45475260416667, TotalY: 2.80341593424479
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 11.8422292073568, TotalY: 12.5428161621094
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 3.20952860514323, TotalY: 3.77924601236979
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 12.6615346272786, TotalY: 13.5227355957031
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 4.03237915039063, TotalY: 4.76089477539063
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 12.8976643880208, TotalY: 14.1595052083333
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 4.93493143717448, TotalY: 5.72846476236979
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 13.551747639974, TotalY: 14.7833862304688
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 5.67492167154948, TotalY: 6.68665568033854
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 14.1307627360026, TotalY: 15.5877075195313
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 6.67552185058594, TotalY: 7.82212320963542
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 14.8915608723958, TotalY: 16.3966369628906
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 7.67821248372396, TotalY: 8.44764200846354
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 15.2916819254557, TotalY: 16.9883219401042
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 8.57093811035156, TotalY: 9.37423706054688
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 15.8519948323568, TotalY: 17.2493794759115
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 9.13496907552083, TotalY: 10.1264038085938
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 16.5894927978516, TotalY: 17.6655578613281
[0:] PanUpdated: StatusType: Running, GestureId: 0, TotalX: 10.049072265625, TotalY: 11.0558268229167
[0:] PanUpdated: StatusType: Completed, GestureId: 0, TotalX: 0, TotalY: 0
If however I add the gesture to the container the value flows fine.
Here is my page:
<ContentPage>
<AbsoluteLayout >
<Image x:Name="Card" Source="CardBack_Red.png" />
</AbsoluteLayout>
</ContentPage>
And the code behind:
public partial class MainPage : ContentPage
{
double x, y;
public MainPage()
{
InitializeComponent();
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += PanGesture_PanUpdated;
panGesture.TouchPoints = 1;
Card.GestureRecognizers.Add(panGesture);
}
private void PanGesture_PanUpdated(object sender, PanUpdatedEventArgs e)
{
Debug.WriteLine($"PanUpdated: StatusType: {e.StatusType}, GestureId: {e.GestureId}, TotalX: {e.TotalX}, TotalY: {e.TotalY}");
Image card = (Image)sender;
switch (e.StatusType)
{
case GestureStatus.Started:
x = card.TranslationX;
y = card.TranslationY;
break;
case GestureStatus.Running:
card.TranslationX = x + e.TotalX;
card.TranslationY = y + e.TotalY;
break;
}
}
}
}
Seems like I'm fighting something but I don't know what, any ideas?
Thanks
-John

SOLVED
Turns out I simply had the wrong translation algorithm, the GestureStatus.Running case needed to add the delta directly to the image translation coordinates, instead of also adding the starting translation. The case in my code above no looks like this:
case GestureStatus.Running:
dragCard.TranslationX += e.TotalX;
dragCard.TranslationY += e.TotalY;
break;
I found a munch better sample here, helped a lot.

Related

Why OpenGL 3D texture sampling to wrong color?

I have some trouble when using 3D-LUT in GLSL shader, so I'm trying to test a minimal 3D-LUT, which is of size 2x2x2, totally 8 colors. My pixel data is
static const unsigned char lutData222[] = {
0, 0, 0, 255, 0, 0,
0,255, 0, 255,255, 0,
0, 0,255, 255, 0,255,
0,255,255, 255,255,255,
};
The 3D-texture settings are
m_lut.create();
m_lut.bind();
m_lut.setFormat(QOpenGLTexture::TextureFormat::RGB8_UNorm);
m_lut.setMinificationFilter(QOpenGLTexture::Filter::Nearest);
m_lut.setMagnificationFilter(QOpenGLTexture::Filter::Nearest);
m_lut.setWrapMode(QOpenGLTexture::WrapMode::ClampToEdge);
m_lut.setSize(LUT_EXTENT,LUT_EXTENT,LUT_EXTENT);
m_lut.allocateStorage(QOpenGLTexture::PixelFormat::RGB,
QOpenGLTexture::PixelType::UInt8);
m_lut.setData(QOpenGLTexture::PixelFormat::RGB,
QOpenGLTexture::PixelType::UInt8,
lutData222);
m_lut.release();
where m_lut is of type QOpenGLTexture, Yes this a Qt project. Blow is my fragment shader, it just using the texture coordinates plus a third dimension to sample the lut. So I can change the third dimension to be 0 or 1, to see if the color is as expected.
#version 330 core
in vec2 uv;
uniform sampler3D lut;
out vec4 FragColor;
void main() {
vec4 col = texture(lut, vec3(uv, 0));
col.a = 1;
FragColor = col;
};
But it is not. When the third dimension is 0, the reuslt picture is
And when the third dimension is 1, the reuslt picture is

Passing/printing parameters in Arduino

There is a function RFID that returns *z4 parameter that should be put into TagID.
When I print TagID from loop(), '1' instead of '1B31687DBC7FF' is printed.
How can I get the whole value? I would like to print full string '1B31687DBC7FF' to serial port.
#include "Arduino.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int inWord = 0;
int outWord[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int index = 0;
unsigned char Data2Calc[]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned short CRC2Calc = 0;
unsigned char Bytes2Calc = 9;
char z5 []= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
const char* TagID;
void setup()
{
pinMode(13, OUTPUT);
lcd.begin(16,2);
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("RFID Reader");
lcd.setCursor(0,1);
lcd.print("Skanuj TAG");
Serial.begin(9600);
Serial1.begin(9600);
lcd.setCursor(0,0);
}
void loop()
{
if (Serial1.available())
{
TagID = RFID();
}
else
{
if (index==11)
{
index=0;
Serial.print(TagID);
Serial.println("");
lcd.setCursor(0,0);
lcd.print("ID:");
lcd.print(TagID);
}
}
}
const char * RFID()
{
char z1 []= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char z2 []= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char z3 []= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned short crc2[] = { 0 };
inWord = Serial1.read();
index++;
if (index == 1)
{
if (inWord == 1)
{
outWord[index] = inWord;
}
else
{
index=index-1;
}
}
else if (index > 1)
{
if (index == 11)
{
outWord[index] = inWord;
for (int i = 1; i <12; i++)
{
Data2Calc[i-1] = outWord[i];
}
CRC16(Data2Calc, &CRC2Calc, Bytes2Calc);
itoa(outWord[10],z1,16);
itoa(outWord[11],z2,16);
strcat(z1, z2);
*crc2 = CRC2Calc;
sprintf(z2, "%x", *crc2); //
if (strcmp(z1,z2) == 0)
{
char z4 []= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i=1;i<10;i++)
{
itoa(outWord[i],z3,16);
if (strlen(z3)<2) strcat(z4, "0");
strcat(z4, z3);
//Serial.print(z4);
//Serial.println("");
}
//Serial.print("z4=");
//Serial.print(z4);
//Serial.println("");
strncpy(z5, z4, 18);
}
}
else
{
outWord[index] = inWord;
}
}
return z5;
}
void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
{
int i, byte;
unsigned short C;
*CRC = 0;
for (byte = 1; byte <= Bytes; byte++, Data++)
{
C = ((*CRC >> 8) ^ *Data) << 8;
for (i = 0; i < 8; i++)
{
if (C & 0x8000)
C = (C << 1) ^ 0x1021;
else
C = C << 1;
}
*CRC = C ^ (*CRC << 8);
}
}
Whole output of the functions is attached bellow:
Currently there are no serial ports registered - please use the + button to add a port to the monitor.
Connect to serial port COM4 at 9600
TagID: 1
UPDATE 1
I have attached above full code. Sorry... it is a bit long.
UPDATE 2
OK. I got it somewhat working, but not quite as expected. I got the value printed as expected, but only for the first time I call the function. If I call the function more times, I get some garbage added to the printed value as bellow:
Currently there are no serial ports registered - please use the + button to add a port to the monitor.
Connect to serial port COM4 at 9600
TagID: 1b31596d9cff
TagID: 1b31596d9cff1b31596d9cff
TagID: 1b31596d9cff1Řc–
ś˙cŘ1b31596d9cff
TagID: 1b31596d9cff1Řc–
ś˙cŘ1b311031596d9cff
TagID: 1b31596d9cff1Řc–
ś˙cŘ1b311031596d9cff
Any idea on what the problem might be?
I have updated the latest full source code at the top of the post.
Thanks.
UPDATE 3
OK, I got it finally working. I have changed declaration from 'char z1 []=...' to 'const char z1 []=...'
I am not sure it is written in decent style... but it works :) I attach working source code at the top of the page.
UPDATE 4
No, after a few tests I have to admit that the solution from UPDATE 3 does NOT work. Indeed it reads correctly but only for the first time... then program crashes and... it reads RFID again for the first time... so it looks only it reads OK, but it does not.
Serial output for 5 readings is as follows:
Currently there are no serial ports registered - please use the + button to add a port to the monitor.
Connect to serial port COM4 at 9600
1b31596d9cff
1b31596d9cff1b31596d9cff
1b31596d9cff1Řc–
ś˙cŘ1b31596d9cff
1b31596d9cff1Řc– ś˙cŘ1b311031596d9cff
1b31596d9cff1Řc– ś˙cŘ1b311031596d9cff
Any hints on what is wrong with the code?
UPDATE 5
OK. Finally I got it working... at least from what I can see.
I changed tables size, reworked HEX display way and made a few minor changes.
The entire source code updated at the top.
TagID is a char and your function returns a char. A char is a one byte variable. It will hold at most one character. It shouldn't then surprise you that you only print one character. You haven't provided enough of your code to really figure out what you're actually after. But that explains why you only get one character printed. A char variable can hold one character, not that whole string of stuff.
I'm thinking that you wanted to get a char*, a pointer to a char array. But you're going to have trouble with that too because z4 is a local array and goes out of scope before you get a chance to use it.

How to apply QMatrix4x4 to Mesh object like QTorusMesh in QT?

I have a 4x4 transformations matrix for object like
0.866, 0, 0.5, 0,
-0.5, 0, 0.866, 0,
0, -1, 0, 0,
0, 0, 0, 0
Or matrix like (Qt Transform matrix)
How apply 4x4 matrix to this construction:
Qt3D::QScaleTransform *torusScale = new Qt3D::QScaleTransform();
Qt3D::QTranslateTransform *torusTranslation = new Qt3D::QTranslateTransform();
Qt3D::QRotateTransform *torusRotation = new Qt3D::QRotateTransform();
Qt3D::QTransform *torusTransforms = new Qt3D::QTransform();
torusScale->setScale3D(QVector3D(2.0f, 2.0f, 2.0f));
torusTranslation->setTranslation(QVector3D(1.7f, 1.7f, 0.0f));
torusRotation->setAngleDeg(25.0f);
torusRotation->setAxis(QVector3D(0, 1, 0));
torusTransforms->addTransform(torusRotation);
torusTransforms->addTransform(torusTranslation);
torusTransforms->addTransform(torusScale);
You need to create a Qt3DCore::QEntity, add your QTorusMesh as a component and also add your torusTransforms (Qt3DCore::QTransform) as a component of the QEntity:
torusEntity = new Qt3DCore::QEntity(root_entity);
torusEntity->addComponent(torusMesh);
torusEntity->addComponent(torusMaterial);
torusEntity->addComponent(torusTransforms);
Now about the QMatrix4x4, you can instantiate a Qt3DCore::QTransform and set its internal matrix by calling the setMatrix SLOT, which receives a QMatrix4x4:
torusTransforms->setMatrix(my_matrix);
For a running example from the Qt docs look at: https://doc.qt.io/qt-5/qt3d-basicshapes-cpp-example.html, more specifically the scene modifier implementation.

clEnqueueReadBuffer return a void buffer

I am trying to implement an OpenCL project that should take in input two "grey" channels images and return a "grey" channel buffer
My OpenCL code:
__kernel void motion_detection(__global uchar* bgImage, __global uchar* motionImage,__global uchar* outputImage)
{
int i = get_global_id(0);
int tsh = 7;
uchar bgEl = bgImage[i];
uchar motionEl = motionImage[i];
float bg = convert_float(bgEl);
float mo = convert_float(motionEl);
float temp = fabs(bg-mo);
if(temp>tsh){temp=255.0;
}else
{temp=0.0;
}
outputImage[i] = convert_uchar(bg);
}
My Host:
// get width and height of input image
height = inputImage->rows;
width = inputImage->cols;
// get the pointer to pixel data
cl_uchar* inputImageData = inputImage->data;
cl_uchar* motionImageData = motionImage->data;
cl_uchar* outputImageData = outputImage->data;
After set up buffers:
// Create memory object for input Image
inputImageBuffer = clCreateBuffer(
context,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
width * height * greyPixelSize,
inputImageData,
&status);
CHECK_OPENCL_ERROR(status, "clCreateBuffer failed. (inputImageBuffer)");
motionImageBuffer = clCreateBuffer(
context,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
width * height * greyPixelSize,
motionImageData,
&status);
CHECK_OPENCL_ERROR(status, "clCreateBuffer failed. (inputImageBuffer)");
// Create memory objects for output Image
outputImageBuffer = clCreateBuffer(
context,
CL_MEM_READ_WRITE,
width * height * greyPixelSize,
0,
&status);
Settting up arguments and executing OpenCL kernel:
// input buffer image
status = clSetKernelArg(
kernl,
0,
sizeof(cl_mem),
&inputImageBuffer);
CHECK_OPENCL_ERROR(status, "clSetKernelArg failed. (inputImageBuffer)");
status = clSetKernelArg(
kernl,
1,
sizeof(cl_mem),
&motionImageBuffer);
CHECK_OPENCL_ERROR(status, "clSetKernelArg failed. (inputImageBuffer)");
// outBuffer imager
status = clSetKernelArg(
kernl,
2,
sizeof(cl_mem),
&outputImageBuffer);
CHECK_OPENCL_ERROR(status, "clSetKernelArg failed. (outputImageBuffer)");
status = clEnqueueNDRangeKernel(
commandQueue,
kernl,
1,
NULL,
globalThreads,
localThreads,
0,
NULL,
&ndrEvt);
clFinish(commandQueue);
Here is my problem, when this intruction is executed it returns outputImageData as "\0" and nothing else:
status = clEnqueueReadBuffer(
commandQueue,
outputImageBuffer,
CL_TRUE,
0,
width * height * greyPixelSize,
outputImageData,
0,
NULL,
NULL);
CHECK_OPENCL_ERROR(status, "clEnqueueReadBuffer failed.");

"ORTED_CMD_PROCESSOR: STUCK IN INFINITE LOOP - Aborting"

When doing the final reduction (summation of a bunch of matrices in my program), as follows
struct Tomo {
typedef Eigen::Matrix<int, HISTOGRAM_BOXES, HISTOGRAM_BOXES, Eigen::RowMajor> HistoMtx;
HistoMtx exp_val;
HistoMtx u;
[...]
struct buffer_set {
Tomo * X;
Tomo * Y;
Tomo * Z;
} buffers[2];
[...]
if(rank == 0){
/* MASTER NODE */
for(int source=1; source<size; source++){
printf("Reducing from %i\n", source);
for(int i=0;i<env_count;i++){
MPI_Recv(buffers[1].X[i].exp_val.data(), buffers[1].X[i].exp_val.size(), MPI_INT, source, 0, MPI_COMM_WORLD, &status);
MPI_Recv(buffers[1].Y[i].exp_val.data(), buffers[1].Y[i].exp_val.size(), MPI_INT, source, 0, MPI_COMM_WORLD, &status);
MPI_Recv(buffers[1].Z[i].exp_val.data(), buffers[1].Z[i].exp_val.size(), MPI_INT, source, 0, MPI_COMM_WORLD, &status);
MPI_Recv(buffers[1].X[i].u.data(), buffers[1].X[i].u.size(), MPI_INT, source, 0, MPI_COMM_WORLD, &status);
MPI_Recv(buffers[1].Y[i].u.data(), buffers[1].Y[i].u.size(), MPI_INT, source, 0, MPI_COMM_WORLD, &status);
MPI_Recv(buffers[1].Z[i].u.data(), buffers[1].Z[i].u.size(), MPI_INT, source, 0, MPI_COMM_WORLD, &status);
}
merge_buffers(0, 1);
}
WriteH5File("h5file.h5", 0);
}else{
/* SLAVE NODES */
for(int i=0;i<env_count;i++){
MPI_Send(buffers[0].X[i].exp_val.data(), buffers[0].X[i].exp_val.size(), MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(buffers[0].Y[i].exp_val.data(), buffers[0].Y[i].exp_val.size(), MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(buffers[0].Z[i].exp_val.data(), buffers[0].Z[i].exp_val.size(), MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(buffers[0].X[i].u.data(), buffers[0].X[i].u.size(), MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(buffers[0].Y[i].u.data(), buffers[0].Y[i].u.size(), MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(buffers[0].Z[i].u.data(), buffers[0].Z[i].u.size(), MPI_INT, 0, 0, MPI_COMM_WORLD);
}
}
the pbs_mom process dies. When running the program in an interactive session, I find the following in my logs
[compute-35-3.local:01139] [[33012,0],2] ORTED_CMD_PROCESSOR: STUCK IN INFINITE LOOP - ABORTING
[compute-35-3:01139] *** Process received signal ***
I don't understand what this means or what would trigger it. It seems quite internal to OpenMPI.
Could be an issue with the underlying network or something else that might require administrator attention. For example:
http://www.open-mpi.org/community/lists/users/2010/08/14130.php
http://lists.mcs.anl.gov/pipermail/petsc-users/2013-August/018470.html

Resources