{"id":306,"date":"2017-12-15T15:27:33","date_gmt":"2017-12-15T14:27:33","guid":{"rendered":"http:\/\/www.em-company.fr\/blog\/?p=306"},"modified":"2017-12-22T16:06:40","modified_gmt":"2017-12-22T15:06:40","slug":"sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation","status":"publish","type":"post","link":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/","title":{"rendered":"Sensor Fusion controller using Fuzzy Logic approach (software implementation)"},"content":{"rendered":"<h5>Description and architecture<\/h5>\n<p>In this systems, the sensors are read under interrupt, while some low-speed processes are executed under a 1 sec repetitive timer. The interrupt rates vary, from a few tens of ms\u00a0 (light measures)\u00a0 to completely arbitrary rates (motion detection) or very long periods (Heart Rate value). Hence I had to defined software components at 2 layers<!--more--><\/p>\n<ol>\n<li>One interrupt level layer which consists in various interrupts callbacks, some very basic formatting and message sending.<\/li>\n<li>One &#8220;Framework&#8221; level (this is the <em><strong>Fuzzy Controller<\/strong><\/em>) , which basically gathers, formats and maintains the sensors information.<\/li>\n<\/ol>\n<p>Then the controller is called at regular intervals (seconds) by the &#8220;Application level&#8221; layer, triggered at regular intervals (seconds) to compute the Membership functions, the Fuzzy Rules and derive a decision (defuzzification).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-325\" src=\"http:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg\" alt=\"\" width=\"967\" height=\"835\" srcset=\"https:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg 967w, https:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd-300x259.jpg 300w, https:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd-768x663.jpg 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\n<h6>Data Structures<\/h6>\n<p>To convey information from the Interrupt level to the Framework level, the following paradigm has been chosen<\/p>\n<ul>\n<li>ISR (Interrupt service routine) sends a 2 bytes data structure, whose mapping is specific to the Originating sensor<\/li>\n<li>ISR calls a Framework interrupt callback<em>\u00a0<\/em>by supplying the following information: Originator and Specific Bit-mapped value<\/li>\n<\/ul>\n<pre>\/\/ Originator of the OWD info\r\ntypedef enum { FROM_BMI_NO_MO, FROM_BMI_ANY_MO, FROM_OHRM, FROM_LS, MAX_OWD_CONTRIBUTORS } fwk_owd_from_t; \r\n\r\n\/\/ decision type\r\ntypedef enum { ON_ARM_STATE, OFF_ARM_STATE, OWD_UNDEFINED_STATE } OWD_Decision_t;<\/pre>\n<p>Shared data structures are defined to hold information from the Sensor detection.<\/p>\n<pre>\/\/ Shared Data structures\r\n\/\/\r\n\r\n<strong>\/\/ Case of BMI160 accelerometer<\/strong>\r\ntypedef struct fwd_owd_bmi {\r\n union {\r\n uint16_t val8;\r\n struct {\r\n uint8_t bmi_anymo_event : 1; \/\/ Any-motion\r\n uint8_t bmi_nomo_event : 1; \/\/ no motion\r\n uint8_t bmi_signimo_event : 1; \/\/ significant movement\r\n uint8_t bmi_orient_fup : 1; \/\/ Orientation facing up\r\n uint8_t bmi_orient_fdown : 1; \/\/ Orientation facing down\r\n uint8_t bmi_orient_portrait_top : 1; \/\/ Orientation portait top\r\n uint8_t bmi_orient_portrait_down : 1; \/\/ Orientation portait down\r\n uint8_t bmi_orient_land_left : 1; \/\/ Orientation landscape left\r\n uint8_t bmi_orient_lan_right : 1; \/\/ Orientation landscape right\r\n uint8_t padding : 7;\r\n } bits;\r\n };\r\n} fwk_bmi_events_t;\r\n\r\n<strong>\/\/ Case of OHRM detector<\/strong>\r\ntypedef struct fwd_owd_ohrm {\r\n union {\r\n uint16_t val16;\r\n struct {\r\n uint8_t ohrm_conf_level : 8; \/\/ confidence level in %\r\n uint8_t ohrm_locked : 1;\r\n uint8_t padding : 7;\r\n } bits;\r\n };\r\n} fwk_owd_ohrm_events_t;\r\n\r\n<strong>\/\/ Case of ambient light sensing<\/strong>\r\ntypedef struct fwd_owd_light {\r\n union {\r\n uint16_t val16; \/\/ light sensor adc value (12 bits)\r\n struct {\r\n uint16_t val : 16;\r\n } bits;\r\n };\r\n} fwk_owd_light_events_t;<\/pre>\n<h6>Interfaces to the OWD Framework<\/h6>\n<p>As an example, the BMI NoMotion ISR would call the framework callback<\/p>\n<pre>void bmi160_isr_int2_handler(void)\r\n{\r\n \r\n\/\/ anymotion was detected\r\nif ( .... )\r\n {\r\n fwk_bmi_events_t event = { 0 };\r\n event.bits.bmi_anymo_event = 1;\r\n \r\n<strong>fwk_owd_common_int_cb(FROM_BMI_ANY_MO, &amp;event);<\/strong>\r\n }\r\n\/\/ nomotion was detected \r\nif ( .... )\r\n {\r\n fwk_bmi_events_t event = { 0 };\r\n event.bits.bmi_nomo_event = 1;\r\n\r\n<strong>fwk_owd_common_int_cb(FROM_BMI_NO_MO, &amp;event);<\/strong>\r\n }\r\n}<\/pre>\n<p>Similarly the light sensor reading callback would call the framework as follows<\/p>\n<pre>void fwk_owd_al_adc_cb(void)\r\n{\r\n uint16_t LsValue;\r\n\r\n ......\r\n ......\r\n <strong>fwk_owd_add_info(FROM_LS, (void*)&amp;LsValue);<\/strong> \/\/ LsValue holds the reading\r\n .......\r\n .......\r\n}<\/pre>\n<p>Within the callback, the passed data is used to call the Controller appropriately. Depending on the sensor, this can be pure value translation, but some processing can also be done. An interesting case is the AnyMotion\/NoMotion events<\/p>\n<pre> if (ActiveNoMotionStatus)\r\n {\r\n <strong>fwk_owd_add_event(FROM_BMI_NO_MO, true);<\/strong>\r\n fwk_owd_add_event(FROM_BMI_ANY_MO, <strong>false<\/strong>);\r\n }\r\n else\r\n {\r\n fwk_owd_add_event(FROM_BMI_NO_MO, false);\r\n fwk_owd_add_event(FROM_BMI_ANY_MO, true);\r\n }<\/pre>\n<p>Notice that we had to duplicate the calls to signal both NO_MOTION and ANY_MOTION at each time. The reason lies deep into the BMI specifications and operations. Basically, if we detect &#8220;ANY_MOTION&#8221; that also means that &#8220;NO_MOTION&#8221; was NOT detected\u00a0 :). This sounds redundant but really isn&#8217;t to our purpose.<\/p>\n<h6>Fuzzy Logic Controller (Sensor Fusion Controller)<\/h6>\n<p>The Fuzzy logic based\u00a0 controller does three main things<\/p>\n<ul>\n<li>It aggregates the sensors provided data into proper structures<\/li>\n<li>Maintain running averages on those data<\/li>\n<li>Upon being called (<em>fwk_compute_owd_decision)<\/em>\n<ul>\n<li>For each sensor computes the membership values (on the averaged values)<\/li>\n<li>computes the Inference rules<\/li>\n<li>Performs the defuzzification and derives the decision<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>As seen earlier, the controller has two main entry points, for sensors carrying analog information and sensors carrying digital information. Although this could have been done with a generic method, I preferred this approach for code clarity<\/p>\n<pre>void fwk_owd_add_info(fwk_owd_from_t orig, void *data); \r\nvoid fwk_owd_add_event(fwk_owd_from_t orig, bool found);<\/pre>\n<p>The\u00a0<em>fwk_add_event<\/em> will basically fall down to the normal case after a simplistic transformation of boolean values into numerical values, as follows<\/p>\n<pre>#define EVENT_FOUND_NUMERICAL (100)\r\n#define EVENT_NOTFOUND_NUMERICAL (0)\r\n\r\nvoid fwk_owd_add_event(fwk_owd_from_t orig, bool found)\r\n{\r\n uint16_t value;\r\n\r\n\/\/ arbitrarily normalise to 0-100 range\r\n if (found)\r\n {\r\n value = EVENT_FOUND_NUMERICAL;\r\n }\r\n else\r\n {\r\n value = EVENT_NOTFOUND_NUMERICAL;\r\n }\r\n <strong>fwk_owd_add_info(orig, (void *)&amp;value);<\/strong>\r\n}<\/pre>\n<p>Here I defined a compound data structure to hold all the data received, but also the averaged values and pointers to static methods like averaging function, membership functions. It is definitely not required to do so, it is purely a matter of personal habit.<\/p>\n<pre>static const owd_contrib_t owdContribTable[MAX_OWD_CONTRIBUTORS] = { \/* avg                  pAvgFunc       pMFunc*\/\r\n { &amp;owd_data.bmiNoMo, stdAvgFunc, bmiNoMoMfArray}, \/* BMI_NOMO*\/\r\n { &amp;owd_data.bmiAnyMo, stdAvgFunc, bmiAnyMoMfArray }, \/* BMI_ANYMO*\/\r\n { &amp;owd_data.hrLockVal, stdAvgFunc, hrLockMfArray }, \/* OHRM*\/\r\n { &amp;owd_data.lsValue , stdAvgFunc, lsValueMfArray } \/* LS*\/\r\n };<\/pre>\n<p>Let us now review the main entry point\u00a0\u00a0<em>fwk_add_info.<\/em><\/p>\n<pre>#define STD_RUNNING_AVG_DEPTH (3) \/* This means 2**3 = 8 *\/\r\n#define VL_RUNNING_AVG_DEPTH (8) \/* HR Conf level (256 seconds) *\/\r\n\r\nvoid fwk_owd_add_info(fwk_owd_from_t orig, void *data)\r\n{\r\n uint16_t val;\r\n\r\n\/\/ Accept auto-generated 0 values, to help decreasing the avg,\r\n \/\/ as well as real non-zero values for actual sensor values\r\n val = *(uint16_t*)data;\r\n \/\/ average each value (running avg)\r\n if (orig == FROM_OHRM)\r\n {\r\n val = val &gt; OHRM_CFLVL_THR ? 1 : 0;\r\n owdContribTable[orig].avgFunc(owdContribTable[orig].avg, <strong>VL_RUNNING_AVG_DEPTH<\/strong>, val);\r\n }\r\n else\r\n owdContribTable[orig].avgFunc(owdContribTable[orig].avg, <strong>STD_RUNNING_AVG_DEPTH<\/strong>, val);\r\n\r\n\/\/ update the noMotion status\r\n if ((orig == FROM_BMI_NO_MO) &amp;&amp; (val == EVENT_FOUND_NUMERICAL))\r\n ActiveNoMotionStatus = true;\r\n else if ((orig == FROM_BMI_ANY_MO) &amp;&amp; (val == EVENT_FOUND_NUMERICAL))\r\n ActiveNoMotionStatus = false;\r\n}<\/pre>\n<p>So for each value, we call the averaging function with different depth, depending on the sensor nature. The averaging function can be easily changed, by changing the table pointers. I opted for a standard running average<\/p>\n<pre>\/********************************************************************\r\n* \\brief generic averaging function whatever the data. We therefore assume a\r\n* reference to the avg os passed as parameter (as the func is generic ..)\r\n*\r\n* \\param[in] reference to the avg\r\n* \\param[in] depth of the estimator (2**depth)\r\n* \\param[in] new value to add to the avg\r\n* \\return 0 None\r\n*\r\n* @remarks we use a running average .... this could be change to something else\r\n* if needed\r\n********************************************************************\/\r\nstatic void stdAvgFunc(uint16_t * const avg, int depth, uint16_t newval)\r\n{\r\n uint32_t temp = ((uint32_t)(*avg)) &lt;&lt; 16; \/\/ upconvert to high precision\r\n temp -= (temp &gt;&gt; depth);\r\n temp += ((((uint32_t)newval) &lt;&lt; 16) &gt;&gt; depth);\r\n\r\n*avg = ((temp &gt;&gt; 16) &amp; 0x0000FFFF); \/\/ downconvert and writeback result\r\n}<\/pre>\n<p>so, as a result, we maintain proper sensor values regularly updated and averaged. Now the interesting part, the Fuzzy Rules computation<\/p>\n<h6>Fuzzy Operators \/ Fuzzy Rules<\/h6>\n<p>Let&#8217;s recall that we have to compute fuzzy rules which look like this<\/p>\n<blockquote><p>if motion low and hr not locked and ambient light high<\/p><\/blockquote>\n<p>For doing this, we need to first define the Operators (Fuzzy operators). There are 2 main approaches, one based on MIN and MAX operators (recommended by Pr. Zadeh), the other\u00a0 based on probabilistic operations. Let&#8217;s stick with the latter.<\/p>\n<pre>#define f_one 1.0f\r\n#define f_zero 0.0f\r\n\r\n#define f_or(a,b) (((a)+(b))-((a)*(b))) \/\/ OR\r\n#define f_and(a,b) ((a)*(b)) \/\/ PROD\r\n#define f_not(a) (f_one - a)<\/pre>\n<p>So now, we can compute the Fuzzy Rules inferences. We compute the values for each of the propositions. For example, the &#8220;certainly off-arm&#8221; proposition was defined by 4 rules, so we infer the proposition value using RSS (Root of Sum of Squares). RSS was chosen after experimentation. One should refer to the various documents mentioned in the <a href=\"http:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/20\/sensor-fusion-controller-fuzzy-logic\/\">first article<\/a> of this serie. For this particular proposition, the inference is as follows:<\/p>\n<pre>\/\/ Rules 1, 2, 3 , 3'==&gt; certainly\r\n \/\/ Rule 1\r\n \/\/ 1. if motion low and hr not locked and ambient light high == &gt; certainly off - arm\r\n temp = f_and(MotionMFunc_LOW(owd_data.bmiAnyMo), OhrmMFunc_CFL_OFF_ARM(owd_data.hrLockVal));\r\n temp = f_and(temp,LsMFunc_HIGH(owd_data.lsValue));\r\n <strong>certainly = pow_s (temp, 2);<\/strong>\r\n\r\n\/\/ Rule 2\r\n \/\/ 2. if motion high and hr not locked and ambient light high ==&gt; certainly off-arm\r\n temp = f_and(MotionMFunc_HIGH(owd_data.bmiAnyMo), OhrmMFunc_CFL_OFF_ARM(owd_data.hrLockVal));\r\n temp = f_and(temp,LsMFunc_HIGH(owd_data.lsValue));\r\n <strong>certainly += pow_s(temp, 2);<\/strong>\r\n\r\n\/\/ Rule 3\r\n \/\/ 2. if motion low and hr not locked and (ambient light low or ambient light moderate)==&gt; certainly off-arm\r\n temp = f_and(MotionMFunc_LOW(owd_data.bmiAnyMo), OhrmMFunc_CFL_OFF_ARM(owd_data.hrLockVal));\r\n temp = f_and(temp, f_or(LsMFunc_LOW(owd_data.lsValue), LsMFunc_MID(owd_data.lsValue)));\r\n <strong>certainly += pow_s(temp, 2);<\/strong>\r\n\r\n\/\/ Rule 3'\r\n \/\/ 2. if ambient light high ==&gt; certainly off-arm\r\n temp = LsMFunc_HIGH(owd_data.lsValue);\r\n <strong>certainly += pow_s(temp, 2); certainly = root2_s(certainly);<\/strong>\r\n\r\n<\/pre>\n<p>One will notice the use of the operators previously defined and the various membership functions for each of the fuzzy variables subsets. Finally, we make use of optimised POW and ROOT functions, to minimize the runtime penalty (see my <a href=\"http:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/08\/cortexm4-fp-optimisation\/\">article <\/a>on these optimised functions).<\/p>\n<p>Similarly, the computation of all the other proposition values (<em>probably, certainly not<\/em>)\u00a0 is done.<\/p>\n<h6>Defuzzification<\/h6>\n<p>As an outcome, we have a numerical value for each proposition, which is stored in variables like\u00a0 &#8220;certainly&#8221; (see above figure), &#8220;CertainlyNot&#8221;, etc.<\/p>\n<p>The only small problem is that, statements like &#8220;Certainly&#8221;, &#8220;Probably&#8221; have to also be quantified so we can calculate a &#8220;crisp&#8221; decision value out of our rules. Let us define arbitrarily the output variable &#8220;off-arm plausibility&#8221; as follows<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-331 size-full\" src=\"http:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd2-1-e1513346117524.jpg\" alt=\"Fuzzy output variable\" width=\"682\" height=\"366\" srcset=\"https:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd2-1-e1513346117524.jpg 682w, https:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd2-1-e1513346117524-300x161.jpg 300w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/>That way we can compute the crisp decision (Defuzzification) via the COG method, which is commonly used. COG (Center Of Gravity) can be computed, in our case, with the very common formula<\/p>\n<pre>\/\/ Decision (using COG)\r\n temp = (((10.0f * certainlyNot) + (40.0f * unlikely) + (65.0f * probably) + (90.0f * certainly))\r\n \/ (certainlyNot + unlikely + probably + certainly));<\/pre>\n<p>It assumes that the COG for each of the subset is right at the middle.<\/p>\n<p><em>temp<\/em> variable then contains the degree of plausibility of the &#8220;off-arm&#8221; output variable. By using some carefully chosen decision threshold, one can derive a decision. For example<\/p>\n<pre>\u00a0if (temp&gt; DECISION_THR)\r\n *decision = OFF_ARM_STATE; \/\/ mean of maxima for certainly\r\n     else\r\n *decision = OWD_UNDEFINED_STATE;<\/pre>\n<p>This is a simplistic example, but it answers to the design objectives set at the beginning, which was very conservative.<\/p>\n<h6>Experimental results \/ improvements<\/h6>\n<p>After quite a lot of tests and parameters tuning, we could reach a good decision on &#8220;typical cases&#8221;, like &#8220;<em><strong>device laying\u00a0on the table<\/strong><\/em>&#8220;, at close to 100% success rate.<\/p>\n<p>For other cases, some false positive were recorded. Then, by adjusting the rules, this clearly could be improved. As our design goal was conservative (i.e. Better not do anything if not certain), this was OK and also suited to incremental improvements of the controller.<\/p>\n<p>Finally, it seemed that the most difficult part lies with the Rules definition. When I first started, I very rapidly came up with as much as 11 Rules. It then appeared there were a lot of redundancies, and after experimentation, I dropped some of them. However, the set I came up with is clearly sub-optimal. Improvement in this area has clearly to use some more formal methods than simple gut feeling &#8230;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Description and architecture In this systems, the sensors are read under interrupt, while some low-speed processes are executed under a 1 sec repetitive timer. The interrupt rates vary, from a few tens of ms\u00a0 (light measures)\u00a0 to completely arbitrary rates (motion detection) or very long periods (Heart Rate value). Hence I had to defined software &hellip; <a href=\"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Sensor Fusion controller using Fuzzy Logic approach (software implementation)&#8221;<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,14],"tags":[42],"class_list":["post-306","post","type-post","status-publish","format-standard","hentry","category-embedded","category-programming","tag-fuzzy-logic"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Sensor Fusion controller using Fuzzy Logic approach (software implementation) - Embedded<\/title>\n<meta name=\"description\" content=\"Software implementation of a sensor fusion controller using fuzzy logic. description of methods and main data structures and some tradeoffs\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sensor Fusion controller using Fuzzy Logic approach (software implementation) - Embedded\" \/>\n<meta property=\"og:description\" content=\"Software implementation of a sensor fusion controller using fuzzy logic. description of methods and main data structures and some tradeoffs\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/\" \/>\n<meta property=\"og:site_name\" content=\"Embedded\" \/>\n<meta property=\"article:published_time\" content=\"2017-12-15T14:27:33+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-12-22T15:06:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"967\" \/>\n\t<meta property=\"og:image:height\" content=\"835\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"kriko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"kriko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/\"},\"author\":{\"name\":\"kriko\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#\\\/schema\\\/person\\\/fcb297f759038f0e8cb969c4c29742df\"},\"headline\":\"Sensor Fusion controller using Fuzzy Logic approach (software implementation)\",\"datePublished\":\"2017-12-15T14:27:33+00:00\",\"dateModified\":\"2017-12-22T15:06:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/\"},\"wordCount\":1051,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/www.em-company.fr\\\/blog\\\/wp-content\\\/uploads\\\/owd.jpg\",\"keywords\":[\"fuzzy logic\"],\"articleSection\":[\"embedded\",\"programming\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/\",\"url\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/\",\"name\":\"Sensor Fusion controller using Fuzzy Logic approach (software implementation) - Embedded\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/www.em-company.fr\\\/blog\\\/wp-content\\\/uploads\\\/owd.jpg\",\"datePublished\":\"2017-12-15T14:27:33+00:00\",\"dateModified\":\"2017-12-22T15:06:40+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#\\\/schema\\\/person\\\/fcb297f759038f0e8cb969c4c29742df\"},\"description\":\"Software implementation of a sensor fusion controller using fuzzy logic. description of methods and main data structures and some tradeoffs\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#primaryimage\",\"url\":\"http:\\\/\\\/www.em-company.fr\\\/blog\\\/wp-content\\\/uploads\\\/owd.jpg\",\"contentUrl\":\"http:\\\/\\\/www.em-company.fr\\\/blog\\\/wp-content\\\/uploads\\\/owd.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/12\\\/15\\\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Sensor Fusion controller using Fuzzy Logic approach (software implementation)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/\",\"name\":\"Embedded\",\"description\":\"(...but not only)\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#\\\/schema\\\/person\\\/fcb297f759038f0e8cb969c4c29742df\",\"name\":\"kriko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Sensor Fusion controller using Fuzzy Logic approach (software implementation) - Embedded","description":"Software implementation of a sensor fusion controller using fuzzy logic. description of methods and main data structures and some tradeoffs","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/","og_locale":"en_US","og_type":"article","og_title":"Sensor Fusion controller using Fuzzy Logic approach (software implementation) - Embedded","og_description":"Software implementation of a sensor fusion controller using fuzzy logic. description of methods and main data structures and some tradeoffs","og_url":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/","og_site_name":"Embedded","article_published_time":"2017-12-15T14:27:33+00:00","article_modified_time":"2017-12-22T15:06:40+00:00","og_image":[{"width":967,"height":835,"url":"https:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg","type":"image\/jpeg"}],"author":"kriko","twitter_card":"summary_large_image","twitter_misc":{"Written by":"kriko","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#article","isPartOf":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/"},"author":{"name":"kriko","@id":"https:\/\/www.em-company.fr\/blog\/#\/schema\/person\/fcb297f759038f0e8cb969c4c29742df"},"headline":"Sensor Fusion controller using Fuzzy Logic approach (software implementation)","datePublished":"2017-12-15T14:27:33+00:00","dateModified":"2017-12-22T15:06:40+00:00","mainEntityOfPage":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/"},"wordCount":1051,"commentCount":0,"image":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#primaryimage"},"thumbnailUrl":"http:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg","keywords":["fuzzy logic"],"articleSection":["embedded","programming"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/","url":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/","name":"Sensor Fusion controller using Fuzzy Logic approach (software implementation) - Embedded","isPartOf":{"@id":"https:\/\/www.em-company.fr\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#primaryimage"},"image":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#primaryimage"},"thumbnailUrl":"http:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg","datePublished":"2017-12-15T14:27:33+00:00","dateModified":"2017-12-22T15:06:40+00:00","author":{"@id":"https:\/\/www.em-company.fr\/blog\/#\/schema\/person\/fcb297f759038f0e8cb969c4c29742df"},"description":"Software implementation of a sensor fusion controller using fuzzy logic. description of methods and main data structures and some tradeoffs","breadcrumb":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#primaryimage","url":"http:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg","contentUrl":"http:\/\/www.em-company.fr\/blog\/wp-content\/uploads\/owd.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/12\/15\/sensor-fusion-controller-using-fuzzy-logic-approach-software-implementation\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.em-company.fr\/blog\/"},{"@type":"ListItem","position":2,"name":"Sensor Fusion controller using Fuzzy Logic approach (software implementation)"}]},{"@type":"WebSite","@id":"https:\/\/www.em-company.fr\/blog\/#website","url":"https:\/\/www.em-company.fr\/blog\/","name":"Embedded","description":"(...but not only)","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.em-company.fr\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.em-company.fr\/blog\/#\/schema\/person\/fcb297f759038f0e8cb969c4c29742df","name":"kriko"}]}},"_links":{"self":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=306"}],"version-history":[{"count":16,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/306\/revisions"}],"predecessor-version":[{"id":341,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/306\/revisions\/341"}],"wp:attachment":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}