{"id":125,"date":"2020-09-03T11:51:24","date_gmt":"2020-09-03T10:51:24","guid":{"rendered":"http:\/\/blog.uclm.es\/felixvillanueva\/?p=125"},"modified":"2020-09-03T11:51:24","modified_gmt":"2020-09-03T10:51:24","slug":"ejemplo-ns3-iot-y-sensores","status":"publish","type":"post","link":"https:\/\/blog.uclm.es\/felixvillanueva\/2020\/09\/03\/ejemplo-ns3-iot-y-sensores\/","title":{"rendered":"Ejemplo b\u00e1sico NS3: IoT y sensores"},"content":{"rendered":"<p>Como ya hemos comentado en las primeras secciones, hay numerosos ejemplos y test que te sirven de ayuda y como punto de partida, vamos a realizar un ejemplo b\u00e1sico intentando simular una red de sensores que mandan informaci\u00f3n a una pasarela (Gateway) o nodo central. El objetivo de este ejemplo es ir complet\u00e1ndolo con otras funciones muy necesarias en simulaci\u00f3n (Log, trazas, configuraci\u00f3n, varias tecnolog\u00edas, energ\u00eda, etc.) en entradas posteriores. En <a href=\"https:\/\/bitbucket.org\/FelixVillanueva\/ns3.tutorial\/src\/master\/iot\/\"> el repositorio del tutorial<\/a>, el archivo de inicio es basic-iot-sensors.cc.<br \/>\nLo primero que vamos a realizar es crear 3 nodos (variable numsensors) y posicionarlos en un punto determinado (aleatorio). Utilizamos una funci\u00f3n que crea un escenario con un radio (variable radio) determinado en metros y, a continuaci\u00f3n, le pasamos el contenedor de nuestros nodos para que posicione, de forma aleatoria, dichos nodos;<br \/>\n<code><br \/>\nNodeContainer nodes;<br \/>\nnodes.Create(numsensors);<br \/>\nMobilityHelper scenario = createscenario(radio);<br \/>\nscenario.Install (nodes);<br \/>\n<\/code><br \/>\nComo ya indicamos en la <a href=\"https:\/\/blog.uclm.es\/felixvillanueva\/2020\/06\/23\/topologia-ejemplos-ns3\/\"> entrada de topolog\u00eda <\/a>, se crea un escenario mediante el MobilityHelper con la configuraci\u00f3n deseada:<br \/>\n<code><br \/>\nMobilityHelper createscenario(double radio)<br \/>\n{<br \/>\nMobilityHelper mobility;<br \/>\nmobility.SetPositionAllocator (\"ns3::UniformDiscPositionAllocator\",<br \/>\n\"rho\", DoubleValue (radio),<br \/>\n\"X\", DoubleValue (0.0),<br \/>\n\"Y\", DoubleValue (0.0),<br \/>\n\"Z\", DoubleValue (0.0));<\/code><\/p>\n<p><code>    mobility.SetMobilityModel (\"ns3::ConstantPositionMobilityModel\");<br \/>\nreturn mobility;<br \/>\n}<\/code><\/p>\n<p><code><br \/>\n<\/code><code><\/code><code><\/code><br \/>\nDel contenedor de nodos, creamos un centro de la estrella donde posicionaremos el primer nodo, que de ahora en adelante representar\u00e1 la pasarela:<br \/>\n<code><br \/>\nMobilityHelper gatewayposition = createstarcenter();<br \/>\ngatewayposition.Install (nodes.Get(0));<br \/>\n<\/code><\/p>\n<p>Una vez creados los dispositivos y emplazados (la pasarela en la posici\u00f3n x,y,z a 0,0,0 y el resto de forma aleatoria), vamos a seguir configurando nuestros nodos, configurando una interfaz wifi en cada uno de los nodos. La tecnolog\u00eda inal\u00e1mbrica WIFI est\u00e1 de sobra probada en NS3 y nos sirve de punto de partida para nuestro ejemplo.<br \/>\nPara la creaci\u00f3n de NetDevice por cada Nodo e instalarlo en cada uno de los nodos, usaremos los asistentes, nos crearemos un asistente para la capa f\u00edsica (wifiPhy), la capa Mac (wifiMac) y el objeto que modela el canal inal\u00e1mbrico (wifiChannel) y al cual deberemos conectar todos los objetos que modelan la capa f\u00edsica.<br \/>\n<code><br \/>\nWifiHelper wifi;<br \/>\nYansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();<br \/>\nYansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();<br \/>\nWifiMacHelper wifiMac;<br \/>\nwifiMac.SetType (\"ns3::AdhocWifiMac\");<br \/>\nwifiPhy.SetChannel(wifiChannel.Create());<br \/>\nNetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, nodes);<br \/>\n<\/code><br \/>\nEn este caso para el modelado de la capa f\u00edsica y el canal utilizamos el modelo Yans. Es el modelo por defecto que se utiliza pero, obviamente, el <a href=\"https:\/\/www.nsnam.org\/docs\/models\/html\/wifi.html\"> El m\u00f3dulo wifi<\/a> es uno de los m\u00e1s completos y estudiados <a href=\"https:\/\/www.nsnam.org\/doxygen\/group__wifi.html\">con varios modelos disponibles<\/a>.<br \/>\nEl tipo de MAC es ns3::AdhocWifiMac que modela relaciones punto a punto entre dos dispositivos con Wifi. A continuaci\u00f3n establecemos el canal en el asistente wifiPhy para que todos los objetos creados de la capa f\u00edsica compartan el canal y se puedan comunicar entre ellos. Estas configuraciones, en la parte wifi, son las configuraciones por defecto. Por \u00faltimo, instalamos usando el asistente general del wifi la capa f\u00edsica y la MAC en todos los nodos. El asistente de wifi nos devuelve un contenedor con los NetDevices creados (y asociados a los nodos):<br \/>\n<code><br \/>\nNetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, nodes);<br \/>\n<\/code><\/p>\n<p>Hemos usado la configuraci\u00f3n por defecto, este es uno de los puntos m\u00e1s importantes en cuanto a una simulaci\u00f3n, tienes que definir claramente las m\u00e9tricas en las cuales est\u00e1s interesados y modelar de forma simple el resto de elementos. Por ejemplo, si est\u00e1s interesado en un protocolo de comunicaciones de la capa de aplicaci\u00f3n y quieres validar su funcionalidad, la capa f\u00edsica\/MAC que utilices debe ser modelada de la forma m\u00e1s simple posible.<\/p>\n<p>Si por contra, est\u00e1s interesado en modelar un nuevo algoritmo de control de flujo de 802.11ax, es la capa de aplicaci\u00f3n la que debe modelar lo m\u00ednimo para generar el tr\u00e1fico necesario para probar la funcionalidad.<\/p>\n<p>Hasta aqu\u00ed hemos creado el \u00abHardware\u00bb de nuestra simulaci\u00f3n, vamos a instalar y configurar el resto de elementos.<\/p>\n<p>Pasemos a la parte de configuraci\u00f3n de la pila de protocolos, en este caso vamos a instalar y configurar una pila de protocolos TCP\/IP, para ello creamos un asistente y lo instalamos en todos los nodos:<br \/>\n<code><br \/>\nInternetStackHelper internet;<br \/>\ninternet.Install (nodes);<br \/>\n<\/code><br \/>\nUna vez instalada, configuramos la direcci\u00f3n de red y le asignamos direcciones IP a las interfaces de red instaladas en los nodos:<br \/>\n<code><br \/>\nIpv4AddressHelper ipv4;<br \/>\nipv4.SetBase (\"10.1.1.0\", \"255.255.255.0\");<br \/>\nIpv4InterfaceContainer i = ipv4.Assign (devices);<br \/>\n<\/code><br \/>\nen este caso, usamos la direcci\u00f3n de red 10.1.1.0 con m\u00e1scara 255.255.255.0 y se les asigna, de forma consecutiva, a cada uno de los NetDevices en el container \u00abdevices\u00bb creando un contenedor de interfaces ya configuradas.<\/p>\n<p>El \u00faltimo paso de creaci\u00f3n de nuestro escenario propiamente dicho es la creaci\u00f3n de aplicaciones que creen tr\u00e1fico. Vamos a instalar un servidor UDP en la pasarela (nodo 0) y lo configuramos para que escuche en el puerto 2000 :<br \/>\n<code><br \/>\nuint16_t port = 2000;<br \/>\nUdpServerHelper server(port);<br \/>\nApplicationContainer gatewayapps = server.Install(nodes.Get(0));<br \/>\ngatewayapps.Start(Seconds(1.0));<br \/>\ngatewayapps.Stop(Seconds(11.0));<br \/>\n<\/code><br \/>\nComo vemos en el c\u00f3digo de arriba, creamos un asistente de servidor en el puerto deseado y lo instalamos en el nodo 0. Por \u00faltimo indicamos los momentos en que arrancamos y paramos el servidor en este caso sobre el contenedor que se ha creado. Un paso similar hay que hacer en los clientes, debemos crear clientes software configurados para enviar una cantidad de tr\u00e1fico al servidor que acabamos de instalar en el todo 0 (y que obtenemos con nodes.Get(0)).<br \/>\nObtenemos la direcci\u00f3n IP del servidor (la 0) del contenedor de interfaces, establecemos el tama\u00f1o en 32 bytes, que para la informaci\u00f3n generada por un sensor es suficiente. En principio generaremos como mucho 10 paquetes:<br \/>\n<code><br \/>\nAddress gatewayAddress = Address(i.GetAddress (0));<br \/>\nuint32_t packetSize = 32;<br \/>\nuint32_t maxPacketCount = 10;<br \/>\n<\/code><br \/>\nCon esta configuraci\u00f3n, se crea un asistente de cliente, se establece el intervalo de env\u00edo y se configura el cliente:<br \/>\n<code><br \/>\nUdpClientHelper client (gatewayAddress, port);<br \/>\nTime interPacketInterval = Seconds (0.5);<br \/>\nclient.SetAttribute(\"PacketSize\", UintegerValue(packetSize));<br \/>\nclient.SetAttribute (\"Interval\", TimeValue (interPacketInterval));<br \/>\nclient.SetAttribute (\"MaxPackets\",  UintegerValue(maxPacketCount));<br \/>\n<\/code><br \/>\nHay que resaltar c\u00f3mo se configura, mediante el m\u00e9todo SetAttribute, cada una de las caracter\u00edsticas, indicando su nombre y valor, este mecanismo es muy utilizado por los objetos NS3 para la configuraci\u00f3n de par\u00e1metros.<br \/>\nPor \u00faltimo, instalamos en los nodos un cliente (incluyendo la pasarela que actuar\u00e1 como sensor\/servidor) cre\u00e1ndose otro contenedor de aplicaciones que debemos arrancar y parar. Hay que asegurarse que el servidor est\u00e9 arrancado antes que los clientes, por eso arrancamos en el segundo 2 y paramos mas tarde para no perder informaci\u00f3n.<br \/>\n<code><br \/>\nApplicationContainer apps = client.Install(nodes);<br \/>\napps.Start(Seconds(2.0));<br \/>\napps.Stop(Seconds(10.0));<br \/>\n<\/code><br \/>\nPor \u00faltimo, arrancamos el simulador:<br \/>\n<code><\/code><br \/>\nSimulator::Stop (Hours (24));<br \/>\nSimulator::Run ();<br \/>\nSimulator::Destroy ();<br \/>\n<code><br \/>\nLos detalles del simulador lo veremos en otra entrada. <\/code><\/p>\n<p>Con esto terminamos nuestra simulaci\u00f3n, colocando el archivo en el directorio scratch lo ejecutamos:<br \/>\n<code><br \/>\n\/ns-3.30.1$ .\/waf --run basic-iot-sensors<br \/>\nWaf: Entering directory `ns-allinone-3.30.1\/ns-3.30.1\/build'<br \/>\nWaf: Leaving directory `\/ns-allinone-3.30.1\/ns-3.30.1\/build'<br \/>\nBuild commands will be stored in build\/compile_commands.json<br \/>\n'build' finished successfully (1.747s)<br \/>\n<\/code><\/p>\n<p>Que compila y ejecuta nuestra simulaci\u00f3n. Realmente no vemos ning\u00fan flujo de informaci\u00f3n por lo que no sabemos si todo ha ido bien, en pr\u00f3ximas entradas veremos c\u00f3mo obtener informaci\u00f3n, mediante log y trazas, de qu\u00e9 est\u00e1 pasando en nuestra simulaci\u00f3n.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como ya hemos comentado en las primeras secciones, hay numerosos ejemplos y test que te sirven de ayuda y como punto de partida, vamos a realizar un ejemplo b\u00e1sico intentando simular una red de sensores que mandan informaci\u00f3n a una &hellip; <a href=\"https:\/\/blog.uclm.es\/felixvillanueva\/2020\/09\/03\/ejemplo-ns3-iot-y-sensores\/\">Sigue leyendo <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":182,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,4,5],"tags":[26],"class_list":["post-125","post","type-post","status-publish","format-standard","hentry","category-ejemplos","category-ns3","category-simulacion","tag-iot"],"_links":{"self":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts\/125","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/users\/182"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/comments?post=125"}],"version-history":[{"count":0,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts\/125\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/media?parent=125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/categories?post=125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/tags?post=125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}