I'm trying to work out a time-delay to display steady flickering. I didn't get it to work with sleep() or time.h, what seems to be logically.
How could I achieve something like, displaying a white rectangle for 10 seconds, then clear this area (also for 10 sec), in a loop.
In this question, a socket of the X11 connection is mentioned to do things like that. But where to dig in, in this matter?
Thanks
The file descriptor is in the Display structure and can be obtained with the macro ConnectionNumber(dis).
You could then use poll with a timeout to wait for an event to arrive or a timeout to occur.
As mentioned in the other questions, XPending will let you see if there are any events, so you don't actually need to check the file descriptor, you could do something like this:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <time.h>
#include <unistd.h>
int main()
{
XEvent ev;
Display *dis = XOpenDisplay(NULL);
Window win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, 0, BlackPixel (dis, 0), WhitePixel(dis, 0));
XMapWindow(dis, win);
GC gc = XCreateGC(dis, win, 0, 0);
int draw = 1;
time_t t = time(NULL) + 10;
XMapWindow(dis, win);
XSelectInput(dis, win, ExposureMask | KeyPressMask);
while (1)
{
if (XPending(dis) > 0)
{
XNextEvent(dis, &ev);
switch (ev.type)
{
case Expose:
printf("Exposed.\n");
if (draw > 0)
{
XFillRectangle(dis, win, gc, 100, 100, 300, 300);
}
break;
case KeyPress:
printf("KeyPress\n");
/* Close the program if q is pressed.*/
if (XLookupKeysym(&ev.xkey, 0) == XK_q)
{
exit(0);
}
break;
}
}
else
{
printf("Pending\n");
sleep(1);
if (time(NULL) >= t)
{
/* Force an exposure */
XClearArea(dis, win, 100, 100, 300, 300, True);
t += 10;
draw = 1 - draw;
}
}
}
return 0;
}
Note: you might want to use something like usleep to get a finer timer granularity.
Related
Okay, so basically, I'm trying to have my robot go forwards, until it detects a wall, then reverse, and then turn into a random direction. Problem is, it's only turning right. If anyone can help with this, I will be VERY appreciative, because I've spent about two days on it, and not even my teacher can figure out what's wrong with it. It is more of a robotics thing rather than just a code thing, but you can probably just ignore the motor/servo jargon. Thanks!
#include <PRIZM.h> // include PRIZM library
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define RAND_MAX 1
PRIZM prizm; // instantiate a PRIZM object “prizm” so we can use its functions
void setup() {
prizm.PrizmBegin(); //initialize PRIZM
prizm.setServoSpeed(1,50);
prizm.setMotorInvert(1,1); // invert the direction of DC Motor 1
// to harmonize the direction of
// opposite facing drive motors
}
void loop() {
int x;
x = 1;
int r;
while((prizm.readSonicSensorCM(3) > 50)&&(x == 1))
{
prizm.setMotorPowers(40,40); // if distance greater than 25cm, do this
prizm.setServoPosition(1,146.75);
prizm.setServoPosition(2,55.5);
r = rand();
}
if((prizm.readSonicSensorCM(3) <= 50)||(x == 0))
{
x--;
prizm.setServoPosition(1, 54.5);
prizm.setServoPosition(2,145.25);
prizm.setMotorPowers(0,0);
delay(250);
prizm.setMotorPowers(-30,-30);
delay(750);
prizm.setMotorPowers(0,0);
delay(300);
if (r == 0) {
prizm.setMotorPowers(-50,50);
delay(1100);
}
else {
prizm.setMotorPowers(50,-50);
delay(1100);
}
prizm.setMotorPowers(0,0);
delay(200);
x++;
}
}
Note that your redefinition of RAND_MAX has no effect on the output of the rand() function. This is not a parameter for the function, but a constant telling you what the maximum value of the output is.
The best way to get a 50% of probability in your if (r == 0), is to go one side if r is even, the other if it is odd:
if ((r % 2) == 0) {
prizm.setMotorPowers(-50,50);
delay(1100);
}
else {
prizm.setMotorPowers(50,-50);
delay(1100);
}
So I understand that XWindow is changing the title bar based on it being a child window. Can I override this? Sample program:
/*
* Study for child windows.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Display* d;
int main(void) {
Window w, w2;
XEvent e;
const char* msg = "Hello, window 1";
const char* msg2 = "Hello, window 2";
int s;
int x;
GC gracxt;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
gracxt = XDefaultGC(d, s);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w);
w2 = XCreateSimpleWindow(d, w, 100, 100, 100, 100, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w2, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w2);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
if (e.xany.window == w) XDrawString(d, e.xany.window, gracxt, 10, 50, msg, strlen(msg));
else XDrawString(d, e.xany.window, gracxt, 10, 50, msg2, strlen(msg2));
}
if (e.type == KeyPress) break; /* exit on any key */
}
XCloseDisplay(d);
return 0;
}
The resulting child window looses its title bar, but gains a black outline frame. What I want in this case is just a window in window, IE., with title frame, size bars, etc.
Is there a method to get this behavior?
What is the purpose? This is for "multiple document" type interfaces, where the user gets several documents contained within the parent window, but can move and size each one within the window.
OS is Ubuntu 20.04, Window manager is Gnome/GDM3.
Thanks.
Scott Franco
San Jose, CA
I have a GLUT-based program that I'm moving from macOS High Sierra (10.13.6) to macOS Mojave (10.14.4). Yes, I know that GLUT is deprecated on both. When I compile and run the program on Mojave, GLUT seems to be batching up calls to the glutMotionFunc() callback in a way that it doesn't when it is compiled and/or run on macOS 10.13.
I've written a simple version of the program to isolate the behavior, which I've included here. When there is no active click-and-drag motion on the GLUT window, the display callback sleeps for a "long time" (by default 300 msec), but when there is such motion detected, it sleeps for just 8 msec.
The expected behavior is that a click followed by rapid back-and-forth dragging motion will cause the program to stay in the 8 msec sleeping behavior, enabling it to sample and respond to mouse motion with low latency. When compiled or run on macOS 10.13.6, it behaves this way. When compiled and run on macOS 10.14.4, it gets a few motion callbacks in a row, but then doesn't get any after the 8 msec display callback finishes, so the next display callback takes 300 msec. In practice, this makes the observed mouse motion very jerky.
I did enough binary chopping to isolate the change in behavior to a single byte in the binary. (I know enough about systems programming to figure out how to do this, but not enough about macOS to know just what it means.) If I take a binary compiled on macOS 10.13 and change the "sdk" field of the LC_VERSION_MIN_MACOSX load command to mean "10.14" rather than "10.13", it shows the jerky behavior. If I take a binary compiled on macOS 10.14 and change the "sdk" field of the LC_BUILD_VERSION load command to mean "10.13" rather than "10.14", it works again.
Is my program doing something obviously dumb that would cause this change? Or is this a Mojave bug? Also, does anyone happen to know what actually changes when I mess with the "sdk" field of the load commands?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <GLUT/glut.h>
/* ------------------------------------------------------------------ */
typedef long long hrtime_t;
hrtime_t
gethrtime(void)
{
struct timeval tp;
hrtime_t rv;
gettimeofday(&tp, NULL);
rv = ((unsigned long long)tp.tv_sec * 1000000ull + tp.tv_usec);
return (rv);
}
static void
stamp(void)
{
static hrtime_t then = 0;
const hrtime_t now = gethrtime();
const hrtime_t delta = (then == 0 ? 0 : now - then);
printf("%16lld %5lld.%03lld ", now, delta / 1000, delta % 1000);
then = now;
}
/* ------------------------------------------------------------------ */
#define NPTS 1024
int Xs[NPTS], Ys[NPTS];
int W, R;
static void
point(int x, int y)
{
Xs[W] = x;
Ys[W] = y;
W = (W + 1) % NPTS;
}
static int
line_pending(void)
{
return (R < W && (R + 1) % NPTS < W);
}
static int
get_line(int *sxp, int *syp, int *exp, int *eyp)
{
if (line_pending()) {
*sxp = Xs[R];
*syp = Ys[R];
R = (R + 1) % NPTS;
*exp = Xs[R];
*eyp = Ys[R];
return (1);
} else {
return (0);
}
}
/* ------------------------------------------------------------------ */
static void
keyboard_cb(unsigned char key, int x, int y)
{
if (key == 'q') {
exit(0);
}
glutPostRedisplay();
}
static void
mouse_cb(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON) {
stamp();
printf("[%4d, %4d]: mouse %s\n",
x, y, (state == GLUT_DOWN) ? "down" : "up");
point(x, y);
}
glutPostRedisplay();
}
static void
motion_cb(int x, int y)
{
stamp();
printf("[%4d, %4d]: motion\n", x, y);
point(x, y);
glutPostRedisplay();
}
/* ------------------------------------------------------------------ */
static hrtime_t Delay;
static void
display_cb(void)
{
printf("\n");
stamp();
if (line_pending()) {
printf("display: found motion\n");
while (line_pending()) {
int sx, sy, ex, ey;
get_line(&sx, &sy, &ex, &ey);
glBegin(GL_LINES);
glVertex2f(sx, 512 - sy);
glVertex2f(ex, 512 - ey);
glEnd();
printf("drawing [%4d %4d]-[%4d %4d]\n", sx, sy, ex, ey);
}
glFlush();
stamp();
printf("display: now sleeping 8 msec\n");
(void) usleep(8000);
} else {
printf("display: no motion, doing %llu msec render\n", Delay);
(void) usleep(1000 * Delay);
}
stamp();
printf("display: done\n");
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutInitWindowPosition(768, 0);
glutCreateWindow("");
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 512.0, 0.0, 512.0, -1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glFlush();
Delay = (argc > 1 ? atoi(argv[1]) : 300);
glutDisplayFunc(display_cb);
glutIdleFunc(glutPostRedisplay);
glutKeyboardFunc(keyboard_cb);
glutMouseFunc(mouse_cb);
glutMotionFunc(motion_cb);
glutMainLoop();
return (0);
}
I found a problem in opencv2.4.8 undistort() in vs2010. It just show me one color image in "undist" window, while the same codes work fine in Qtcreator.
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
int main()
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
while(1)
{
Mat frame;
cap >> frame;
imshow("video",frame);
double cM[3][3] = {{610.12376,0,319.5}, {0,610.12376,239.5}, {0, 0, 1}};
Mat cameraMatrix = Mat(3, 3,CV_64F,cM);
double dM[5]={0.0681495,-0.128756,0,0,0.5857514};
Mat distCoeffs = Mat(8, 1, CV_64F,dM);
Mat undi=frame.clone();
undistort(frame,undi, cameraMatrix, distCoeffs);
imshow("undist",undi);
if ( (cvWaitKey(30) & 255) == 's' )
{
imwrite("test.jpg",undi);
}
else if ( (cvWaitKey(30) & 255) == 27 ) break;
}
cvWaitKey(0);
return 0;
}
Consider the following fragment of OpenMP code which transfers private data between two threads using an intermediate shared variable
#pragma omp parallel shared(x) private(a,b)
{
...
a = somefunction(b);
if (omp_get_thread_num() == 0) {
x = a;
}
}
#pragma omp parallel shared(x) private(a,b)
{
if (omp_get_thread_num() == 1) {
a = x;
}
b = anotherfunction(a);
...
}
I would (in pseudocode ) need to transfer of private data from one process to another using a single-sided message-passing library.
Any ideas?
This is possible, but there's a lot more "scaffolding" involved -- after all, you are communicating data between potentially completely different computers.
The coordination for this sort of thing is done between windows of data which are accessible from other processors, and with lock/unlock operations which coordinate the access of this data. The locks aren't really locks in the sense of being mutexes, but they are more like synchronization points coordinating data access to the window.
I don't have time right now to explain this in the detail I'd like, but below is an example of using MPI2 to do something like shared memory flagging in a system that doesn't have shared memory:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "mpi.h"
int main(int argc, char** argv)
{
int rank, size, *a, geta;
int x;
int ierr;
MPI_Win win;
const int RCVR=0;
const int SENDER=1;
ierr = MPI_Init(&argc, &argv);
ierr |= MPI_Comm_rank(MPI_COMM_WORLD, &rank);
ierr |= MPI_Comm_size(MPI_COMM_WORLD, &size);
if (ierr) {
fprintf(stderr,"Error initializing MPI library; failing.\n");
exit(-1);
}
if (rank == RCVR) {
MPI_Alloc_mem(sizeof(int), MPI_INFO_NULL, &a);
*a = 0;
} else {
a = NULL;
}
MPI_Win_create(a, 1, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
if (rank == SENDER) {
/* Lock recievers window */
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, RCVR, 0, win);
x = 5;
/* put 1 int (from &x) to 1 int rank RCVR, at address 0 in window "win"*/
MPI_Put(&x, 1, MPI_INT, RCVR, 0, 1, MPI_INT, win);
/* Unlock */
MPI_Win_unlock(0, win);
printf("%d: My job here is done.\n", rank);
}
if (rank == RCVR) {
for (;;) {
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, RCVR, 0, win);
MPI_Get(&geta, 1, MPI_INT, RCVR, 0, 1, MPI_INT, win);
MPI_Win_unlock(0, win);
if (geta == 0) {
printf("%d: a still zero; sleeping.\n",rank);
sleep(2);
} else
break;
}
printf("%d: a now %d!\n",rank,geta);
printf("a = %d\n", *a);
MPI_Win_free(&win);
if (rank == RCVR) MPI_Free_mem(a);
MPI_Finalize();
return 0;
}