{"id":7732,"date":"2023-09-25T20:20:35","date_gmt":"2023-09-25T19:20:35","guid":{"rendered":"https:\/\/dronesonen.usn.no\/?p=7732"},"modified":"2023-09-25T20:20:35","modified_gmt":"2023-09-25T19:20:35","slug":"turret-syndrome-week-5","status":"publish","type":"post","link":"https:\/\/dronesonen.usn.no\/?p=7732","title":{"rendered":"Turret Syndrome &#8211; Week 5"},"content":{"rendered":"\n<p>Here is our teams contributions for our project this week in sprint 5! Things are starting to ramp up!<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Harald Berzinis<\/h2>\n\n\n\n<p>Harald Berzinis<\/p>\n\n\n\n<p>This week I have been reiterating the original model, 3D-printing the trigger mechanism and further testing it.\u00a0\u00a0<\/p>\n\n\n\n<p>Initial CAD-design:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><img loading=\"lazy\" decoding=\"async\" width=\"573\" height=\"344\" src=\"https:\/\/lh4.googleusercontent.com\/p3JKVDcPX8ncp5xve8i3lbHIvpKjsTcQCDKn44U_WMc3loiZeZ6nt-hYf90UJkD8ANZ4AwC4yIAMJFGpyFb82war7_OZxhW5Rp2S-cZ7jhY-tUS4pi-tTQ0wMzTka9n2_wgGw84b255dJVBBdH7Xkgo\"><\/h2>\n\n\n\n<p>Main Enclosure:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/FKwGmud4lX68oxilO94TjJaBZ-BLk-9oJH7ES12O67wontXf4vuPI-bTslP11lx1QkWcOUPLsfEcBV9_oIaSzbKx6zDmTS7xKhHthw_OWXK3ZfA9TfCcJNfhWUaK0GesBWe6NHdHCm1dw4fJMItj7Mc\" alt=\"\" \/><\/figure>\n\n\n\n<p>The main enclosure that holds everything together, 3cm x 5cm x 11cm<\/p>\n\n\n\n<p>Bolt:<br><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/NSfHlngkIe43kUW1lLhK5sN0kzkP_JN5s7V-mj-_wm5nOrbL1qg0xM0eGlpZVyfj3yZnocPtgJVKMhJBulPFkeDQJpNqtEJEnCazqKxCIBnApvrSrd3IqswH0Qg-40m3MZC--bHbKlhpVF9c4ESz7-M\" width=\"624\" height=\"397\"><\/p>\n\n\n\n<p>The main bolt that activates when the servo mechanism is initiated, converting from rotational to linear actuation for the trigger. This bolt is then suspended with a rubber band to the main enclosure.&nbsp;<\/p>\n\n\n\n<p>Servo bolt:<br><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/2M55DWJJvwrY4PV3eQCh_nd1B15IWsi2k3efVjgkuaU4em1NdHJHTJRNpm1uNnKESMk7NnZh6C0sUjGYaGdlw0zH3wu8fTQwZXCeM1CTNivR8mGlahl6VSHvY5KeUOfOoa5VUIvqtsDEuMGQZp96ekU\" width=\"624\" height=\"161\"><\/p>\n\n\n\n<p>This servo bolt gets directly mounted on the 20 tooth spur gear and the stopping component for the main bolt, this of course gets placed through the main enclosure, then glued and assembled with the other parts.<\/p>\n\n\n\n<p>Stopping component for the main bolt:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/FnaCdxolLyHZcHzhnkm2hn_Q0oDeyZZmj-Qfme9w82frOUnhxWnq1sLwiPjx_ivH3v7uOZKRLma9YRANkyMQAz2VmbMlmYbhdT54xu13zHAbpL93z0swTm9v4ngo0t2wMnKCTc8WGFXMy3s-QZXtcbs\" alt=\"\" \/><\/figure>\n\n\n\n<p>This component is responsible for holding the main bolt at the suspended state. When the servo is initiated, this component rotates to the left and releases the suspended bolt hitting the trigger.<\/p>\n\n\n\n<p>Trigger bolt<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/ambpc_VIlq5LNMNIahb3607gafKZq3fYnUPEFwB-3Ihh7Hg_Lj6TUt1BW0kcGt8tuDDAiNb6jkhnuQYVsaYWsLBgbOO4MMndT8vU8YMm65d5I-Gj6t-364AQtjsfTM_Io-IdDch1BSMVJB7duUShRLs\" alt=\"\" \/><\/figure>\n\n\n\n<p>This is an extension for the main bolt so it hits the trigger.<\/p>\n\n\n\n<p>20 and 10 tooth gears:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/rQpiHfskZtoL3iBBeI9UBf64YqTQZP9O-QnBL4tJdYq_IDAT_4qAMWMWzkImKVaWVAkGcEOUXWBKGbso9iosS-7UjaMGKYj6e9wYoKt9ZTt5dBRE9uv8QeTdySjiXOdPuYyufOaZlywU_aJxbd5iYDA\" alt=\"\" \/><\/figure>\n\n\n\n<p>These are the 20 and 10 tooth spur gears, which makes a ratio of 2:1. These gears were reiterated due to when 3D-printing I experienced that the gears that I made were not high enough resolution, therefore I stepped down the number of teeth on each gear. These were printed at 70% infill to make sure that they do not break under load.<\/p>\n\n\n\n<p>Assembly and testing:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/7SSUDyfwyvdfRiQExZnHOTd625qXvQUMofdX7RjlYWi-2Aawl-I21Uow6Cq25J-MlEVLH4D7_nES3EzV1hppw0ppNVYicoQxehoiWXlcCeSKUTCafj2DgD5k8n5Nl_gP-GYCWsS39dtLOMiRl9_UFTo\" alt=\"\" \/><\/figure>\n\n\n\n<p>Fully assembled trigger mechanism. In addition, we have tested it and the mechanism activates the paintball gun&#8217;s trigger. Further testing proved that the mechanism experiences tear at the main bolt and that it needs to be printed at a higher level of infill.<\/p>\n\n\n\n<p>Next week:<\/p>\n\n\n\n<p>The plan for me next week is to make a version of this that is mounted on the buttstock of the paintball gun, this is because we have a lot of unused space. I will then reiterate this mechanism to a more beefier version to withstand the rubber band force and further improve the stability and safety for the shooting mechanism.<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Mats Bergum<\/h2>\n\n\n\n<p>Most of my time was spent watching and following this tutorial. (<a href=\"https:\/\/www.youtube.com\/watch?v=d_TPIxPX01s&amp;ab_channel=RobertFeranec\">https:\/\/www.youtube.com\/watch?v=d_TPIxPX01s&amp;ab_channel=RobertFeranec<\/a>) from Robert Feranec. Following this tutorial taught me how to make footprints and 3D models and assign them to the correct components. I also learned how to set up PCB stackup in Allegro and route the PCB in Allegro. Moreover, the tutorial also showed me how to import changes in the schematic to the existing PCB design, which can be helpful when producing my own PCB.<\/p>\n\n\n\n<p>The PCB I made following this tutorial can be found below. This was done by copying what was done in the tutorial, but it was a good learning experience.<\/p>\n\n\n\n<p>3D view of the board:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/_owCImWdo8aKrFPmNCXSrboDSqZFdEhD86Abz-vmcnrMCVfeMTM8iyyOTxL6I7B1dVZW1NGuCY7DLHR7doo3PvxBBaiCV5BItXrZG_WMR8WxCi-21lqDQh-pgAraRqhikHCy4K5b2iZGpyBrC2jD_XY\" alt=\"\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/hL2Fbth5rBeHJZaUAW_pp9XuJFUBT_FIeKOKKmxgf_vrDsvctaRpL2QD3VGpObdZJeviThuQiAC9oUu60EiX7E_Qv5Q5k2rNGkwiT7i0rgk8VmUZp8kOLn-A0PTtGuo-Q64bVOt2pBP_TeHesjiAX8o\" alt=\"\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/dgh0LW7H9w1Outm6TPh4Fyb6m40kKW2Z0JZm6kzpI2QjHYR9ABDIo0v7tiXcppWNHRnpr2YqcMV9D5gVRiLAVOOHfJnbkbLS9Z_qNXZBdVVZ-ia5mSzIC8ygeakc7vvG_Oc6e-NiafP0z7vX8v8N-R4\" alt=\"\" \/><\/figure>\n\n\n\n<p>Routing:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/QPbCcJl6-VUseAUMcOWa3wbiD7BPWKw5ORMDt3QH10LYzHxjP6vEm11k8CyH9v4lzn7U-KlHUyDI4cetnlkdCt1w0funmlr9s0kwxXs1kYJUhbVyj_urLyxUssPYoWJheGXFrh-RY7nUG_Xm0lmIo3I\" alt=\"\" \/><\/figure>\n\n\n\n<p>I tried to make the PCB design for our circuit, but I could not do this due to some console errors that I could not fix. Thus, I only made some footprints and 3D models for curtain components. Next week, I need to try fixing those errors and start with the routing.<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Christopher Daffinrud<\/h2>\n\n\n\n<p>After severe testing using the Pi for object detection calculations, and using probably one of the most efficient models in EfficientDet we concluded in the beginning of week 5 that we would like to separate the object and color recognition calculations on an external device communicating with the Raspberry Pi over UDP.&nbsp;<\/p>\n\n\n\n<p>Our new intention is setting up a local network on the Raspberry Pi allowing for UDP-communication between the Pi and an external computer with a socket. The camera feed captures from the Raspberry Pi\u00b4s web camera shall then be transferred to the external computer for computations. The external computer will then return the relevant data and coordinates needed for the Turret System to perform its actions depending on the calculations.<\/p>\n\n\n\n<p>I iterated on my previous class diagram, now facilitating this change.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/QdUgq9clCJnzy6nbSKElBRLv-P7Ktbh-Ee-javtGpoyJv3Ea79ehXYfQtsM57WwZuXjiC6xRm_P6bKMawwZjVMaSe88_gpVRXhZQko3g15Uc3jEk0FZqFUfnDR2dAiZeanBtWb2ylGoflIFhD5IEUm0\" alt=\"\" \/><\/figure>\n\n\n\n<p>As you can see from the model the Turret and the external computer are connected through the class \u201ccommInterface\u201d.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>UDPSocket for transferring camera frames from Pi to external computer<\/li>\n\n\n\n<li>TCPSocket for transferring object coordinates and relevant data from external computer to Pi<\/li>\n<\/ul>\n\n\n\n<p>I also created a simple high-level component diagram of our system, including the component needing 5V or 12V.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/ccRUfaGmN-Cjb-hRex-I4k0TNyJACtbRMEBmsfkhrlisIZ5cTdfF8t5hRoxwsf1gR7r_jctt0dYZUvaHQd09jg48ahDbIYClQ-dmaHPR3Z7NBMW4cxN57SO45lC8msmqIIquwXLOesrGHSIEbNxM2yk\" alt=\"\" \/><\/figure>\n\n\n\n<p>The 3.3V to 5V represents the converter circuit which Harald and Mats are developing.<\/p>\n\n\n\n<p>All nodes with 5V and 12V are additional voltage requirements needed that will be fulfilled by creating a PCB.<\/p>\n\n\n\n<p>The network communication channel in this model is the Local Wifi-network supplied either by the Raspberry Pi or the external computer with communication through sockets.&nbsp;<\/p>\n\n\n\n<p>These diagrams allowed further specification of tasks needed to be done through Azure Devops.&nbsp;<\/p>\n\n\n\n<p>Hopefully we will be able to start implementing some software solutions during this week. That will also be the main focus for software next week.<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Ole Eirik S.Seljordslia<\/h2>\n\n\n\n<p>In response to the computational limitations we encountered with the Raspberry Pi last week, we took a step back to explore alternative solutions. One of the promising ideas that emerged was the concept of streaming video from the Raspberry Pi to an external computer. This approach would leverage the secondary computer&#8217;s superior processing power to handle computationally intensive tasks.<\/p>\n\n\n\n<p>In this envisioned setup, the external computer would receive the video feed from the Raspberry Pi, process it, and return coordinates corresponding to any detected balloons within the video stream. An advantage of this arrangement is its versatility; it allows us to conveniently test the system using a regular laptop, we could also switch out the laptop at a later time.<\/p>\n\n\n\n<p>To realize communication between the turret and the image processor, we needed a interface capable of efficiently sending and receiving frames. In practice, the external computer would act as a server hosting a socket connection through UDP, enabling the Raspberry Pi mounted on the turret to send images and receive balloon coordinates in response. These coordinates represent the predictions made by our object detection model regarding balloon locations.<\/p>\n\n\n\n<p>During the past week, I dedicated my efforts to implementing and testing this interface between the two computers.<\/p>\n\n\n\n<p>Our project consists of two distinct code bases: one for the turret and another for the image processor. Given that the turret&#8217;s role is to transmit frames to the image processor, I developed communication classes to interface the two systems. The following snippet is the turret&#8217;s method for sending frames: <\/p>\n\n\n\n<h3 class=\"has-text-align-center wp-block-heading\">Transmitting frames<\/h3>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #202020;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em\"><table><tr><td><pre style=\"margin: 0;line-height: 125%\"> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26<\/pre><\/td><td><pre style=\"margin: 0;line-height: 125%\"><span style=\"color: #6ab825;font-weight: bold\">def<\/span> <span style=\"color: #447fcf\">send_frame<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #d0d0d0\">frame:<\/span> <span style=\"color: #d0d0d0\">cv2.typing.MatLike)-&gt;<\/span><span style=\"color: #24909d\">None<\/span><span style=\"color: #d0d0d0\">:<\/span>\n        <span style=\"color: #ed9d13\">&quot;&quot;&quot;_summary_<\/span>\n<span style=\"color: #ed9d13\">        Send individual frames<\/span>\n<span style=\"color: #ed9d13\">        Args:<\/span>\n<span style=\"color: #ed9d13\">            frame (cv2.typing.MatLike): Frame from video stream<\/span>\n<span style=\"color: #ed9d13\">        Raises:<\/span>\n<span style=\"color: #ed9d13\">            Exception: Unable to encode frame<\/span>\n<span style=\"color: #ed9d13\">        &quot;&quot;&quot;<\/span>\n        <span style=\"color: #d0d0d0\">return_value,<\/span> <span style=\"color: #d0d0d0\">image_buffer<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">cv2.imencode(<\/span><span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__image_format,<\/span> <span style=\"color: #d0d0d0\">frame)<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #6ab825;font-weight: bold\">not<\/span> <span style=\"color: #d0d0d0\">return_value:<\/span> <span style=\"color: #6ab825;font-weight: bold\">raise<\/span> <span style=\"color: #bbbbbb\">Exception<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #ed9d13\">&#039;Unable to encode frame&#039;<\/span><span style=\"color: #d0d0d0\">)<\/span>\n        <span style=\"color: #d0d0d0\">image_buffer<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">image_buffer.tobytes()<\/span>\n        <span style=\"color: #d0d0d0\">number_of_packets<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">1<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #24909d\">len<\/span><span style=\"color: #d0d0d0\">(image_buffer)<\/span> <span style=\"color: #d0d0d0\">&gt;<\/span> <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__max_buffer_size:<\/span>\n            <span style=\"color: #d0d0d0\">number_of_packets<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">int<\/span><span style=\"color: #d0d0d0\">(np.ceil(<\/span><span style=\"color: #24909d\">len<\/span><span style=\"color: #d0d0d0\">(image_buffer)\/<\/span><span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__max_buffer_size))<\/span>\n       \n        <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__socket.sendto(pickle.dumps({<\/span><span style=\"color: #ed9d13\">&#039;packets&#039;<\/span><span style=\"color: #d0d0d0\">:number_of_packets}),<\/span>\n                            <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__server)<\/span>\n        <span style=\"color: #d0d0d0\">left<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span>\n        <span style=\"color: #d0d0d0\">right<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__max_buffer_size<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">for<\/span> <span style=\"color: #d0d0d0\">packet_index<\/span> <span style=\"color: #6ab825;font-weight: bold\">in<\/span> <span style=\"color: #24909d\">range<\/span><span style=\"color: #d0d0d0\">(number_of_packets):<\/span>\n            <span style=\"color: #d0d0d0\">payload<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">image_buffer[left:right]<\/span>\n            <span style=\"color: #d0d0d0\">left<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">right<\/span>\n            <span style=\"color: #d0d0d0\">right<\/span> <span style=\"color: #d0d0d0\">+=<\/span> <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__max_buffer_size<\/span>\n            <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__socket.sendto(payload,<\/span> <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__server)<\/span>  \n<\/pre><\/td><\/tr><\/table><\/div>\n\n\n\n<p>This &#8216;send_frame&#8217; method anticipates a &#8216;cv2.typing.MatLike&#8217; input, which aligns with the output of &#8216;cv2.VideoCapture()&#8217;. It encodes the frame to a buffer using the &#8216;.jpg&#8217; format. If the encoding is successful, it converts the buffer to bytes and determines the number of packets required based on the byte conversion. The number of packets is then sent as the first packet to the image processor, serving as an indicator of the frame&#8217;s completeness. This packet is serialized through the `pickle.dumps` function. Subsequently, segments of the image buffer are dispatched to the image processor, respecting the maximum packet size, which should be predefined and agreed upon by both the turret and image processor. The maximum packet size is determined by each computer UDP MTU, this can vary based on hardware and operating system compositions.&nbsp;<\/p>\n\n\n\n<p>The image processor, in turn, implements a complementary method to receive frames:<\/p>\n\n\n\n<h3 class=\"has-text-align-center wp-block-heading\">Receiving frames<\/h3>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #202020;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em\"><table><tr><td><pre style=\"margin: 0;line-height: 125%\"> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40<\/pre><\/td><td><pre style=\"margin: 0;line-height: 125%\"><span style=\"color: #6ab825;font-weight: bold\">def<\/span> <span style=\"color: #447fcf\">receive_frame<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">)-&gt;np.ndarray:<\/span>\n        <span style=\"color: #ed9d13\">&quot;&quot;&quot;Will return next frame from a video stream<\/span>\n<span style=\"color: #ed9d13\">        Returns:<\/span>\n<span style=\"color: #ed9d13\">            Array of pixels<\/span>\n<span style=\"color: #ed9d13\">        &quot;&quot;&quot;<\/span>\n        <span style=\"color: #24909d\">buffer<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #d0d0d0\">address<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__socket.recvfrom(<\/span><span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__max_buffer_size)<\/span>\n        <span style=\"color: #999999;font-style: italic\"># try:<\/span>\n        <span style=\"color: #999999;font-style: italic\">#     frame_info = pickle.loads(buffer)<\/span>\n        <span style=\"color: #999999;font-style: italic\"># except:<\/span>\n        <span style=\"color: #999999;font-style: italic\">#     print(&#039;Missed frame information&#039;)<\/span>\n        <span style=\"color: #999999;font-style: italic\">#     return None<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #24909d\">len<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #24909d\">buffer<\/span><span style=\"color: #d0d0d0\">)<\/span> <span style=\"color: #d0d0d0\">&gt;<\/span> <span style=\"color: #3677a9\">500<\/span><span style=\"color: #d0d0d0\">:<\/span> <span style=\"color: #6ab825;font-weight: bold\">return<\/span> <span style=\"color: #24909d\">None<\/span>\n        <span style=\"color: #d0d0d0\">frame_info<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">pickle.loads(<\/span><span style=\"color: #24909d\">buffer<\/span><span style=\"color: #d0d0d0\">)<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #d0d0d0\">frame_info:<\/span>\n            <span style=\"color: #d0d0d0\">number_of_packets<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">frame_info[<\/span><span style=\"color: #ed9d13\">&#039;packets&#039;<\/span><span style=\"color: #d0d0d0\">]<\/span>\n            <span style=\"color: #d0d0d0\">packets<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">bytes<\/span><span style=\"color: #d0d0d0\">()<\/span>\n           \n            <span style=\"color: #6ab825;font-weight: bold\">for<\/span> <span style=\"color: #d0d0d0\">packet_index<\/span> <span style=\"color: #6ab825;font-weight: bold\">in<\/span> <span style=\"color: #24909d\">range<\/span><span style=\"color: #d0d0d0\">(number_of_packets):<\/span>\n                <span style=\"color: #d0d0d0\">payload,<\/span> <span style=\"color: #d0d0d0\">_<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__socket.recvfrom(<\/span><span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__max_buffer_size)<\/span>\n                <span style=\"color: #d0d0d0\">packets<\/span> <span style=\"color: #d0d0d0\">+=<\/span> <span style=\"color: #d0d0d0\">payload<\/span>\n            <span style=\"color: #6ab825;font-weight: bold\">return<\/span> <span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">.__process_frames(packets)<\/span>\n       \n    <span style=\"color: #6ab825;font-weight: bold\">def<\/span> <span style=\"color: #447fcf\">__process_frames<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #24909d\">self<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #24909d\">buffer<\/span><span style=\"color: #d0d0d0\">)-&gt;np.ndarray:<\/span>\n        <span style=\"color: #ed9d13\">&quot;&quot;&quot;Transform frame.<\/span>\n<span style=\"color: #ed9d13\">        Args:<\/span>\n<span style=\"color: #ed9d13\">            buffer: Incoming buffer representing a frame from video stream.<\/span>\n<span style=\"color: #ed9d13\">        Returns:<\/span>\n<span style=\"color: #ed9d13\">            Transformed buffer of frame<\/span>\n<span style=\"color: #ed9d13\">        &quot;&quot;&quot;<\/span>\n        <span style=\"color: #d0d0d0\">frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">np.frombuffer(<\/span><span style=\"color: #24909d\">buffer<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #d0d0d0\">dtype=np.uint8)<\/span>\n        <span style=\"color: #d0d0d0\">frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">frame.reshape(frame.shape[<\/span><span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">],<\/span> <span style=\"color: #3677a9\">1<\/span><span style=\"color: #d0d0d0\">)<\/span>\n        <span style=\"color: #d0d0d0\">frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">cv2.imdecode(frame,<\/span> <span style=\"color: #d0d0d0\">cv2.IMREAD_COLOR)<\/span>\n        <span style=\"color: #d0d0d0\">frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">cv2.flip(frame,<\/span> <span style=\"color: #3677a9\">1<\/span><span style=\"color: #d0d0d0\">)<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">return<\/span> <span style=\"color: #d0d0d0\">frame<\/span>\n<\/pre><\/td><\/tr><\/table><\/div>\n\n\n\n<p>The &#8216;receive_frame&#8217; method begins by receiving a buffer from the turret. It extracts frame information from the first packet, particularly the number of packets to expect. To address potential challenges like missing initial packets, we employ a size threshold to distinguish between the initial information packet and subsequent data packets. This could have also been handled by trying to process the packet and possibly catching an exception. I opted from this as I expect it to be a more time consuming solution opposed to checking the length.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Following this, each packet is collected into a byte array before being processed by the internal `__process_frames` method, which ultimately returns a NumPy array suitable for object detection.<\/p>\n\n\n\n<p>I created two examples to put these methods to the test.<\/p>\n\n\n\n<h3 class=\"has-text-align-center wp-block-heading\">Image processor example<\/h3>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #202020;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em\"><table><tr><td><pre style=\"margin: 0;line-height: 125%\"> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29<\/pre><\/td><td><pre style=\"margin: 0;line-height: 125%\"><span style=\"color: #6ab825;font-weight: bold\">from<\/span> <span style=\"color: #447fcf;text-decoration: underline\">image_processor.communication<\/span> <span style=\"color: #6ab825;font-weight: bold\">import<\/span> <span style=\"color: #d0d0d0\">Communication<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">import<\/span> <span style=\"color: #447fcf;text-decoration: underline\">cv2<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">import<\/span> <span style=\"color: #447fcf;text-decoration: underline\">numpy<\/span> <span style=\"color: #6ab825;font-weight: bold\">as<\/span> <span style=\"color: #447fcf;text-decoration: underline\">np<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">import<\/span> <span style=\"color: #447fcf;text-decoration: underline\">time<\/span>\n<span style=\"color: #d0d0d0\">communication<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">Communication(<\/span><span style=\"color: #ed9d13\">&quot;192.168.1.77&quot;<\/span><span style=\"color: #d0d0d0\">)<\/span>\n<span style=\"color: #d0d0d0\">previous_frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span>\n<span style=\"color: #d0d0d0\">next_frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span>\n<span style=\"color: #d0d0d0\">i<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span>\n<span style=\"color: #d0d0d0\">fps_sum<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span>\n<span style=\"color: #d0d0d0\">fps_str<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #ed9d13\">&#039;loading&#039;<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">while<\/span> <span style=\"color: #24909d\">True<\/span><span style=\"color: #d0d0d0\">:<\/span>\n    <span style=\"color: #d0d0d0\">frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">communication.receive_frame()<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #d0d0d0\">frame<\/span> <span style=\"color: #6ab825;font-weight: bold\">is<\/span> <span style=\"color: #6ab825;font-weight: bold\">not<\/span> <span style=\"color: #24909d\">None<\/span> <span style=\"color: #6ab825;font-weight: bold\">and<\/span> <span style=\"color: #24909d\">type<\/span><span style=\"color: #d0d0d0\">(frame)<\/span> <span style=\"color: #d0d0d0\">==<\/span> <span style=\"color: #d0d0d0\">np.ndarray:<\/span>\n        <span style=\"color: #d0d0d0\">next_frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">time.time()<\/span>\n        <span style=\"color: #d0d0d0\">fps<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">1<\/span><span style=\"color: #d0d0d0\">\/(next_frame<\/span> <span style=\"color: #d0d0d0\">-<\/span> <span style=\"color: #d0d0d0\">previous_frame)<\/span>\n        <span style=\"color: #d0d0d0\">previous_frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">next_frame<\/span>\n        <span style=\"color: #d0d0d0\">fps_sum<\/span> <span style=\"color: #d0d0d0\">+=<\/span> <span style=\"color: #d0d0d0\">fps<\/span>\n        <span style=\"color: #d0d0d0\">i+=<\/span><span style=\"color: #3677a9\">1<\/span>\n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #d0d0d0\">i<\/span> <span style=\"color: #d0d0d0\">==<\/span> <span style=\"color: #3677a9\">10<\/span><span style=\"color: #d0d0d0\">:<\/span>\n            <span style=\"color: #d0d0d0\">fps_str<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #24909d\">str<\/span><span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #24909d\">int<\/span><span style=\"color: #d0d0d0\">(fps_sum\/i))<\/span>\n            <span style=\"color: #d0d0d0\">fps_sum<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span>\n            <span style=\"color: #d0d0d0\">i<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #3677a9\">0<\/span>\n        <span style=\"color: #d0d0d0\">cv2.putText(frame,<\/span> <span style=\"color: #d0d0d0\">fps_str,<\/span> <span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #3677a9\">7<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #3677a9\">70<\/span><span style=\"color: #d0d0d0\">),<\/span> <span style=\"color: #d0d0d0\">cv2.FONT_HERSHEY_SIMPLEX,<\/span> <span style=\"color: #3677a9\">3<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #d0d0d0\">(<\/span><span style=\"color: #3677a9\">100<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #3677a9\">255<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">),<\/span> <span style=\"color: #3677a9\">3<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #d0d0d0\">cv2.LINE_AA)<\/span>\n        <span style=\"color: #d0d0d0\">cv2.imshow(<\/span><span style=\"color: #ed9d13\">&quot;Stream&quot;<\/span><span style=\"color: #d0d0d0\">,<\/span> <span style=\"color: #d0d0d0\">frame)<\/span>\n       \n        <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #d0d0d0\">cv2.waitKey(<\/span><span style=\"color: #3677a9\">1<\/span><span style=\"color: #d0d0d0\">)<\/span> <span style=\"color: #d0d0d0\">==<\/span> <span style=\"color: #3677a9\">27<\/span><span style=\"color: #d0d0d0\">:<\/span>\n            <span style=\"color: #6ab825;font-weight: bold\">break<\/span>\n<\/pre><\/td><\/tr><\/table><\/div>\n\n\n\n<h3 class=\"has-text-align-center wp-block-heading\">Turret example<\/h3>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #202020;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em\"><table><tr><td><pre style=\"margin: 0;line-height: 125%\"> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14<\/pre><\/td><td><pre style=\"margin: 0;line-height: 125%\"><span style=\"color: #6ab825;font-weight: bold\">from<\/span> <span style=\"color: #447fcf;text-decoration: underline\">turret.communication<\/span> <span style=\"color: #6ab825;font-weight: bold\">import<\/span> <span style=\"color: #d0d0d0\">Communication<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">import<\/span> <span style=\"color: #447fcf;text-decoration: underline\">cv2<\/span>\n<span style=\"color: #d0d0d0\">ci<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">Communication(<\/span><span style=\"color: #ed9d13\">&#039;192.168.1.77&#039;<\/span><span style=\"color: #d0d0d0\">)<\/span>\n<span style=\"color: #d0d0d0\">camera<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">cv2.VideoCapture(<\/span><span style=\"color: #3677a9\">0<\/span><span style=\"color: #d0d0d0\">)<\/span>\n<span style=\"color: #6ab825;font-weight: bold\">while<\/span> <span style=\"color: #24909d\">True<\/span><span style=\"color: #d0d0d0\">:<\/span>\n    <span style=\"color: #d0d0d0\">value,<\/span> <span style=\"color: #d0d0d0\">frame<\/span> <span style=\"color: #d0d0d0\">=<\/span> <span style=\"color: #d0d0d0\">camera.read()<\/span>\n    <span style=\"color: #6ab825;font-weight: bold\">if<\/span> <span style=\"color: #d0d0d0\">value:<\/span>\n        <span style=\"color: #d0d0d0\">ci.send_frame(frame)<\/span>\n<\/pre><\/td><\/tr><\/table><\/div>\n\n\n\n<p>&nbsp;The turret example sends frames to the image processor, while the image processor example displays the frames and calculates an average frames-per-second (FPS) metric. During the testing, I achieved an average of approximately 30 FPS, this was quite satisfactory as the camera used by the turret only outputted 30 FPS.<\/p>\n\n\n\n<h2 class=\"has-text-align-center wp-block-heading\">Hannes Weigel<\/h2>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">Week 5<\/h4>\n\n\n\n<p>The goal for this week was to assemble the Azimuth Drive of the turret. Most of the printing work had been achieved by late week 4 \/ early week 5. With an estimated total printing time of 70 hours, I\u2019m certain this project has contributed to about 0.1% of the total microplastics in the oceans.<\/p>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">The Sun Gear<\/h4>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/U4bnIXL9zTp3swaM-scPNzNOiKYMqU-367SMqcVjKHN9tq3Q7ZDPCq7zQy2OjCM2bt42fbTAPgDXNdvcr7VzzXxafDPOTYS8mtv0HsSFF64AdvXPYUoZL1-DUfSs5X0lEwzbRyYxmZgTxbvqChjsn3I\" width=\"602\" height=\"452\"><\/p>\n\n\n\n<p>The sun gear is now completely finished. Consisting of the outer teeth ring, upper inner race, lower inner race, and 144 bearing rollers.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/omnom7UcPez8PyqMo84UN4vK73BqTAegCXLgTW-qDz_TD2Nx9tbJf1XwnAV0ipy0pmsJqTYoHCF72ked--pUa2DjKj2clnJtrWBhlh7BS_jQkP2UG1kX3mWdx_bt6NasitLlUedb572q1sUmt956D30\" width=\"471\" height=\"629\"><\/p>\n\n\n\n<p>The inner race of the slew bearing consists of an upper and lower ring. The seam of these rings is offset by 45 degrees.&nbsp;<\/p>\n\n\n\n<p>After assembling both upper and lower, I realized that I had no way of feeding the bearings into the race.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"452\" src=\"https:\/\/lh3.googleusercontent.com\/R13_X9XvlOo3HryyyizylUAdgwEuSMrEDWTZJ2vpz4X_u-ViPwEWkqaASzzgR4h8IllpajIjxAypm7IQx8k5hve-7yc92lBDHxzLXT3PbIvVtDPwZra1l7sTlKXVy4qLYzmX4-OFe23I3PGuDnT-9-g\"><\/p>\n\n\n\n<p>Therefore I had to bolt the upper plate of the thrust bearing to the lower ring of the inner race.<\/p>\n\n\n\n<p>With these two components now joined, the painstaking process of adding 144 bearings to the race started. Thankfully, I got great help from Ole, as the entire process of cleaning the bearings, and orienting the bearings took nearly an hour.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/09\/Last-Segment-Upper-Race.mp4\"><\/video><\/figure>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/09\/Spinning-Sun-Gear.mp4\"><\/video><\/figure>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">Thrust Bearing<\/h4>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"452\" src=\"https:\/\/lh6.googleusercontent.com\/wXCG5aHi4hcnkfqmzgcKPKr1xWQmufqJjGzPjnLQX7hENTSCZbR0lMJIO7bSZPD_iBJqhekTLfIuNzHu_WDEhtOUALeT9KTG7lLRXZ90U6BqrTnTPpzPSVu6wzgozEo5OPTJ_cuWh8LuxQ32jKlEB-w\"><\/p>\n\n\n\n<p>The thrust bearing consists of four segments with matching protrusions\/cavities on each end. The segments are held together by pinions.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/3ppQwU8IzdvPvJ5OuE1JUttGBO3jFS7HsT-RTj3cM1k2OzmOhFYTJTefDRne4z2VgdwgC0hmIIS_ejPgtgFSmvQBxjZN0wyiyxLeT6Qs77-xX9gbVHcy10vWz0BMNYr50p4f6Rx9rLn2JGdxhL9pAzA\" width=\"602\" height=\"452\"><\/p>\n\n\n\n<p>In the first iteration of the bearing\/shaft design, said shafts were 3D printed, which obviously -now- was a terrible idea.<\/p>\n\n\n\n<p>Thankfully for Richard Thues endless wisdom, the shafts were replaced with lightly sanded BBQ skewers. This worked remarkably well!<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/_oMDBZM-PI5dWw6XldPQXNd-VLNqqQOoqr7JUqQX8pOT86ME_Z84PunXpCQ6AHbG9z54VutJ__AuJnOMU9n9OYemsQMq_DJMitNxreXlyW17e4CfPBDwP2ZVEzQi1C1l24P6ITXWAHl6469n_ASKdw8\" width=\"602\" height=\"452\"><\/p>\n\n\n\n<p>Now the thrust bearing was completely assembled with 20 rollers, 20 shafts, and a bottom plate.&nbsp;<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" width=\"471\" height=\"629\" src=\"https:\/\/lh4.googleusercontent.com\/yIDrCIKBIq1gLMd3eA7RsyfRi03Z0lopat33N3WBO3ixYOumGl9e0DbjGQIvOMseboZO39NfX3skFhCfYpFpTB0J9YT5lK848eJ2LeA2IyVQL1aYqPvZClDltWR0l4-stdY-1Eweif_4KvNFL4kxdEk\"><\/p>\n\n\n\n<p>The last step was laying the sun gear on the thrust bearing, and giving it a spin!<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/dronesonen.usn.no\/wp-content\/uploads\/2023\/09\/Sun-Gear-Spin-With-Thrust-Bearing.mp4\"><\/video><\/figure>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">The Ring Gear<\/h4>\n\n\n\n<p>The Azimuth Drive obviously consists of more than just the sun gear and the thrust bearing. The planet gears had been printed previously, so the only outstanding parts were the ring gear and the mounting plate.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/G66ZnA86NKeK_q8UrhVGPMGCRD82ZoC5DoT96l5-4o4y7HgoATBbVBEXxhDMK-J3fEzConZSUcoU3SMik-WA9PjHRZl4WI4bm0wMndntOzzq8vVYb0adyHCek9ftCX_TrU1MjI253O6THzaEfdW6kG8\" width=\"471\" height=\"629\"><\/p>\n\n\n\n<p>The ring gear would consist of 9 layers of 3.3mm plywood. As with previous parts, the seams of the rings would be 45 degrees offset from each other. 9 layers \u00e0 4 segments are 36 pieces.<\/p>\n\n\n\n<p>Of course, the fume extractor for the laser cutter broke, which now has resulted in an incomplete ring gear and missing mounting plate.<\/p>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\">Further Work<\/h4>\n\n\n\n<p>Hopefully the laser cutter will be up and running again, so that the azimuth drive can be completely assembled. The goal for this week was -and still is- to design the completed pitching system of the paintball marker.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here is our teams contributions for our project this week in sprint 5! Things are starting to ramp up! Harald Berzinis Harald Berzinis This week I have been reiterating the original model, 3D-printing the trigger mechanism and further testing it.\u00a0\u00a0 Initial CAD-design: Main Enclosure: The main enclosure that holds everything together, 3cm x 5cm x [&hellip;]<\/p>\n","protected":false},"author":100,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7732","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/7732","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/users\/100"}],"replies":[{"embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7732"}],"version-history":[{"count":9,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/7732\/revisions"}],"predecessor-version":[{"id":7783,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=\/wp\/v2\/posts\/7732\/revisions\/7783"}],"wp:attachment":[{"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7732"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7732"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dronesonen.usn.no\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}