00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <iostream>
00035 #include <sstream>
00036 #include <vector>
00037 #include <algorithm>
00038 #include <string>
00039 #include <cstring>
00040 #include <cmath>
00041 #include <cerrno>
00042 #include <unistd.h>
00043 #include <igraph/igraph.h>
00044 #include "sim_phenomena.h"
00045 #include "sim_graph.h"
00046
00047
00048
00049 SensorData::SensorData(Phenom t, int x_val, int y_val, SensorData *n)
00050 {
00051 source = Phenomenon::PhenomenonFactory(t);
00052 x = x_val;
00053 y = y_val;
00054 strength = 0;
00055 time = 0;
00056 on_path = false;
00057 if (source->isAmbient())
00058 prev = NULL;
00059 else
00060 prev = n;
00061 }
00062
00063
00064 SensorData::SensorData(Phenom t, char* in, SensorData *n)
00065 {
00066 source = Phenomenon::PhenomenonFactory(t);
00067 sscanf(in, "%lld:%u:%u:%d", &time, &x, &y, &strength);
00068 on_path = false;
00069 if (source->isAmbient())
00070 prev = NULL;
00071 else
00072 prev = n;
00073 }
00074
00075
00076 bool SensorData::operator==(const SensorData &other)
00077 {
00078 if (abs(x - other.x) <= 5 && abs(y - other.y) <= 5)
00079 return true;
00080 return false;
00081 }
00082
00083
00084 bool SensorData::operator!=(const SensorData &other)
00085 {
00086 if (abs(x - other.x) > 5 && abs(y - other.y) > 5)
00087 return true;
00088 return false;
00089 }
00090
00091
00092 bool SensorData::operator<(const SensorData &other) const
00093 {
00094 return time > other.time;
00095 }
00096
00097
00098 const char* SensorData::toString(bool cfg)
00099 {
00100 std::ostringstream line;
00101 line << source->toString(cfg) << ":" << time << ":"
00102 << x << ":" << y << ":" << strength << std::endl;
00103 return line.str().c_str();
00104 }
00105
00106
00107 unsigned int SensorData::distanceTo(const SensorData &other)
00108 {
00109 return (int)(distance(x, y, other.x, other.y));
00110 }
00111
00112
00114
00115
00116 Phenomenon::Phenomenon(Phenom t, std::string s, std::string c, bool a, bool g) :
00117 _type(t), _string(s), _color(c), _ambient(a), _global(g) {}
00118
00119 const char* Phenomenon::toString(bool cfg) {
00120 if (cfg && _global) {
00121 if (_type == SOUND)
00122 return phenoms[STARTSOUND];
00123 if (_type == LIGHT)
00124 return phenoms[STARTLIGHT];
00125 if (_type == AMBTEMP)
00126 return phenoms[STARTTEMP];
00127 if (_type == RAD)
00128 return phenoms[STARTRAD];
00129 if (_type == ACCEL_X)
00130 return phenoms[STARTACCEL_X];
00131 if (_type == MAG_X)
00132 return phenoms[STARTMAG_X];
00133 return _string.c_str();
00134 }
00135 else
00136 return _string.c_str();
00137 }
00138
00139 void Phenomenon::toOutput(FILE *stream, unsigned long long time,
00140 unsigned short node, unsigned short strength,
00141 int x1, int y1, int x2, int y2) {
00142 unsigned short stren = static_cast<unsigned short>
00143 (round(strength * fadeRate(distance(x1, y1, x2, y2))));
00144 if (_global)
00145 stren = strength;
00146 if (stren > 0)
00147 fprintf(stream, "%llu:%hu:%hhu:%hu\n",
00148 time, node, tossim_ports[_type], stren);
00149 fflush(stream);
00150 }
00151
00152
00153 Light::Light(Phenom t, std::string s, bool g) :
00154 Phenomenon(t, s, "yellow", false, g) {}
00155
00156
00157 Sound::Sound(Phenom t, std::string s, bool g) :
00158 Phenomenon(t, s, "blue", false, g) {}
00159
00160 double Sound::fadeRate(double dist) {
00161 return (1.0 / dist);
00162 }
00163
00164 double Sound::fadeDistance(double strength) {
00165 return strength + 1.0;
00166 }
00167
00168
00169 Accel::Accel(Phenom t, std::string s, bool g) :
00170 Phenomenon(t, s, "brown", false, g) {}
00171
00172 double Accel::fadeRate(double dist) {
00173 return (1.0 / dist);
00174 }
00175
00176 double Accel::fadeDistance(double strength) {
00177 return strength + 1.0;
00178 }
00179 void Accel::toOutput(FILE *stream, unsigned long long time,
00180 unsigned short node, unsigned short strength,
00181 int x1, int y1, int x2, int y2) {
00182 double dist = abs(x1 - x2);
00183 unsigned short stren = static_cast<unsigned short>
00184 (round(strength * fadeRate(dist)));
00185 if (_global)
00186 stren = strength;
00187 if (stren > 0)
00188 fprintf(stream, "%llu:%hu:%hhu:%hu\n",
00189 time, node, tossim_ports[ACCEL_X], stren);
00190 dist = abs(y1 - y2);
00191 stren = static_cast<unsigned short> (round(strength * fadeRate(dist)));
00192 if (_global)
00193 stren = strength;
00194 if (stren > 0)
00195 fprintf(stream, "%llu:%hu:%hhu:%hu\n",
00196 time, node, tossim_ports[ACCEL_Y], stren);
00197 fflush(stream);
00198 }
00199
00200
00201 Mag::Mag(Phenom t, std::string s, bool g) :
00202 Phenomenon(t, s, "purple", false, g) {}
00203
00204 void Mag::toOutput(FILE *stream, unsigned long long time,
00205 unsigned short node, unsigned short strength,
00206 int x1, int y1, int x2, int y2) {
00207 double dist = abs(x1 - x2);
00208 unsigned short stren = static_cast<unsigned short>
00209 (round(strength * fadeRate(dist)));
00210 if (_global)
00211 stren = strength;
00212 if (stren > 0)
00213 fprintf(stream, "%llu:%hu:%hhu:%hu\n",
00214 time, node, tossim_ports[MAG_X], stren);
00215 dist = abs(y1 - y2);
00216 stren = static_cast<unsigned short> (round(strength * fadeRate(dist)));
00217 if (_global)
00218 stren = strength;
00219 if (stren > 0)
00220 fprintf(stream, "%llu:%hu:%hhu:%hu\n",
00221 time, node, tossim_ports[MAG_Y], stren);
00222 fflush(stream);
00223 }
00224
00225
00226 Rad::Rad(Phenom t, std::string s, bool g) :
00227 Phenomenon(t, s, "green", false, g) {}
00228
00229
00230 AmbientPhenomenon::AmbientPhenomenon(Phenom t, std::string s,
00231 unsigned int i, std::string c, bool g) :
00232 Phenomenon(t, s, c, true, g), _range(i) {}
00233
00234 AmbientSound::AmbientSound(Phenom t, std::string s, unsigned int i) :
00235 AmbientPhenomenon(t, s, i, "blue") {}
00236
00237 AmbientLight::AmbientLight(Phenom t, std::string s, unsigned int i) :
00238 AmbientPhenomenon(t, s, i, "yellow") {}
00239
00240 AmbientTemp::AmbientTemp(Phenom t, std::string s, unsigned int i, bool g) :
00241 AmbientPhenomenon(t, s, i, "red", g) {}
00242
00243 AmbientRad::AmbientRad(Phenom t, std::string s, unsigned int i) :
00244 AmbientPhenomenon(t, s, i, "green") {}
00245
00246
00247 Phenomenon* Phenomenon::PhenomenonFactory(Phenom t)
00248 {
00249 switch(t) {
00250 case AMBSOUND:
00251 return new AmbientSound();
00252 case AMBLIGHT:
00253 return new AmbientLight();
00254 case AMBTEMP:
00255 return new AmbientTemp();
00256 case AMBRAD:
00257 return new AmbientRad();
00258
00259 case SOUND:
00260 return new Sound();
00261 case LIGHT:
00262 return new Light();
00263 case ACCEL_X:
00264 case ACCEL_Y:
00265 return new Accel();
00266 case MAG_X:
00267 case MAG_Y:
00268 return new Mag();
00269 case RAD:
00270 return new Rad();
00271
00272 case STARTSOUND:
00273 return new Sound(SOUND, phenoms[SOUND], true);
00274 case STARTLIGHT:
00275 return new Light(LIGHT, phenoms[LIGHT], true);
00276 case STARTTEMP:
00277 return new AmbientTemp(AMBTEMP, phenoms[AMBTEMP], 300, true);
00278 case STARTACCEL_X:
00279 case STARTACCEL_Y:
00280 return new Accel(ACCEL_X, phenoms[ACCEL_X], true);
00281 case STARTMAG_X:
00282 case STARTMAG_Y:
00283 return new Mag(MAG_X, phenoms[MAG_X], true);
00284 case STARTRAD:
00285 return new Rad(RAD, phenoms[RAD], true);
00286
00287 case NONE:
00288 default:
00289 return new Phenomenon();
00290 }
00291 }
00292
00293
00295
00296
00297 int compute_adc(const char* scenario, const char* network, const char* adc)
00298 {
00299 int err = 0;
00300 FILE *tmp;
00301 const char *temp_name = "temp";
00302 char* line = NULL;
00303 size_t unused;
00304 int len = 0;
00305 SensorData *datum = NULL;
00306 std::vector<SensorData> data;
00307
00308 igraph_i_set_attribute_table(&igraph_cattribute_table);
00309
00310 FILE *adc_data_file;
00311 if ((adc_data_file = fopen(adc, "w")) == NULL) {
00312 perror("fopen");
00313 return -errno;
00314 }
00315 #if 0
00316 FILE *scene_data_file;
00317 if ((scene_data_file = fopen(scenario, "r")) == NULL) {
00318 perror("fopen");
00319 return -errno;
00320 }
00321 if ((tmp = fopen(temp_name, "w+")) == NULL) {
00322 perror("fopen");
00323 return -errno;
00324 }
00325
00326 if ((err = read_scenario(scene_data_file, data)) < 0)
00327 return err;
00328 fclose(scene_data_file);
00329
00330 make_heap(data.begin(), data.end());
00331 sort_heap(data.begin(), data.end());
00332 for (unsigned int i = 0; i < data.size(); i++) {
00333 SensorData d = data[i];
00334 fprintf(tmp, "%s", d.toString(true));
00335 }
00336 data.clear();
00337
00338 std::cout << "Scenario loaded. Computing sensor interaction..." << std::endl;
00339 rewind(tmp);
00340 #else
00341 if ((tmp = fopen(scenario, "r")) == NULL) {
00342 perror("fopen");
00343 return -errno;
00344 }
00345 #endif
00346 while((len = getline(&line, &unused, tmp)) != -1) {
00347 if (len < 2)
00348 continue;
00349
00350 int ph_len = 0;
00351 bool seen = false;
00352 Phenom current = NONE;
00353 for (Phenom i = Phenom_MIN; i < Phenom_MAX; ++i) {
00354 if (strncasecmp(line, phenoms[i], strlen(phenoms[i])) == 0) {
00355 current = i;
00356 ph_len = strlen(phenoms[i]) + 1;
00357 seen = true;
00358 break;
00359 }
00360 }
00361 if (!seen)
00362 continue;
00363 datum = new SensorData(current, line + ph_len, datum);
00364 double radius = datum->source->fadeDistance(datum->strength);
00365 free(line);
00366 line = NULL;
00367
00368 igraph_t neighbor_graph;
00369 igraph_vs_t selector;
00370 igraph_vit_t neighbors;
00371 if (datum->source->isGlobal()){
00372 FILE *net_file = NULL;
00373 igraph_vs_all(&selector);
00374 if ((net_file = fopen(network, "r")) == NULL) {
00375 perror("fopen");
00376 return -errno;
00377 }
00378 if ((err = igraph_read_graph_gml(&neighbor_graph, net_file)) < 0) {
00379 perror("igraph_read_graph_gml");
00380 return err;
00381 }
00382 fclose(net_file);
00383 igraph_vit_create(&neighbor_graph, selector, &neighbors);
00384 }
00385 else {
00386 if (EuclideanNeighbors(network, datum->x, datum->y,
00387 static_cast<unsigned int> (ceil(radius)),
00388 &neighbor_graph) < 0) {
00389 fprintf(stderr, "EuclideanNeighbors call to R failed.\n");
00390 return -1;
00391 }
00392 igraph_vs_all(&selector);
00393 igraph_vit_create(&neighbor_graph, selector, &neighbors);
00394 }
00395
00396 for(; !IGRAPH_VIT_END(neighbors); IGRAPH_VIT_NEXT(neighbors)) {
00397 igraph_integer_t vertex = IGRAPH_VIT_GET(neighbors);
00398
00399 unsigned short node = (unsigned short)VAN(&neighbor_graph, "id", vertex);
00400 datum->source->toOutput(adc_data_file, datum->time, node,
00401 datum->strength, datum->x, datum->y,
00402 (int)VAN(&neighbor_graph, "x", vertex),
00403 (int)VAN(&neighbor_graph, "y", vertex));
00404 }
00405 igraph_vit_destroy(&neighbors);
00406 igraph_vs_destroy(&selector);
00407 }
00408 fclose(adc_data_file);
00409 fclose(tmp);
00410 unlink(temp_name);
00411 return 0;
00412 }
00413
00414
00415 int read_scenario(FILE *file, std::vector<SensorData> &data)
00416 {
00417 Phenom current = NONE;
00418 char* line = NULL;
00419 size_t unused;
00420 int len = 0;
00421 bool seen = false;
00422 SensorData *prev = NULL;
00423 unsigned int line_no = 0;
00424
00425 while((len = getline(&line, &unused, file)) > 0) {
00426 line_no++;
00427 if (len == 0)
00428 continue;
00429 if (line[0] == '#')
00430 continue;
00431
00432 for (Phenom i = Phenom_MIN; i < Phenom_MAX; ++i) {
00433 if (strncasecmp(line, phenoms[i], strlen(phenoms[i])) == 0) {
00434 current = i;
00435 seen = true;
00436 break;
00437 }
00438 }
00439 if (!seen) {
00440 std::cerr << "Malformed line #" << line_no << " : " << line;
00441 continue;
00442 }
00443
00444 prev = new SensorData(current, line, prev);
00445 data.push_back(*prev);
00446 }
00447 return 0;
00448 }
00449
00450
00451
00452 #ifdef ADC_STANDALONE
00453
00454 int main(int argc, char* argv[])
00455 {
00456 if (argc != 4) {
00457 std::cerr << "Usage: " << argv[0] << " <scenario file> <network file> "
00458 << "<adc file>" << std::endl;
00459 exit(-1);
00460 }
00461 if (compute_adc(argv[1], argv[2], argv[3]) < 0)
00462 exit(-1);
00463
00464 return 0;
00465 }
00466
00467 #endif