{"id":331,"date":"2021-06-04T18:28:00","date_gmt":"2021-06-04T17:28:00","guid":{"rendered":"https:\/\/blog.uclm.es\/felixvillanueva\/?p=331"},"modified":"2021-06-04T18:28:00","modified_gmt":"2021-06-04T17:28:00","slug":"simulando-consumo-y-recoleccion-de-energia-con-lorawan-en-ns3-y-iii","status":"publish","type":"post","link":"https:\/\/blog.uclm.es\/felixvillanueva\/2021\/06\/04\/simulando-consumo-y-recoleccion-de-energia-con-lorawan-en-ns3-y-iii\/","title":{"rendered":"Simulando consumo y recolecci\u00f3n de energ\u00eda con LoraWan en NS3 (y III)"},"content":{"rendered":"<p>Vamos a ver un ejemplo completo de simulaci\u00f3n de consumo y recolecci\u00f3n de energ\u00eda con LoraWan en NS3. La idea es simular un nodo LoraWan al cual le a\u00f1adiremos un m\u00f3dulo recolector de energ\u00eda (BasicEnergyHarvesterHelper). El ejemplo que usaremos en esta entrada se encuentra en <a href=\"https:\/\/bitbucket.org\/FelixVillanueva\/ns3.tutorial\/src\/master\/iot\/\">lorawan-energy.cc<\/a>. Haremos especial \u00e9nfasis en la parte de la energ\u00eda. No obstante, vamos a ir describiendo paso a paso, cada bloque en el ejemplo.<br \/>\nLo primero que tenemos es la creaci\u00f3n de los nodos. Crearemos un dispositivo final en LoraWan y una pasarela. El ejemplo est\u00e1 preparado para ampliar sus capacidades por lo que podr\u00edamos poner el n\u00famero de nodos finales que queramos como argumento. Tal y como vimos en la entrada <a href=\"https:\/\/blog.uclm.es\/felixvillanueva\/2021\/03\/11\/argumentos-de-entrada-en-simulaciones-de-ns3\/\">relativa a los argumentos de entrada<\/a>.<br \/>\nVolviendo a la creaci\u00f3n de nodos:<br \/>\n<code><br \/>\nNodeContainer endDevices;<br \/>\nendDevices.Create(numendDevices);<br \/>\nMobilityHelper scenario = createscenario(radio);<br \/>\nscenario.Install (endDevices);<br \/>\n\/\/put the hub in 0.0 0.0 0.0  center<br \/>\nNodeContainer hub;<br \/>\nhub.Create(1);<br \/>\nMobilityHelper hubposition = createstarcenter();<br \/>\nhubposition.Install (hub);<br \/>\n<\/code><br \/>\nSe crea un contenedor de nodos con numendDevices, por defecto igual a uno, y se posicionan con un radio igual a 20. Utilizamos para ello la funci\u00f3n createscenario. A continuaci\u00f3n creamos otro contenedor de nodos para los nodos que hacen las funciones de pasarela o gateway\/hub. En este caso, tambi\u00e9n uno, y lo posicionamos en el centro. La funci\u00f3n createstarcenter y la funci\u00f3n createscenario se encuentran al final del archivo. Ambas devuelven un MobilityHelper que, utilizando los contenedores, instalamos en los nodos finales endDevices y en los hub.<br \/>\nA continuaci\u00f3n debemos poner un interfaz LoraWan en cada dispositivo final y en cada Hub o pasarela.<br \/>\nPara ello, creamos un canal LoraWan de acuerdo a la documentaci\u00f3n del m\u00f3dulo:<br \/>\n<code><br \/>\nPtr &lt;logdistancepropagationlossmodel&gt; loss = CreateObject&lt;logdistancepropagationlossmodel&gt; ();<br \/>\nloss-&gt;SetPathLossExponent (3.76);<br \/>\nloss-&gt;SetReference (1, 7.7);<br \/>\nPtr&lt;propagationdelaymodel&gt; delay = CreateObject&lt;constantspeedpropagationdelaymodel&gt; ();<br \/>\nPtr&lt;lorachannel&gt; channel = CreateObject&lt;lorachannel&gt; (loss, delay);<br \/>\n<\/code><br \/>\nEstos par\u00e1metros de retardo y p\u00e9rdida simulan la propagaci\u00f3n de un canal usando la codificaci\u00f3n LoRa. Ahora hay que crear las interfaces Lora, conectadas al canal y las a\u00f1adiremos a los nodos ya creados. Primero la interfaz LoRa para los dispositivos finales usando los asistentes:<br \/>\n<code><br \/>\nLoraPhyHelper phyHelper = LoraPhyHelper ();<br \/>\nphyHelper.SetChannel (channel);<br \/>\nLorawanMacHelper macHelper = LorawanMacHelper ();<br \/>\nLoraHelper helper = LoraHelper ();<br \/>\nhelper.EnablePacketTracking();<br \/>\nphyHelper.SetDeviceType(LoraPhyHelper::ED);<br \/>\nmacHelper.SetDeviceType(LorawanMacHelper::ED_A);<br \/>\nNetDeviceContainer  endDevicesNetDevices = helper.Install(phyHelper, macHelper, endDevices);<br \/>\n<\/code><br \/>\nComo se puede observar, creamos la capa f\u00edsica y MAC, indic\u00e1ndole que es un dispositivo final mediante ED y ED_A respectivamente. Adicionalmente, hacemos lo mismo con la pasarela.<br \/>\n<code><br \/>\nLoraHelper helperHub = LoraHelper ();<br \/>\nphyHelper.SetDeviceType (LoraPhyHelper::GW);<br \/>\nmacHelper.SetDeviceType (LorawanMacHelper::GW);<br \/>\nhelperHub.Install (phyHelper, macHelper, hub);<br \/>\nmacHelper.SetSpreadingFactorsUp (endDevices, hub, channel);<br \/>\n<\/code><br \/>\nAhora indicando que es una pasarela.<br \/>\nBien, el siguiente paso es configurar una aplicaci\u00f3n, que instalaremos en los nodos finales y que mandar\u00e1 un paquete cada 5 segundos de un tama\u00f1o de 12 bytes:<br \/>\n<code><br \/>\nPeriodicSenderHelper periodicSenderHelper;<br \/>\nperiodicSenderHelper.SetPeriod (Seconds (5));<br \/>\nperiodicSenderHelper.SetPacketSize (12);<br \/>\nApplicationContainer appContainer = periodicSenderHelper.Install (endDevices);<br \/>\ndouble simulationTime = 3600;<br \/>\nTime appStopTime = Seconds (simulationTime);<br \/>\nappContainer.Start (Seconds (0));<br \/>\nappContainer.Stop (appStopTime);<br \/>\n<\/code><br \/>\nComo podemos ver,  configuramos el periodo y el tama\u00f1o de paquete para instalarlo en los dispositivos finales. A continuaci\u00f3n indicamos que inicie en el segundo 0 y termine a la hora de comienzo mediante una variable, appStopTime que utilizaremos para configurar la simulaci\u00f3n.<br \/>\nEl siguiente paso que vamos a\u00f1adir a nuestro dispositivo final es una fuente de energ\u00eda, una pila de 200 mAh y luego configuraremos el consumo de acuerdo a un circuito final. Primero la pila:<br \/>\n<code><br \/>\nBasicEnergySourceHelper basicSourceHelper;<br \/>\nLoraRadioEnergyModelHelper radioEnergyHelper;<\/code><\/p>\n<p><code><br \/>\n<\/code><code>\/\/ Bateria PD2032 200 mAh 3.7V<br \/>\nbasicSourceHelper.Set (\"BasicEnergySourceInitialEnergyJ\", DoubleValue (2664)); \/\/ Energy in J<br \/>\nbasicSourceHelper.Set (\"BasicEnergySupplyVoltageV\", DoubleValue (3.7));<br \/>\n<\/code><br \/>\nComo podemos ver, 2664 julios a 3.7 voltios.<br \/>\nEl consumo lo obtenemos de un modem semtech sx1276:<br \/>\n<code><br \/>\nradioEnergyHelper.Set (\"StandbyCurrentA\", DoubleValue (0.0016));<br \/>\nradioEnergyHelper.Set (\"TxCurrentA\", DoubleValue (0.120)); \/\/20 dbm<br \/>\nradioEnergyHelper.Set (\"SleepCurrentA\", DoubleValue (0.0000002));<br \/>\nradioEnergyHelper.Set (\"RxCurrentA\", DoubleValue (0.0115));<br \/>\nradioEnergyHelper.SetTxCurrentModel (\"ns3::ConstantLoraTxCurrentModel\",\"TxCurrent\", DoubleValue (0.12)); \/\/+20dbm<br \/>\nEnergySourceContainer sources = basicSourceHelper.Install (endDevices);<br \/>\nDeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install<br \/>\n(endDevicesNetDevices, sources);<br \/>\n<\/code><br \/>\nCon esta configuraci\u00f3n, nuestro dispositivo transmitir\u00eda hasta que terminara la simulaci\u00f3n o hasta que la bater\u00eda no suministrara suficiente energ\u00eda.<br \/>\nA\u00f1adimos un simulador de un recolector de energ\u00eda, que de forma peri\u00f3dica recolecta un valor aleatorio de energ\u00eda:<br \/>\n<code><br \/>\nBasicEnergyHarvesterHelper basicHarvesterHelper;<br \/>\nbasicHarvesterHelper.Set (\"PeriodicHarvestedPowerUpdateInterval\", TimeValue (Seconds (1.0)));<br \/>\nbasicHarvesterHelper.Set (\"HarvestablePower\", StringValue (\"ns3::UniformRandomVariable[Min=0.0|Max=0.009]\"));<br \/>\nEnergyHarvesterContainer harvesters = basicHarvesterHelper.Install (sources);<br \/>\n<\/code><br \/>\nPodemos ver, que se configura una recolecci\u00f3n peri\u00f3dica de un segundo con un valor aleatorio entre 0 y 0.09 julios.<br \/>\nFinalmente configuramos el navegador como en cualquier otra simulaci\u00f3n:<br \/>\n<code><br \/>\nSimulator::Stop (appStopTime);<br \/>\nSimulator::Run ();<br \/>\nSimulator::Destroy ();<br \/>\n<\/code><br \/>\nEl ejemplo tiene mas c\u00f3digo relacionado con extraer resultados por l\u00ednea de comando y por gnuplot, esta parte la veremos en otra entrada. Si ejecutamos el ejemplo, vemos que hay una serie de resultados relacionados con la energ\u00eda restante en la pila.<br \/>\n<code><br \/>\n$ .\/waf --run lorawan-energy<br \/>\n<\/code><br \/>\nUna vez ejecutada la simulaci\u00f3n, tenemos un archivo gnuplot-energy-example.sh que se ha generado junto con los datos de la simulaci\u00f3n, le damos permisos de ejecuci\u00f3n, lo ejecutamos y nos genera una gr\u00e1fica con la evoluci\u00f3n de la energ\u00eda restante en el nodo final durante la hora de simulaci\u00f3n:<br \/>\n<img decoding=\"async\" alt=\"Energ\u00eda restante con recolector de energ\u00eda\" src=\"https:\/\/blog.uclm.es\/felixvillanueva\/wp-content\/uploads\/sites\/81\/2021\/06\/gnuplot-energy-example.png\"><br \/>\nDonde podemos ver c\u00f3mo la recolecci\u00f3n de energ\u00eda mitiga el gasto energ\u00e9tico asociado al env\u00edo de paquetes. Si vemos c\u00f3mo ser\u00eda la gr\u00e1fica sin el recolector de energ\u00eda, basta con comentar esa parte, volver a simular y obtener la gr\u00e1fica:<\/p>\n<p><img decoding=\"async\" alt=\"Energ\u00eda restante con recolector de energ\u00eda\" src=\"https:\/\/blog.uclm.es\/felixvillanueva\/wp-content\/uploads\/sites\/81\/2021\/06\/noharvester.png\"><\/p>\n<p>Donde podemos ver c\u00f3mo la energ\u00eda restante no se repone en ning\u00fan momento.<br \/>\nEs una buena t\u00e9cnica jugar con los valores para observar su influencia en la energ\u00eda restante en la pila del dispositivo final.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vamos a ver un ejemplo completo de simulaci\u00f3n de consumo y recolecci\u00f3n de energ\u00eda con LoraWan en NS3. La idea es simular un nodo LoraWan al cual le a\u00f1adiremos un m\u00f3dulo recolector de energ\u00eda (BasicEnergyHarvesterHelper). El ejemplo que usaremos en &hellip; <a href=\"https:\/\/blog.uclm.es\/felixvillanueva\/2021\/06\/04\/simulando-consumo-y-recoleccion-de-energia-con-lorawan-en-ns3-y-iii\/\">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":[4,5,6],"tags":[23,29],"class_list":["post-331","post","type-post","status-publish","format-standard","hentry","category-ns3","category-simulacion","category-tutorial","tag-energia","tag-lorawan"],"_links":{"self":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts\/331","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=331"}],"version-history":[{"count":0,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/posts\/331\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/media?parent=331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/categories?post=331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.uclm.es\/felixvillanueva\/wp-json\/wp\/v2\/tags?post=331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}