Project

General

Profile

Revision 939

Added by Ryan Cahoon over 15 years ago

added passing of overhead camera image to client through PHP
fixed unfreed memory in server/vision/savetonetwork.c

View differences:

trunk/code/projects/colonet/server/Main.cpp
45 45

  
46 46
  if (colonet_server.start_listening() < 0) {
47 47
    fprintf(stderr, "ColonetServer.start_listening failed.\n");
48
    cleanup(0);
48 49
    return -1;
49 50
  }
50 51

  
trunk/code/projects/colonet/server/vision/shmimgserve.h
1
#ifndef SHMIMGSERVE_H
2
#define SHMIMGSERVE_H
3

  
4
#include <cv.h>
5

  
6
#define JPEG_QUALITY  50
7

  
8
int sendImage(IplImage *image);
9

  
10
int openShM();
11
void releaseShM();
12

  
13
#endif
trunk/code/projects/colonet/server/vision/vision.c
17 17
#include <stdio.h>
18 18
#include <stdlib.h>
19 19

  
20
#include "shmimgserve.h"
21

  
20 22
#define MIN_PADDING 70
21 23

  
22
#define DEBUG 1 //Debug to find threshold level
24
#define DEBUG 0 //Debug to find threshold level
23 25

  
24
int write_JPEG_to_mem (unsigned char *storage, int length, IplImage *img, int quality);
25

  
26 26
struct CenterP {
27 27
  CvPoint center;
28 28
  int count;
......
42 42
    fprintf( stderr, "ERROR: capture is NULL \n" );
43 43
    return -1;
44 44
  }
45
  
46
  openShM();
45 47

  
46 48
  if (DEBUG)
47 49
  {
48
    printf("Vision debugging start\n");
49 50
    cvNamedWindow("mywindow1", CV_WINDOW_AUTOSIZE);
50 51
  }
51 52
  
......
57 58
  if (DEBUG)
58 59
    cvDestroyWindow("mywindow1");
59 60

  
61
  releaseShM();
62

  
60 63
  cvReleaseCapture(&capture);
61 64
  
62 65
  printf("Vision closed.\n");
63 66
}
64 67

  
65
int getImageBytes(unsigned char *buffer, int length)
66
{
67
  IplImage* im_capture;
68

  
69
  if(!cvGrabFrame(capture)){              // capture a frame 
70
    printf("Could not grab a frame\n\7");
71
    exit(0);
72
  }
73
  im_capture=cvRetrieveFrame(capture);           // retrieve the captured frame
74
  
75
  return write_JPEG_to_mem (buffer, length, im_capture, 30);
76
}
77

  
78 68
int vision_get_robot_positions(VisionPosition** positions) {
79 69
  IplImage *image03;
80 70

  
81 71
  if(!cvGrabFrame(capture)){              // capture a frame 
82
    printf("Could not grab a frame\n\7");
72
    printf("Could not grab a frame\n");
83 73
    return -1;
84 74
  }
85 75
  IplImage *im_capture=cvRetrieveFrame(capture);           // retrieve the captured frame
86
    
76
  
77
  sendImage(im_capture);
78
  
87 79
  image03 = cvCreateImage(cvGetSize(im_capture), im_capture->depth, 1);
88 80
  cvCvtColor(im_capture, image03, CV_RGB2GRAY);
89 81

  
......
103 95
    CvPoint center = cvPoint(cvRound(p[0]), cvRound(p[1]));
104 96
    int r = cvRound(p[2]);
105 97

  
106
    if (DEBUG) cvCircle( image03, center, 3, CV_RGB(255,255,255), -1, 8, 0 );
98
    if (DEBUG) cvCircle( image03, center, 3, CV_RGB(255,255,255), 3, 8, 0 );
107 99

  
108 100
    int dist2 = MIN_PADDING;
109 101
    int loc = count;
......
129 121
    if (loc == count) count++;
130 122
  }
131 123

  
132
  if (DEBUG)
133
  {
134
    for (i = 0; i < count; i++)
135
    {
136
      cvCircle( image03, centers[i].center, 60, CV_RGB(255,255,255), 3, 8, 0 );
137
    }
124
  if (DEBUG) cvShowImage( "mywindow1", image03 );
138 125

  
139
    cvShowImage( "mywindow1", image03 );
140
  }
141

  
142 126
  cvReleaseMemStorage(&storage);
143 127

  
144 128
  cvReleaseImage(&image03);
trunk/code/projects/colonet/server/vision/sysvsem.cpp
1
/*
2
   +----------------------------------------------------------------------+
3
   | PHP Version 5                                                        |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 1997-2008 The PHP Group                                |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 3.01 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | http://www.php.net/license/3_01.txt                                  |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Authors: Tom May <tom@go2net.com>                                    |
16
   |          Gavin Sherry <gavin@linuxworld.com.au>                      |
17
   +----------------------------------------------------------------------+
18
 */
19
 
20
/* $Id: sysvsem.c,v 1.51.2.3.2.3 2007/12/31 07:20:13 sebastian Exp $ */
21

  
22
/* Latest update build anc tested on Linux 2.2.14
23
 *
24
 * This has been built and tested on Solaris 2.6 and Linux 2.1.122.
25
 * It may not compile or execute correctly on other systems.
26
 *
27
 * sas: Works for me on Linux 2.0.36 and FreeBSD 3.0-current
28
 */
29

  
30
#include <sys/types.h>
31
#include <sys/ipc.h>
32
#include <sys/sem.h>
33
#include <errno.h>
34

  
35
#include <string.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38

  
39
#include <php/main/php_config.h>
40

  
41
#include "php_sysvsem.h"
42

  
43
#if !HAVE_SEMUN
44

  
45
union semun {
46
	int val;                    /* value for SETVAL */
47
	struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
48
	unsigned short int *array;  /* array for GETALL, SETALL */
49
	struct seminfo *__buf;      /* buffer for IPC_INFO */
50
};
51

  
52
#undef HAVE_SEMUN
53
#define HAVE_SEMUN 1
54

  
55
#endif
56

  
57
/* Semaphore functions using System V semaphores.  Each semaphore
58
 * actually consists of three semaphores allocated as a unit under the
59
 * same key.  Semaphore 0 (SYSVSEM_SEM) is the actual semaphore, it is
60
 * initialized to max_acquire and decremented as processes acquire it.
61
 * The value of semaphore 1 (SYSVSEM_USAGE) is a count of the number
62
 * of processes using the semaphore.  After calling semget(), if a
63
 * process finds that the usage count is 1, it will set the value of
64
 * SYSVSEM_SEM to max_acquire.  This allows max_acquire to be set and
65
 * track the PHP code without having a global init routine or external
66
 * semaphore init code.  Except see the bug regarding a race condition
67
 * php_sysvsem_get().  Semaphore 2 (SYSVSEM_SETVAL) serializes the
68
 * calls to GETVAL SYSVSEM_USAGE and SETVAL SYSVSEM_SEM.  It can be
69
 * acquired only when it is zero.
70
 */
71

  
72
#define SYSVSEM_SEM		0
73
#define SYSVSEM_USAGE	1
74
#define SYSVSEM_SETVAL	2
75

  
76
/* {{{ release_sysvsem_sem
77
 */
78
sysvsem::~sysvsem()
79
{
80
	struct sembuf sop[2];
81
	int opcount = 1;
82

  
83
	/* Decrement the usage count. */
84
	sop[0].sem_num = SYSVSEM_USAGE;
85
	sop[0].sem_op  = -1;
86
	sop[0].sem_flg = SEM_UNDO;
87
	/* Release the semaphore if it has been acquired but not released. */
88
	if (this->count) {
89
		sop[1].sem_num = SYSVSEM_SEM;
90
		sop[1].sem_op  = this->count;
91
		sop[1].sem_flg = SEM_UNDO;
92

  
93
		opcount++;
94
	}
95

  
96
	semop(this->semid, sop, opcount);
97
	
98
	
99
	//TODO: Need to auto remove() semaphore when SYSVSEM_USAGE is 0
100
	
101
	//efree(sem_ptr);
102
}
103
/* }}} */
104
#define SETVAL_WANTS_PTR
105

  
106
#if defined(_AIX)
107
#undef SETVAL_WANTS_PTR
108
#endif
109

  
110
/* {{{ proto resource sem_get(int key [, int max_acquire [, int perm [, int auto_release]])
111
	 Return an id for the semaphore with the given key, and allow max_acquire (default 1) processes to acquire it simultaneously */
112
/*  max_aquire = 1, perm = 0666, auto_release = 1 */
113
sysvsem::sysvsem(long key, long max_acquire, long perm, long auto_release) throw (sysvsem_error)
114
{
115
	int semid;
116
	struct sembuf sop[3];
117
	int count;
118

  
119
	/* Get/create the semaphore.  Note that we rely on the semaphores
120
	 * being zeroed when they are created.  Despite the fact that
121
	 * the(?)  Linux semget() man page says they are not initialized,
122
	 * the kernel versions 2.0.x and 2.1.z do in fact zero them.
123
	 */
124

  
125
	semid = semget(key, 3, perm|IPC_CREAT);
126
	if (semid == -1) {
127
		fprintf(stderr, "%s failed for key 0x%lx: %s\n", __FUNCTION__, key, strerror(errno));
128
		throw sysvsem_error("failed to open semaphore");
129
	}
130

  
131
	/* Find out how many processes are using this semaphore.  Note
132
	 * that on Linux (at least) there is a race condition here because
133
	 * semaphore undo on process exit is not atomic, so we could
134
	 * acquire SYSVSEM_SETVAL before a crashed process has decremented
135
	 * SYSVSEM_USAGE in which case count will be greater than it
136
	 * should be and we won't set max_acquire.  Fortunately this
137
	 * doesn't actually matter in practice.
138
	 */
139

  
140
	/* Wait for sem 1 to be zero . . . */
141

  
142
	sop[0].sem_num = SYSVSEM_SETVAL;
143
	sop[0].sem_op  = 0;
144
	sop[0].sem_flg = 0;
145

  
146
	/* . . . and increment it so it becomes non-zero . . . */
147

  
148
	sop[1].sem_num = SYSVSEM_SETVAL;
149
	sop[1].sem_op  = 1;
150
	sop[1].sem_flg = SEM_UNDO;
151

  
152
	/* . . . and increment the usage count. */
153

  
154
	sop[2].sem_num = SYSVSEM_USAGE;
155
	sop[2].sem_op  = 1;
156
	sop[2].sem_flg = SEM_UNDO;
157
	while (semop(semid, sop, 3) == -1) {
158
		if (errno != EINTR) {
159
			fprintf(stderr, "%s failed acquiring SYSVSEM_SETVAL for key 0x%lx: %s\n", __FUNCTION__, key, strerror(errno));
160
			break;
161
		}
162
	}
163

  
164
	/* Get the usage count. */
165
	count = semctl(semid, SYSVSEM_USAGE, GETVAL, NULL);
166
	if (count == -1) {
167
		fprintf(stderr, "%s failed for key 0x%lx: %s\n", __FUNCTION__, key, strerror(errno));
168
	}
169
	
170
	printf("proc count: %d\n", count);
171

  
172
	/* If we are the only user, then take this opportunity to set the max. */
173

  
174
	if (count == 1) {
175
#if HAVE_SEMUN
176
		/* This is correct for Linux which has union semun. */
177
		union semun semarg;
178
		semarg.val = max_acquire;
179
		if (semctl(semid, SYSVSEM_SEM, SETVAL, semarg) == -1) {
180
			fprintf(stderr, "%s failed for key 0x%lx: %s\n", __FUNCTION__, key, strerror(errno));
181
		}
182
#elif defined(SETVAL_WANTS_PTR)
183
		/* This is correct for Solaris 2.6 which does not have union semun. */
184
		if (semctl(semid, SYSVSEM_SEM, SETVAL, &max_acquire) == -1) {
185
			fprintf(stderr, "%s failed for key 0x%lx: %s\n", __FUNCTION__, key, strerror(errno));
186
		}
187
#else
188
		/* This works for i.e. AIX */
189
		if (semctl(semid, SYSVSEM_SEM, SETVAL, max_acquire) == -1) {
190
			fprintf(stderr, "%s failed for key 0x%lx: %s\n", __FUNCTION__, key, strerror(errno));
191
		}
192
#endif
193
	}
194

  
195
	/* Set semaphore 1 back to zero. */
196

  
197
	sop[0].sem_num = SYSVSEM_SETVAL;
198
	sop[0].sem_op  = -1;
199
	sop[0].sem_flg = SEM_UNDO;
200
	while (semop(semid, sop, 1) == -1) {
201
		if (errno != EINTR) {
202
			fprintf(stderr, "%s failed releasing SYSVSEM_SETVAL for key 0x%lx: %s\n", __FUNCTION__, key, strerror(errno));
203
			break;
204
		}
205
	}
206

  
207
	//sem_ptr = (sysvsem_sem *) emalloc(sizeof(sysvsem_sem));
208
	this->key   = key;
209
	this->semid = semid;
210
	this->count = 0;
211
	this->auto_release = auto_release;
212

  
213
	//this->id = (int)sem_ptr;
214
	
215
	//return sem_ptr;
216
}
217
/* }}} */
218

  
219
/* {{{ php_sysvsem_semop
220
 */
221
int sysvsem::php_sysvsem_semop(int acquire)
222
{
223
	struct sembuf sop;
224

  
225
	if (!acquire && this->count == 0) {
226
		fprintf(stderr, "SysV semaphore 0x%x is not currently acquired\n", this->key);
227
		return 0;
228
	}
229

  
230
	sop.sem_num = SYSVSEM_SEM;
231
	sop.sem_op  = acquire ? -1 : 1;
232
	sop.sem_flg = SEM_UNDO;
233

  
234
	while (semop(this->semid, &sop, 1) == -1) {
235
		if (errno != EINTR) {
236
			fprintf(stderr, "%s failed to %s semaphore 0x%x: %s\n", __FUNCTION__, acquire ? "acquire" : "release", this->key, strerror(errno));
237
			return 0;
238
		}
239
	}
240

  
241
	this->count -= acquire ? -1 : 1;
242
	return 1;
243
}
244
/* }}} */
245

  
246
/* {{{ proto bool sem_acquire(resource id)
247
	 Acquires the semaphore with the given id, blocking if necessary */
248
int sysvsem::sem_acquire()
249
{
250
	return this->php_sysvsem_semop(1);
251
}
252
/* }}} */
253

  
254
/* {{{ proto bool sem_release(resource id)
255
	 Releases the semaphore with the given id */
256
int sysvsem::sem_release()
257
{
258
	return this->php_sysvsem_semop(0);
259
}
260
/* }}} */
261

  
262
/* {{{ proto bool sem_remove(resource id)
263
	 Removes semaphore from Unix systems */
264

  
265
/*
266
 * contributed by Gavin Sherry gavin@linuxworld.com.au
267
 * Fri Mar 16 00:50:13 EST 2001
268
 */
269

  
270
int sysvsem::sem_remove()
271
{
272
#if HAVE_SEMUN
273
	union semun un;
274
	struct semid_ds buf;
275
#endif
276

  
277
#if HAVE_SEMUN
278
	un.buf = &buf;
279
	if (semctl(this->semid, 0, IPC_STAT, un) < 0) {
280
#else
281
	if (semctl(this->semid, 0, IPC_STAT, NULL) < 0) {
282
#endif
283
		fprintf(stderr, "SysV semaphore 0x%x does not (any longer) exist\n", this->key);
284
		return 0;
285
	}
286

  
287
#if HAVE_SEMUN
288
	if (semctl(this->semid, 0, IPC_RMID, un) < 0) {
289
#else
290
	if (semctl(this->semid, 0, IPC_RMID, NULL) < 0) {
291
#endif
292
		fprintf(stderr, "%s failed for SysV sempphore 0x%x: %s\n", __FUNCTION__, this->key, strerror(errno));
293
		return 0;
294
	}
295
	
296
	/* let release_sysvsem_sem know we have removed
297
	 * the semaphore to avoid issues with releasing.
298
	 */ 
299

  
300
	this->count = -1;
301
	return 1;
302
}
303

  
304
/* }}} */
305

  
306
/*
307
 * Local variables:
308
 * tab-width: 4
309
 * c-basic-offset: 4
310
 * End:
311
 * vim600: sw=4 ts=4 fdm=marker
312
 * vim<600: sw=4 ts=4
313
 */
trunk/code/projects/colonet/server/vision/savetonetwork.c
1 1
#include <stdio.h>
2 2
#include "jpeglib.h"
3 3
#include <cv.h>
4
#include "vision.h"
5 4
#include "memdst.h"
6 5

  
7 6
int write_JPEG_to_mem (unsigned char *storage, int length, IplImage *_img, int quality)
......
41 40
  jpeg_finish_compress(&cinfo);
42 41
  jpeg_destroy_compress(&cinfo);
43 42
  
43
  cvReleaseImage(&img);
44
  
44 45
  return numBytes;
45 46
}
46 47

  
trunk/code/projects/colonet/server/vision/php_sysvsem.h
1
/* 
2
   +----------------------------------------------------------------------+
3
   | PHP Version 5                                                        |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 1997-2008 The PHP Group                                |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 3.01 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | http://www.php.net/license/3_01.txt                                  |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Author: Tom May <tom@go2net.com>                                     |
16
   +----------------------------------------------------------------------+
17
*/
18

  
19
/* $Id: php_sysvsem.h,v 1.16.2.1.2.2 2007/12/31 07:20:13 sebastian Exp $ */
20

  
21
#ifndef PHP_SYSVSEM_H
22
#define PHP_SYSVSEM_H
23

  
24
#include <stdexcept>
25
#include <string>
26

  
27
struct sysvsem_error : public std::runtime_error
28
{
29
    sysvsem_error(const std::string& msg) : runtime_error(msg){}
30
};
31

  
32
class sysvsem {
33
private:
34
	//int id;						/* For error reporting. */
35
	int key;					/* For error reporting. */
36
	int semid;					/* Returned by semget(). */
37
	int count;					/* Acquire count for auto-release. */
38
	int auto_release;			/* flag that says to auto-release. */
39

  
40
	int php_sysvsem_semop(int acquire);
41
	
42
public:
43
	sysvsem(long key, long max_acquire = 1, long perm = 0666, long auto_release = 1) throw (sysvsem_error);
44
	~sysvsem();
45
	int sem_acquire();
46
	int sem_release();
47
	int sem_remove();
48
};
49

  
50
#endif /* PHP_SYSVSEM_H */
trunk/code/projects/colonet/server/vision/shmimgserve.cpp
1
#include "shmimgserve.h"
2

  
3
#include <stdio.h>
4
#include <string.h>
5
#include <stdlib.h>
6

  
7
#include <errno.h>
8

  
9
#include <sys/types.h>
10
#include <sys/shm.h>
11

  
12
#include "php_sysvsem.h"
13

  
14
#define DEBUG 0
15

  
16
#if DEBUG
17
#define dbg_printf(...)   printf(__VA_ARGS__)
18
#else
19
#define dbg_printf(...) 
20
#endif
21

  
22
int write_JPEG_to_mem (unsigned char *storage, int length, IplImage *_img, int quality);
23

  
24
static sysvsem *sem;
25
static int shm_id;
26

  
27
int sendImage(IplImage *image)
28
{
29
  dbg_printf("Send image\n");
30

  
31
	if (sem->sem_acquire())
32
	{
33
		dbg_printf("Semaphore acquired\n");
34

  
35
		unsigned char *p = (unsigned char *)shmat(shm_id, NULL, 0);
36
		if (p!=(void *)-1)
37
		{
38
			dbg_printf("Memory mapped at %p\n", p);
39

  
40
			int len = write_JPEG_to_mem (p+4, 150000-4, image, JPEG_QUALITY);
41

  
42
			int i;
43
			int length = len;
44
			dbg_printf("%d\n", length);
45
			for(i=0; i < 4; i++)
46
			{
47
				char digit = (char)(length & 0xff);
48
				length >>= 8;
49
				memcpy(p+i, &digit, sizeof(char));
50
			}
51

  
52
			dbg_printf("Memory copied\n");
53
			
54
			sem->sem_release();
55
			dbg_printf("Semaphore released\n");
56
			
57
			shmdt(p);
58
		  dbg_printf("Memory detached\n");
59
		}
60
	}
61

  
62
  if (errno!=0)
63
  {
64
    int errnum = errno;
65
    errno = 0;
66
    
67
    fprintf(stderr, "error %d %s\n", errnum, strerror(errnum));
68
    return errnum;
69
  }
70
  
71
  return 0;
72
}
73

  
74
int openShM()
75
{
76
	shm_id = shmget(0x40305163, 150000, IPC_CREAT | 0666);
77
	if (shm_id > 0)
78
		dbg_printf("Shared memory opened\n");
79
	else
80
	{
81
		fprintf(stderr, "Error opening shared memory\n");
82
		return -1;
83
	}
84
		
85
  sem = new (std::nothrow)sysvsem(0x40309999);
86
  if (sem)
87
		dbg_printf("Semaphore opened\n");
88
	else
89
	{
90
		fprintf(stderr, "Error opening semaphore\n");
91
		return -2;
92
	}
93
}
94

  
95
void releaseShM()
96
{
97
  sem->sem_remove();
98
	delete sem;
99
	dbg_printf("Semaphore deleted\n");
100

  
101
  shmctl(shm_id, IPC_RMID, NULL);
102
  dbg_printf("Memory marked for deletion\n");
103
}
trunk/code/projects/colonet/server/vision/Makefile
2 2

  
3 3
CC = g++
4 4

  
5
all: clean_programs clean_vision savetonetwork vision vision_driver fitellipse
5
all: clean_programs clean_vision shmimgserve vision vision_driver fitellipse
6 6

  
7
savetonetwork:
8
	$(CC) -ggdb `pkg-config opencv --cflags ` -c -g -I . memdst.c
7
shmimgserve:
8
	$(CC) -ggdb `pkg-config opencv --cflags` -c -g -I . memdst.c
9 9
	$(CC) -ggdb `pkg-config opencv --cflags` -c -g -I . savetonetwork.c
10
	$(CC) -ggdb                              -c -g -I . sysvsem.cpp
11
	$(CC) -ggdb `pkg-config opencv --cflags` -c -g -I . shmimgserve.cpp
10 12

  
11 13
vision:
12 14
	$(CC) -ggdb `pkg-config opencv --cflags` -c -I . vision.c
13 15

  
14
vision_driver: vision
15
	$(CC) -ggdb `pkg-config opencv --cflags --libs` -g -I. -L. vision_driver.c memdst.o savetonetwork.o vision.o -ljpeg -o vision_driver
16
vision_driver: vision shmimgserve
17
	$(CC) -ggdb `pkg-config opencv --cflags --libs` -g -I. -L. vision_driver.c memdst.o savetonetwork.o sysvsem.o shmimgserve.o vision.o -ljpeg -o vision_driver
16 18

  
17 19
fitellipse: 
18 20
	$(CC) -ggdb `pkg-config opencv --cflags --libs` fitellipse.c -o fitellipse
trunk/code/projects/colonet/server/vision/shmservetest.cpp
1
#include <cv.h>
2
#include <highgui.h>
3

  
4
#include <stdio.h>
5

  
6
#define CAPTURE
7

  
8
#ifdef CAPTURE
9
static CvCapture *capture;
10
#endif
11

  
12
#include <sys/types.h>
13
#include <sys/shm.h>
14
#include <string.h>
15
#include <stdlib.h>
16

  
17
#include "php_sysvsem.h"
18

  
19
#include <errno.h>
20

  
21
int write_JPEG_to_mem (unsigned char *storage, int length, IplImage *_img, int quality);
22

  
23
static sysvsem *sem;
24
static int shm_id;
25

  
26
int sendImage(IplImage *image)
27
{
28
  printf("Send image\n");
29

  
30
	if (sem->sem_acquire())
31
	{
32
		printf("Semaphore acquired\n");
33

  
34
		unsigned char *p = (unsigned char *)shmat(shm_id, NULL, 0);
35
		if (p!=(void *)-1)
36
		{
37
			printf("Memory mapped at %p\n", p);
38

  
39
			int len = write_JPEG_to_mem (p+4, 150000-4, image, 30);
40

  
41
			int i;
42
			int length = len;
43
			printf("%d\n", length);
44
			for(i=0; i < 4; i++)
45
			{
46
				char digit = (char)(length & 0xff);
47
				length >>= 8;
48
				memcpy(p+i, &digit, sizeof(char));
49
			}
50

  
51
			printf("Memory copied\n");
52
			
53
			sem->sem_release();
54
			printf("Semaphore released\n");
55
			
56
			shmdt(p);
57
		  printf("Memory detached\n");
58
		}
59
	}
60

  
61
  if (errno!=0)
62
  {
63
    int errnum = errno;
64
    errno = 0;
65
    
66
    fprintf(stderr, "error %d %s\n", errnum, strerror(errnum));
67
    return errnum;
68
  }
69
  
70
  return 0;
71
}
72

  
73
void openShM()
74
{
75
	shm_id = shmget(0x40305163, 150000, IPC_CREAT | 0666);
76
	if (shm_id > 0)
77
		printf("Shared memory opened\n");
78
	else
79
	{
80
		fprintf(stderr, "Error opening shared memory\n");
81
		exit(-2);
82
	}
83
		
84
  sem = new (std::nothrow)sysvsem(0x40309999);
85
  if (sem)
86
		printf("Semaphore opened\n");
87
	else
88
	{
89
		fprintf(stderr, "Error opening semaphore\n");
90
		exit(-1);
91
	}
92
}
93

  
94
void releaseShM()
95
{
96
  sem->sem_remove();
97
	delete sem;
98
	printf("Semaphore deleted\n");
99

  
100
  shmctl(shm_id, IPC_RMID, NULL);
101
  printf("Memory marked for deletion\n");
102
}
103

  
104
int main(int argc, char *argv[])
105
{
106
#ifdef CAPTURE
107
  capture = cvCaptureFromCAM( 0 );
108
  if( !capture ) {
109
    fprintf( stderr, "ERROR: capture is NULL \n" );
110
    return -1; 	
111
  }
112
#endif
113

  
114
	openShM();
115

  
116
  // Create a window in which the captured images will be presented
117
  //cvNamedWindow( "mywindow1", CV_WINDOW_AUTOSIZE );
118

  
119
  // Show the image captured from the camera in the window and repeat
120
  while((cvWaitKey(10) & 255) != 27)
121
  {
122
    usleep(15000);
123
    
124
#ifdef CAPTURE
125
    if(!cvGrabFrame(capture)){              // capture a frame
126
      printf("Could not grab a frame\n\7");
127
      return -1;
128
    }
129
    IplImage *image03=cvRetrieveFrame(capture);
130
#else
131
    IplImage *image03;
132
    // load image and force it to be grayscale
133
    if ((image03 = cvLoadImage(argv[1], 0)) == 0) {
134
      fprintf(stderr, "Failed to load image.\n");
135
      return -1;
136
    }
137
#endif
138

  
139
    //cvShowImage( "mywindow1", image03 );
140

  
141
    sendImage(image03);
142

  
143
#ifndef CAPTURE
144
    cvReleaseImage(&image03);
145
#endif
146

  
147
    //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
148
    //remove higher bits using AND operator
149
  }
150

  
151
#ifdef CAPTURE
152
  // Release the capture device housekeeping
153
  cvReleaseCapture( &capture );
154
#endif
155

  
156
  releaseShM();
157
  
158
  cvDestroyWindow( "mywindow1" );
159
  return 0;
160
}
trunk/code/projects/colonet/server/ColonetServer.cpp
66 66

  
67 67
  if (initialize_wireless() < 0) {
68 68
    fprintf(stderr, "%s: initWireless failed\n", __FUNCTION__);
69
    return -1;
69
    //TODO: Can we continue safely without wireless?
70
    //return -1;
70 71
  }
71 72

  
72 73
  return 0;
......
111 112
  return 0;
112 113
}
113 114

  
115
/**
116
 * @brief The function that is run in the new pthread in order to do the client processing
117
 */
114 118
void ColonetServer::loop_server() {
115 119
  //add the socket that you will listen to connections on to the connection pool
116 120
  connection_pool->add_new_socket_to_pool(listen_socket);
......
178 182
  }
179 183
}
180 184

  
185
/**
186
 * @brief Launchpad function to start loop_server() since callbacks don't support member functions
187
 *
188
 * @param arg the argument to give to the new thread
189
 */
181 190
void * launch_loop_server(void *arg) {
182 191
  ColonetServer *object = (ColonetServer*) arg;
183 192
  object->loop_server();
......
195 204
  return 0;
196 205
}
197 206

  
207
/**
208
 * @brief Main loop of the server, runs periodic tasks
209
 *
210
 * @return 0 on success, negative error code on failure
211
 */
198 212
int ColonetServer::run_loop() {
199 213

  
200 214
  int refresh_virtual_wall_count = 0;
trunk/code/projects/colonet/server/Makefile
13 13
LOGGINGFILES = Log.cpp
14 14
LOGGINGOBJECTS = $(LOGGINGFILES:.cpp=.o)
15 15

  
16
VISIONOBJECTS = vision/vision.o vision/savetonetwork.o vision/memdst.o
16
VISIONOBJECTS = vision/vision.o vision/savetonetwork.o vision/memdst.o vision/sysvsem.o vision/shmimgserve.o
17 17

  
18 18
COLONETHEADERFILES = includes/*.h
19 19

  
trunk/code/projects/colonet/server/PositionMonitor.cpp
18 18
//Based on 640x480 resolution
19 19
//TODO: Change detection constants to be dependent on resolution
20 20
#define MAX_POSITIONS 20
21
#define SAME_ROBOT_DISTANCE_THRESHOLD 60
21
#define SAME_ROBOT_DISTANCE_THRESHOLD 60 //TODO: This needs some tuning
22 22
#define ROBOT_DELETE_BUFFER 10
23 23
#define CAM_UPDATE_PERIOD 100000
24 24

  
trunk/code/projects/colonet/client/ColonetConstants.java
14 14
	public static final int BATTERY_WIDTH = 50;
15 15
	public static final int BATTERY_HEIGHT = 10;
16 16
	public static final int WEBCAM_DELAY = 500;
17
	public static final String WEBCAM_PATH = "http://128.2.99.176/overhead.jpg";
17
	public static final String WEBCAM_PATH = "http://128.2.99.176/colonet/overheadimage.php";
18 18

  
19 19
  // Set the default look and feel - choose one
20 20
  public static final String LOOK_AND_FEEL = javax.swing.UIManager.getSystemLookAndFeelClassName();
trunk/code/projects/colonet/client/overheadimage.php
1
<?php
2
header('Content-Type: image/jpeg');
3

  
4
$sem_key = 0x40309999;
5
$shm_key = 0x40305163;
6

  
7
$sem_id = sem_get($sem_key, 1);
8
if (!sem_acquire($sem_id))
9
{
10
   print "Error acquiring semaphore\n";
11
   return;
12
}
13

  
14
$shm_id = shmop_open($shm_key, 'a', 0666, 150000);
15
if ($shm_id===false)
16
{
17
   print "Error opening shared memory\n";
18
   return;
19
}
20

  
21
$size = shmop_read($shm_id, 0, 4);
22
$length = 0;
23
for ($i=strlen($size)-1; $i >= 0; $i--)
24
{
25
   $length <<= 8;
26
   $length |= ord(substr($size, $i));
27
}
28
$data = shmop_read($shm_id, 4, $length);
29

  
30
shmop_close($shm_id);
31

  
32
sem_release($sem_id);
33

  
34
print $data;
35
?>
trunk/code/projects/colonet/client/AppletViewer.java
1
/*
2
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002.
3
 * All rights reserved. Software written by Ian F. Darwin and others.
4
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
19
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
 * POSSIBILITY OF SUCH DAMAGE.
26
 * 
27
 * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee
28
 * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's,
29
 * pioneering role in inventing and promulgating (and standardizing) the Java 
30
 * language and environment is gratefully acknowledged.
31
 * 
32
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
33
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
34
 */
35

  
36
import java.applet.Applet;
37
import java.applet.AppletContext;
38
import java.applet.AppletStub;
39
import java.applet.AudioClip;
40
import java.awt.BorderLayout;
41
import java.awt.Container;
42
import java.awt.Dimension;
43
import java.awt.Image;
44
import java.awt.Label;
45
import java.awt.Panel;
46
import java.awt.event.WindowAdapter;
47
import java.awt.event.WindowEvent;
48
import java.io.IOException;
49
import java.io.InputStream;
50
import java.net.URL;
51
import java.util.Enumeration;
52
import java.util.HashMap;
53
import java.util.Iterator;
54
import java.util.Map;
55

  
56
import javax.swing.JFrame;
57

  
58
/*
59
 * AppletViewer - a simple Applet Viewer program.
60
 * @author  Ian Darwin, http://www.darwinsys.com/
61
 */
62
public class AppletViewer {
63
  /** The main Frame of this program */
64
  JFrame f;
65
  /** The AppletAdapter (gives AppletStub, AppletContext, showStatus) */
66
  static AppletAdapter aa = null;
67
  /** The name of the Applet subclass */
68
  String appName = null;
69
  /** The Class for the actual applet type */
70
  Class ac = null;
71
  /** The Applet instance we are running, or null. Can not be a JApplet
72
   * until all the entire world is converted to JApplet. */
73
  Applet ai = null;
74
  /** The width of the Applet */
75
  final int WIDTH = 250;
76
  /** The height of the Applet */
77
  final int HEIGHT = 200;
78

  
79
  /** Main is where it all starts. 
80
   * Construct the GUI. Load the Applet. Start it running.
81
   */
82
  public static void main(String[] av) {
83
    if (av.length==0)
84
    {
85
      System.err.println("No class name specified\n");
86
      System.exit(1);
87
    }
88
    
89
    new AppletViewer(av[0]);
90
  }
91

  
92
  /** Construct the GUI for an Applet Viewer */
93
  AppletViewer(String appName) {
94
    super();
95

  
96
    this.appName = appName;
97

  
98
    f = new JFrame(appName);
99
    f.addWindowListener(new WindowAdapter() {
100
      public void windowClosing(WindowEvent e) {
101
        f.setVisible(false);
102
        f.dispose();
103
        System.exit(0);
104
      }
105
    });
106
    Container cp = f.getContentPane();
107
    cp.setLayout(new BorderLayout());
108

  
109
    // Instantiate the AppletAdapter which gives us
110
    // AppletStub and AppletContext.
111
    if (aa == null)
112
      aa = new AppletAdapter();
113

  
114
    // The AppletAdapter also gives us showStatus.
115
    // Therefore, must add() it very early on, since the Applet's
116
    // Constructor or its init() may use showStatus()
117
    cp.add(BorderLayout.SOUTH, aa);
118

  
119
    showStatus("Loading Applet " + appName);
120

  
121
    loadApplet(appName , WIDTH, HEIGHT);  // sets ac and ai
122
    if (ai == null)
123
      return;
124

  
125
    // Now right away, tell the Applet how to find showStatus et al.
126
    ai.setStub(aa);
127

  
128
    // Connect the Applet to the Frame.
129
    cp.add(BorderLayout.CENTER, ai);
130

  
131
    Dimension d = ai.getSize();
132
    d.height += aa.getSize().height;
133
    f.setSize(d);
134
    f.setVisible(true);    // make the Frame and all in it appear
135

  
136
    showStatus("Applet " + appName + " loaded");
137

  
138
    // Here we pretend to be a browser!
139
    ai.init();
140
    ai.start();
141
  }
142

  
143
  /*
144
   * Load the Applet into memory. Should do caching.
145
   */
146
  void loadApplet(String appletName, int w, int h) {
147
    // appletName = ... extract from the HTML CODE= somehow ...;
148
    // width =     ditto
149
    // height =     ditto
150
    try {
151
      // get a Class object for the Applet subclass
152
      ac = Class.forName(appletName);
153
      // Construct an instance (as if using no-argument constructor)
154
      ai = (Applet) ac.newInstance();
155
    } catch(ClassNotFoundException e) {
156
      showStatus("Applet subclass " + appletName + " did not load");
157
      return;
158
    } catch (Exception e ){
159
      showStatus("Applet " + appletName + " did not instantiate");
160
      return;
161
    }
162
    ai.setSize(w, h);
163
  }
164

  
165
  public void showStatus(String s) {
166
    aa.getAppletContext().showStatus(s);
167
  }
168
}
169

  
170
/*
171
 * AppletAdaptor: partial implementation of AppletStub and AppletContext.
172
 *
173
 * This code is far from finished, as you will see.
174
 *
175
 * @author  Ian Darwin, http://www.darwinsys.com/, for Learning Tree Course 478
176
 */
177
class AppletAdapter extends Panel implements AppletStub, AppletContext {
178
  /** The status window at the bottom */
179
  Label status = null;
180

  
181
  /** Construct the GUI for an Applet Status window */
182
  AppletAdapter() {
183
    super();
184

  
185
    // Must do this very early on, since the Applet's
186
    // Constructor or its init() may use showStatus()
187
    add(status = new Label());
188

  
189
    // Give "status" the full width
190
    status.setSize(getSize().width, status.getSize().height);
191

  
192
    showStatus("AppletAdapter constructed");  // now it can be said
193
  }
194

  
195
  /****************** AppletStub ***********************/
196
  /** Called when the applet wants to be resized.  */
197
  public void appletResize(int w, int h) {
198
    // applet.setSize(w, h);
199
  }
200

  
201
  /** Gets a reference to the applet's context.  */
202
  public AppletContext getAppletContext() {
203
    return this;
204
  }
205

  
206
  /** Gets the base URL.  */
207
  public URL getCodeBase() {
208
    return getClass().getResource(".");
209
  }
210

  
211
  /** Gets the document URL.  */
212
  public URL getDocumentBase() {
213
    return getClass().getResource(".");
214
  }
215

  
216
  /** Returns the value of the named parameter in the HTML tag.  */
217
  public String getParameter(String name) {
218
    String value = null;
219
    return value;
220
  }
221
  /** Determines if the applet is active.  */
222
  public boolean isActive() {
223
    return true;
224
  }
225

  
226
  /************************ AppletContext ************************/
227

  
228
  /** Finds and returns the applet with the given name. */
229
  public Applet getApplet(String an) {
230
    return null;
231
  }
232

  
233
  /** Finds all the applets in the document */
234
  public Enumeration<Applet> getApplets()  {
235
    class AppletLister implements Enumeration<Applet> {
236
      public boolean hasMoreElements() {
237
        return false;
238
      }
239
      public Applet nextElement() {
240
        return null;
241
      }
242
    }
243
    return new AppletLister();
244
  }
245

  
246
  /** Create an audio clip for the given URL of a .au file */
247
  public AudioClip getAudioClip(URL u) {
248
    return null;
249
  }
250

  
251
  /** Look up and create an Image object that can be paint()ed */
252
  public Image getImage(URL u)  {
253
    return null;
254
  }
255

  
256
  /** Request to overlay the current page with a new one - ignored */
257
  public void showDocument(URL u) {
258
  }
259

  
260
  /** as above but with a Frame target */
261
  public void showDocument(URL u, String frame)  {
262
  }
263

  
264
  /** Called by the Applet to display a message in the bottom line */
265
  public void showStatus(String msg) {
266
    if (msg == null)
267
      msg = "";
268
    status.setText(msg);
269
  }
270

  
271
  /* StreamKey stuff - new in JDK1.4 */
272
  Map<String, InputStream> streamMap = new HashMap<String, InputStream>();
273

  
274
  /** Associate the stream with the key. */
275
  public void setStream(String key, InputStream stream) throws IOException {
276
    streamMap.put(key, stream);
277
  }
278

  
279
  public InputStream getStream(String key) {
280
    return streamMap.get(key);
281
  }
282

  
283
  public Iterator<String> getStreamKeys() {
284
    return streamMap.keySet().iterator();
285
  }
286
}
trunk/code/projects/colonet/client/Makefile
46 46
	cp $(DIR)/Colonet.jar /var/www/colonet/Colonet.jar
47 47
	cp index.xhtml /var/www/colonet/index.xhtml
48 48
	cp colonetstyle.css /var/www/colonet/colonetstyle.css
49
	cp overheadimage.php /var/www/colonet/overheadimage.php
49 50

  
50 51
clean:
51 52
	$(RM) -r $(DIR)

Also available in: Unified diff