From 868857d494c43aacd63ceff8872af7cad03bc88e Mon Sep 17 00:00:00 2001 From: Carlos Pereira Atencio Date: Mon, 10 Jun 2024 18:05:44 +0100 Subject: [PATCH] Add Action Threshold to the model header. --- README.md | 23 ++++++++++++++ autogenerated.ts | 2 +- enums.d.ts | 7 +++-- pxt.json | 2 +- pxtextension.cpp | 82 +++++++++++++++++++++++++++++++++--------------- 5 files changed, 86 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 2687ef2..c9a60bd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,29 @@ This extension is experimental and is being used for testing purposes. +## Building locally + +Ensure you have the required toolchain to build for V1 and V2 +(arm-none-eabi-gcc, python, yotta, cmake, ninja, srec_cat) or docker. + +```bash +git clone https://github.com/microbit-foundation/pxt-ml-extension-poc +cd pxt-ml-extension-poc +npm install pxt --no-save +npx pxt target microbit --no-save +npx pxt install +PXT_FORCE_LOCAL=1 PXT_NODOCKER=1 npx pxt +``` + +For the V1 build Yotta can hit the GitHub rate limits quite easily if the +project is built from a clean state more than once. +A V2-only build can be performed with the `PXT_COMPILE_SWITCHES=csv---mbcodal` +environmental variable. + +``` +PXT_FORCE_LOCAL=1 PXT_NODOCKER=1 PXT_COMPILE_SWITCHES=csv---mbcodal npx pxt +``` + ## Build flags ### Built-in ML model diff --git a/autogenerated.ts b/autogenerated.ts index 9eb5e65..6aca7c9 100644 --- a/autogenerated.ts +++ b/autogenerated.ts @@ -14,7 +14,7 @@ namespace mlrunner { } getModelBlob = (): Buffer => { - const result = hex`4C444F4D270028001900500003000000000000035368616B65005374696C6C00436972636C650000620F47304D4C344650000000700D0000A40500000000000000000000A80000000800000001000000080000000100000000000000000000000000000000000000180000000000000003000000000000002DE9F05F0F460169091839600021796038680346B3EC1E1A07F2080292EC010A20EE010A30EE210AA2EC010A92EC010A20EE020A30EE220AA2EC010A92EC010A20EE030A30EE230AA2EC010A92EC010A20EE040A30EE240AA2EC010A92EC010A20EE050A30EE250AA2EC010A92EC010A20EE060A30EE260AA2EC010A92EC010A20EE070A30EE270AA2EC010A92EC010A20EE080A30EE280AA2EC010A92EC010A20EE090A30EE290AA2EC010A92EC010A20EE0A0A30EE2A0AA2EC010A92EC010A20EE0B0A30EE2B0AA2EC010A92EC010A20EE0C0A30EE2C0AA2EC010A92EC010A20EE0D0A30EE2D0AA2EC010A92EC010A20EE0E0A30EE2E0AA2EC010A92EC010A20EE0F0A30EE2F0AA2EC010A02F22402B3EC121A07F2440292EC010A20EE010A30EE210AA2EC010A92EC010A20EE020A30EE220AA2EC010A92EC010A20EE030A30EE230AA2EC010A92EC010A20EE040A30EE240AA2EC010A92EC010A20EE050A30EE250AA2EC010A92EC010A20EE060A30EE260AA2EC010A92EC010A20EE070A30EE270AA2EC010A92EC010A20EE080A30EE280AA2EC010A92EC010A20EE090A30EE290AA2EC010A02F23C02386800F2C00307F268021024B3EC010A07F20801F1EC0E0AF3EC0E7A60EEA70A21EE081A30EE200A61EEA81A30EE010A22EE092A30EE210A62EEA92A30EE020A23EE0A3A30EE220A63EEAA3A30EE030A24EE0B4A30EE230A64EEAB4A30EE040A25EE0C5A30EE240A65EEAC5A30EE050A26EE0D6A30EE250A66EEAD6A30EE060A27EE0E7A30EE260A30EE070AF1EC0A0AF3EC0A7A60EEA70A21EE081A30EE200A61EEA81A30EE010A22EE092A30EE210A62EEA92A30EE020A23EE0A3A30EE220A63EEAA3A30EE030A24EE0B4A30EE230A64EEAB4A30EE040A25EE0C5A30EE240A30EE050AA2EC010A013C8FD107F2680210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C2386800F2007307F208020324B3EC010A07F26801F1EC0E0AF3EC0E7A60EEA70A21EE081A30EE200A61EEA81A30EE010A22EE092A30EE210A62EEA92A30EE020A23EE0A3A30EE220A63EEAA3A30EE030A24EE0B4A30EE230A64EEAB4A30EE040A25EE0C5A30EE240A65EEAC5A30EE050A26EE0D6A30EE250A66EEAD6A30EE060A27EE0E7A30EE260A30EE070AF1EC020AF3EC027A60EEA70A21EE081A30EE200A30EE010AA2EC010A013CAFD107F208021046032100F002F8BDE8F09F012938B5D0ED002A29D9031D00EB8102F3EC017AF4EE627AF1EE10FAC8BFF0EE672A9A42F4D1002402EE104A054695ED000A30EE620A00F015F80134A14232EE002AA5EC010AF2D8002390ED007AC7EE027A01339942E0EC017AF6D838BD0029E1D138BDDFED297AB4EEE70AF1EE10FA48D4DFED277AB4EEE70AF1EE10FA3ADCDFED247ADFED244A9FED243ADFED243A9FED245A9FED244ADFED245A9FED246ADFED246A60EE277AB7EE007A77EEA47A77EEE47AA7EE830AFDEEE74AA7EEA30AF0EE457AE4EE007A14EE903AE7EE805AA5EE806AE6EE006AF0EE667AF0EE476AE7EE806AA6EE807A17EE102A02EBC35300EE103A7047DFED107AB7EE007A87EE270A70479FED0C0A704700000000AAC20000AE423BAAB83F0000404B007231BF8EBEBFB56E2F093C00A0B43AADAD2A3D28AA2A3EFBFFFF3E00000000C956A53FB5BFF2BEC8A4CF3F59C686BFD39EE13FA24D4C3D341DFD3F084BBA3E9E9CEB3F603506BF8509E73F2F9C6E3F3BF26F3F6FD8343FA273A03F8EB07B3DB3359E3F361AA23FD15AE23F2B4FEDBE554AB33F8B315DBEB1DB0540EF9E11BFE8BD263FF6DEE6BF5A5BB93E295054BF9866263FB5C0DDBF4FCF2B3DD8C7C8BF74293B3DD72AE7BFD3B6683D6A753AC0218D224006D3BABCE213EA3F4248043EB06190406D0BD23DDA4F094098C16CBFBCE40440BB166DBFC03B01402101A3BFDC506D3BF9F3B03E2308D0BE00C316BF6F7F79BE09B891BE6A463BBFE0247E3C880900BEB55BB1BE43EBB53E62CF403E0B9CDA3EB74D2F3E55E5A43ED75B613ED8FA8BBDE1D564BF30C3E73E016415BF962BAE3CA42E2EBF09BA8CBEFCD96BBF7486F53E80AEC23DDB820D3EACCB963ED947E03E5EC2DABDF7DD24BEE0B7613D3F1C893DCF78F5BEC6D4B7BEDF4285BEF0EE0C3E3613893E312FCB3E1F40BA3CF6A18F3EE0CB473E40FE5E3DCF29463E3BD21E3EAB46393EE206863FF7E28D3DFCF135BD8EE6963E325E7D3DA676D83DC17399BDE024423EA80F503DACBF0EBE070602BE6244F73DA90457BD88D62C3E7F06233EA6EB5DBE4A5605BFC49A8FBE03137BBE336AB5BECD3ACE3E2DA56DBDE688DCBEDBCBFC3E0DFABC3D328CFB3E162E253FB27E5EBE5D2FDABE2480ACBD8688453D57AD31BE25D448BE8FFE843D97299CBEB9C7D23C96553F3DB565B73E8CFF2D3D57CFD53D3F028FBEDFF2B6BB58F582BEC773043DF66420BE892D4CBE9964CC3E0DA9A53D2F9FB1BED90288BE6A98E73E24DB603EB265B0BC00EF35BE685084BD49ACD9BDAE6D853E7AAA86BE9FE7BF3DF30114BFDD31B63D0445EFBDA65C3EBEA94D77BD1C167CBDED09543E396B20BE96237BBD06A5BD3D36F1DF3D7CC7CB3EC09C543EA91CF0BEA2628E3EBB552A3E60D9FB3DB17DAD3DBC839B3DEB99953D393BCDBDFCB9B63E27FD97BE269401BEFA6E183E65D621BEA5B9363C2738253E5BEF043ED606363EEAA84CBDBD31B43E35F2A33CAEA7B4BDE22252BE89A2D5BD5220003C52F9BFBC42213BBE760A8B3EE60798BEEAA9A4BE4BDD7C3E568E77BC1B8B82BE0F6AB4BC803DB4BEFF17003D543DDA3D6214C2BEA4B7AA3E32C93F3E27E805BF4BC335BE2567003C9468B13D513DEB3D76E9763D747DD73E8D4003BFEC802E3F508CB23E19315A3D0BA914BF6DA56E3DA65F15BEFEE601BE3B8E25BE6E8D4BBED60920BF56C9AEBCF0BC9B3E36AFDD3E171ED93E6BD1033EBDF91E3EDF2082BD4A9FC93C008B04BF9ED8E0BEB11FCE3ECF1C27BD9CCFB93EBBB4803C3D568CBEE1DF443EB50C713E0E788A3EDA040D3D443AEE3ED2FC6F3EA4B6603EA7A3593EFE9D413E5F302C3E8AB2EEBDD61429BEDAC38BBE9618A5BE6365063F6BFF5BBE703CB23E2C8B673E994743BEEB96DC3D4D20FD3D619B6CBED7E139BD86C5663DFF8DD8BD9335E8BD3E19C53E0B54413CC29E043D8ED579BE89CC6A3E922BD73DBA4882BD1B665A3E4B390DBEAE4F32BE4A24A6BE5850F63DB341483D06529DBE44CDDF3DAB1F9CBE1C257EBE1C72E0BC3722CA3D3B12ED3CD5F4F6BD1C918CBEE688843EC30211BDE283823D398000BE623D18BEA742043EF8BE0EBE359E03BE3C53B7BE3E64033E3268E9BDA4D6943DD6F651BD078CC0BC110C9E3DE790E0BE422A1ABFE98AA03CB01FB63EC627853E6460CF3E76FD903D7D2D79BE249D9C3DE1D9323E88F8123FABF200BF8B03063FE390E9BD2EC5743EEEA5E2BED07A423E2C65323E593D69BF5D69C0BE9D838EBE9B4C61BE3C9D25BE806AB33EECCB8ABE2C3F633D487BF2BD166E8FBECE4DE43D01185ABED33B573EFD9A5A3E26D7AFBEA4900FBE4B7B073EC767BDBE4E370A3D79D2B73DF31FAD3ECF0932BE7D3F15BE8323203E970CE8BEC782B83DB721E83EF91D4BBE18C2B33B4D301ABEBEB9933EE5D56D3EEEA5963D0EE88B3D1EADE7BC4A01F93DEB15E4BD2C6B023EFAA1ACBE28EAAFBD7FFEC4BE37F0723EB1588C3DA0EBF5BDB2AC18BBB3BC88BDA3DBCB3D43FABCBC5622993E22DE41BEC52F293F5B43483EBBBB6CBB1BFC653E8896F8BCECF5653E9567483E8C738E3E7B783ABD3BC2753E5D15343E6FA449BC299E48BEFC68E83D76BEB73C472C4E3E07F4893E24D4D53D7C19B1BDA82389BEE803B23DAFE99D3D4475633E68B39BBD4A2089BDEFC7703EB8CFA33EE83C2ABE60EB833E016D243E5F62AA3D8CCBA63E1DA4BE3D25E1293EFE51463EF12045BE999E593CD6CF2B3DC7E88EBD8FA6AC3E7FD1A33E82D54C3ED4EB3A3EAAFDDB3E855E76BEAECAA6BDF156AE3E5843333ED5DE5C3ECBA59B3E4F271F3E5B9F9C3E9DA811BE669A113ED5C86CBE9124BCBE190BDCBE592A91BE5435A83E9B3D25BF001CC23E79264C3E0FD405BEBB7C563E1B7710BF714514BE60EFBEBE6BE58ABF9C6761BEDF5D89BFEAB1DA3D6B04EE3E5BE3613EDE4D133D0FE6D6BDC6BC8A3E674635BE6B6F973E63558EBD137A72BD298D7EBFE89E423FC7E17B3E37C8923E9AD7A23D2DB5BFBEC83843BED63D5C3F38090ABF2025C2BDF0E01CBF52B228BD1705B2BD522ADE3E0766F83E85A601BF3A0AD5BEC72D12BF0DD336BE52D1F63E13AF073FE2E325BEDB4D7D3DB7B022BF05DF22BF4E5D66BD75E41E3D1521A23DE37DA13EC1F3ED3E7595F33E80AA54BF5A2E733F7D59F33E8A9A583FBED47CBE0CCA2EBF6C46E13D048907BFCC7533BDBD110B3F44272D3E30ACC4BE10F4903EB7180A3F22E8AFBE5B0845BF244012BC334D54BD414E3BBF`; + const result = hex`4C444F4D38001900500003000000000000000003CDCC4C3F065368616B650000CDCC4C3F065374696C6C0000CDCC4C3F07436972636C6500620F47304D4C344650000000700D0000A40500000000000000000000A80000000800000001000000080000000100000000000000000000000000000000000000180000000000000003000000000000002DE9F05F0F460169091839600021796038680346B3EC1E1A07F2080292EC010A20EE010A30EE210AA2EC010A92EC010A20EE020A30EE220AA2EC010A92EC010A20EE030A30EE230AA2EC010A92EC010A20EE040A30EE240AA2EC010A92EC010A20EE050A30EE250AA2EC010A92EC010A20EE060A30EE260AA2EC010A92EC010A20EE070A30EE270AA2EC010A92EC010A20EE080A30EE280AA2EC010A92EC010A20EE090A30EE290AA2EC010A92EC010A20EE0A0A30EE2A0AA2EC010A92EC010A20EE0B0A30EE2B0AA2EC010A92EC010A20EE0C0A30EE2C0AA2EC010A92EC010A20EE0D0A30EE2D0AA2EC010A92EC010A20EE0E0A30EE2E0AA2EC010A92EC010A20EE0F0A30EE2F0AA2EC010A02F22402B3EC121A07F2440292EC010A20EE010A30EE210AA2EC010A92EC010A20EE020A30EE220AA2EC010A92EC010A20EE030A30EE230AA2EC010A92EC010A20EE040A30EE240AA2EC010A92EC010A20EE050A30EE250AA2EC010A92EC010A20EE060A30EE260AA2EC010A92EC010A20EE070A30EE270AA2EC010A92EC010A20EE080A30EE280AA2EC010A92EC010A20EE090A30EE290AA2EC010A02F23C02386800F2C00307F268021024B3EC010A07F20801F1EC0E0AF3EC0E7A60EEA70A21EE081A30EE200A61EEA81A30EE010A22EE092A30EE210A62EEA92A30EE020A23EE0A3A30EE220A63EEAA3A30EE030A24EE0B4A30EE230A64EEAB4A30EE040A25EE0C5A30EE240A65EEAC5A30EE050A26EE0D6A30EE250A66EEAD6A30EE060A27EE0E7A30EE260A30EE070AF1EC0A0AF3EC0A7A60EEA70A21EE081A30EE200A61EEA81A30EE010A22EE092A30EE210A62EEA92A30EE020A23EE0A3A30EE220A63EEAA3A30EE030A24EE0B4A30EE230A64EEAB4A30EE040A25EE0C5A30EE240A30EE050AA2EC010A013C8FD107F2680210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C210680028B8BF40F2000001C2386800F2007307F208020324B3EC010A07F26801F1EC0E0AF3EC0E7A60EEA70A21EE081A30EE200A61EEA81A30EE010A22EE092A30EE210A62EEA92A30EE020A23EE0A3A30EE220A63EEAA3A30EE030A24EE0B4A30EE230A64EEAB4A30EE040A25EE0C5A30EE240A65EEAC5A30EE050A26EE0D6A30EE250A66EEAD6A30EE060A27EE0E7A30EE260A30EE070AF1EC020AF3EC027A60EEA70A21EE081A30EE200A30EE010AA2EC010A013CAFD107F208021046032100F002F8BDE8F09F012938B5D0ED002A29D9031D00EB8102F3EC017AF4EE627AF1EE10FAC8BFF0EE672A9A42F4D1002402EE104A054695ED000A30EE620A00F015F80134A14232EE002AA5EC010AF2D8002390ED007AC7EE027A01339942E0EC017AF6D838BD0029E1D138BDDFED297AB4EEE70AF1EE10FA48D4DFED277AB4EEE70AF1EE10FA3ADCDFED247ADFED244A9FED243ADFED243A9FED245A9FED244ADFED245A9FED246ADFED246A60EE277AB7EE007A77EEA47A77EEE47AA7EE830AFDEEE74AA7EEA30AF0EE457AE4EE007A14EE903AE7EE805AA5EE806AE6EE006AF0EE667AF0EE476AE7EE806AA6EE807A17EE102A02EBC35300EE103A7047DFED107AB7EE007A87EE270A70479FED0C0A704700000000AAC20000AE423BAAB83F0000404B007231BF8EBEBFB56E2F093C00A0B43AADAD2A3D28AA2A3EFBFFFF3E00000000C956A53FB5BFF2BEC8A4CF3F59C686BFD39EE13FA24D4C3D341DFD3F084BBA3E9E9CEB3F603506BF8509E73F2F9C6E3F3BF26F3F6FD8343FA273A03F8EB07B3DB3359E3F361AA23FD15AE23F2B4FEDBE554AB33F8B315DBEB1DB0540EF9E11BFE8BD263FF6DEE6BF5A5BB93E295054BF9866263FB5C0DDBF4FCF2B3DD8C7C8BF74293B3DD72AE7BFD3B6683D6A753AC0218D224006D3BABCE213EA3F4248043EB06190406D0BD23DDA4F094098C16CBFBCE40440BB166DBFC03B01402101A3BFDC506D3BF9F3B03E2308D0BE00C316BF6F7F79BE09B891BE6A463BBFE0247E3C880900BEB55BB1BE43EBB53E62CF403E0B9CDA3EB74D2F3E55E5A43ED75B613ED8FA8BBDE1D564BF30C3E73E016415BF962BAE3CA42E2EBF09BA8CBEFCD96BBF7486F53E80AEC23DDB820D3EACCB963ED947E03E5EC2DABDF7DD24BEE0B7613D3F1C893DCF78F5BEC6D4B7BEDF4285BEF0EE0C3E3613893E312FCB3E1F40BA3CF6A18F3EE0CB473E40FE5E3DCF29463E3BD21E3EAB46393EE206863FF7E28D3DFCF135BD8EE6963E325E7D3DA676D83DC17399BDE024423EA80F503DACBF0EBE070602BE6244F73DA90457BD88D62C3E7F06233EA6EB5DBE4A5605BFC49A8FBE03137BBE336AB5BECD3ACE3E2DA56DBDE688DCBEDBCBFC3E0DFABC3D328CFB3E162E253FB27E5EBE5D2FDABE2480ACBD8688453D57AD31BE25D448BE8FFE843D97299CBEB9C7D23C96553F3DB565B73E8CFF2D3D57CFD53D3F028FBEDFF2B6BB58F582BEC773043DF66420BE892D4CBE9964CC3E0DA9A53D2F9FB1BED90288BE6A98E73E24DB603EB265B0BC00EF35BE685084BD49ACD9BDAE6D853E7AAA86BE9FE7BF3DF30114BFDD31B63D0445EFBDA65C3EBEA94D77BD1C167CBDED09543E396B20BE96237BBD06A5BD3D36F1DF3D7CC7CB3EC09C543EA91CF0BEA2628E3EBB552A3E60D9FB3DB17DAD3DBC839B3DEB99953D393BCDBDFCB9B63E27FD97BE269401BEFA6E183E65D621BEA5B9363C2738253E5BEF043ED606363EEAA84CBDBD31B43E35F2A33CAEA7B4BDE22252BE89A2D5BD5220003C52F9BFBC42213BBE760A8B3EE60798BEEAA9A4BE4BDD7C3E568E77BC1B8B82BE0F6AB4BC803DB4BEFF17003D543DDA3D6214C2BEA4B7AA3E32C93F3E27E805BF4BC335BE2567003C9468B13D513DEB3D76E9763D747DD73E8D4003BFEC802E3F508CB23E19315A3D0BA914BF6DA56E3DA65F15BEFEE601BE3B8E25BE6E8D4BBED60920BF56C9AEBCF0BC9B3E36AFDD3E171ED93E6BD1033EBDF91E3EDF2082BD4A9FC93C008B04BF9ED8E0BEB11FCE3ECF1C27BD9CCFB93EBBB4803C3D568CBEE1DF443EB50C713E0E788A3EDA040D3D443AEE3ED2FC6F3EA4B6603EA7A3593EFE9D413E5F302C3E8AB2EEBDD61429BEDAC38BBE9618A5BE6365063F6BFF5BBE703CB23E2C8B673E994743BEEB96DC3D4D20FD3D619B6CBED7E139BD86C5663DFF8DD8BD9335E8BD3E19C53E0B54413CC29E043D8ED579BE89CC6A3E922BD73DBA4882BD1B665A3E4B390DBEAE4F32BE4A24A6BE5850F63DB341483D06529DBE44CDDF3DAB1F9CBE1C257EBE1C72E0BC3722CA3D3B12ED3CD5F4F6BD1C918CBEE688843EC30211BDE283823D398000BE623D18BEA742043EF8BE0EBE359E03BE3C53B7BE3E64033E3268E9BDA4D6943DD6F651BD078CC0BC110C9E3DE790E0BE422A1ABFE98AA03CB01FB63EC627853E6460CF3E76FD903D7D2D79BE249D9C3DE1D9323E88F8123FABF200BF8B03063FE390E9BD2EC5743EEEA5E2BED07A423E2C65323E593D69BF5D69C0BE9D838EBE9B4C61BE3C9D25BE806AB33EECCB8ABE2C3F633D487BF2BD166E8FBECE4DE43D01185ABED33B573EFD9A5A3E26D7AFBEA4900FBE4B7B073EC767BDBE4E370A3D79D2B73DF31FAD3ECF0932BE7D3F15BE8323203E970CE8BEC782B83DB721E83EF91D4BBE18C2B33B4D301ABEBEB9933EE5D56D3EEEA5963D0EE88B3D1EADE7BC4A01F93DEB15E4BD2C6B023EFAA1ACBE28EAAFBD7FFEC4BE37F0723EB1588C3DA0EBF5BDB2AC18BBB3BC88BDA3DBCB3D43FABCBC5622993E22DE41BEC52F293F5B43483EBBBB6CBB1BFC653E8896F8BCECF5653E9567483E8C738E3E7B783ABD3BC2753E5D15343E6FA449BC299E48BEFC68E83D76BEB73C472C4E3E07F4893E24D4D53D7C19B1BDA82389BEE803B23DAFE99D3D4475633E68B39BBD4A2089BDEFC7703EB8CFA33EE83C2ABE60EB833E016D243E5F62AA3D8CCBA63E1DA4BE3D25E1293EFE51463EF12045BE999E593CD6CF2B3DC7E88EBD8FA6AC3E7FD1A33E82D54C3ED4EB3A3EAAFDDB3E855E76BEAECAA6BDF156AE3E5843333ED5DE5C3ECBA59B3E4F271F3E5B9F9C3E9DA811BE669A113ED5C86CBE9124BCBE190BDCBE592A91BE5435A83E9B3D25BF001CC23E79264C3E0FD405BEBB7C563E1B7710BF714514BE60EFBEBE6BE58ABF9C6761BEDF5D89BFEAB1DA3D6B04EE3E5BE3613EDE4D133D0FE6D6BDC6BC8A3E674635BE6B6F973E63558EBD137A72BD298D7EBFE89E423FC7E17B3E37C8923E9AD7A23D2DB5BFBEC83843BED63D5C3F38090ABF2025C2BDF0E01CBF52B228BD1705B2BD522ADE3E0766F83E85A601BF3A0AD5BEC72D12BF0DD336BE52D1F63E13AF073FE2E325BEDB4D7D3DB7B022BF05DF22BF4E5D66BD75E41E3D1521A23DE37DA13EC1F3ED3E7595F33E80AA54BF5A2E733F7D59F33E8A9A583FBED47CBE0CCA2EBF6C46E13D048907BFCC7533BDBD110B3F44272D3E30ACC4BE10F4903EB7180A3F22E8AFBE5B0845BF244012BC334D54BD414E3BBF`; return result; }; diff --git a/enums.d.ts b/enums.d.ts index 429c21d..30dc795 100644 --- a/enums.d.ts +++ b/enums.d.ts @@ -13,9 +13,10 @@ ErrorSamplesDimension = 802, ErrorSamplesPeriod = 803, ErrorInputLength = 804, - ErrorMemAlloc = 805, - ErrorModelInference = 806, - ErrorDataProcessing = 807, + ErrorActions = 805, + ErrorMemAlloc = 806, + ErrorModelInference = 807, + ErrorDataProcessing = 808, } // Auto-generated. Do not edit. Really. diff --git a/pxt.json b/pxt.json index 1d278b7..93a41fc 100644 --- a/pxt.json +++ b/pxt.json @@ -4,7 +4,7 @@ "description": "Machine learning with the micro:bit experimental extension", "dependencies": { "core": "*", - "ml-runner-poc": "github:microbit-foundation/pxt-ml-runner-poc#v0.3.2" + "ml-runner-poc": "github:microbit-foundation/pxt-ml-runner-poc#v0.3.5" }, "files": [ "README.md", diff --git a/pxtextension.cpp b/pxtextension.cpp index c2a2b33..1d93d85 100644 --- a/pxtextension.cpp +++ b/pxtextension.cpp @@ -1,7 +1,6 @@ #include #include "mlrunner.h" #include "mldataprocessor.h" -#include "example_model1.h" enum MlRunnerIds { MlRunnerInference = 71, @@ -14,15 +13,12 @@ enum MlRunnerError { ErrorSamplesDimension, ErrorSamplesPeriod, ErrorInputLength, + ErrorActions, ErrorMemAlloc, ErrorModelInference, ErrorDataProcessing, }; -static bool initialised = false; - -static const uint16_t ML_CODAL_TIMER_VALUE = 1; - // Enable/disable debug print to serial, can be set in pxt.json #ifndef DEVICE_ML_DEBUG_PRINT #define DEVICE_ML_DEBUG_PRINT 0 @@ -35,9 +31,14 @@ static const uint16_t ML_CODAL_TIMER_VALUE = 1; namespace mlrunner { + static bool initialised = false; + static const uint16_t ML_CODAL_TIMER_VALUE = 1; + static ml_actions_t *actions = NULL; + static ml_predictions_t *predictions = NULL; + // Order is important for the outputData as set in: // https://github.com/microbit-foundation/ml-trainer/blob/v0.6.0/src/script/stores/mlStore.ts#L122-L131 - static const MlDataFilters_t mlDataFilters[] = { + static const MlDataFilters_t mlTrainerDataFilters[] = { {1, filterMax}, {1, filterMean}, {1, filterMin}, @@ -47,33 +48,42 @@ namespace mlrunner { {1, filterZcr}, {1, filterRms}, }; - static const int mlDataFiltersLen = sizeof(mlDataFilters) / sizeof(mlDataFilters[0]); + static const int mlTrainerDataFiltersLen = sizeof(mlTrainerDataFilters) / sizeof(mlTrainerDataFilters[0]); void runModel() { if (!initialised) return; + unsigned int time_start = uBit.systemTime(); float *modelData = mlDataProcessor.getProcessedData(); if (modelData == NULL) { DEBUG_PRINT("Failed to processed data for the model\n"); uBit.panic(MlRunnerError::ErrorDataProcessing); } - ml_prediction_t* predictions = ml_predict(modelData); - if (predictions == NULL) { + + bool success = ml_predict( + modelData, mlDataProcessor.getProcessedDataSize(), actions, predictions); + if (!success) { DEBUG_PRINT("Failed to run model\n"); uBit.panic(MlRunnerError::ErrorModelInference); } - DEBUG_PRINT("Max prediction: %d %s\nPredictions: ", - predictions->max_index, - predictions->labels[predictions->max_index]); - for (size_t i = 0; i < predictions->num_labels; i++) { + DEBUG_PRINT("Prediction (%d ms): ", uBit.systemTime() - time_start); + if (predictions->index >= 0) { + DEBUG_PRINT("%d - %s\n", + predictions->index, + actions->action[predictions->index].label); + } else { + DEBUG_PRINT("None\n"); + } + DEBUG_PRINT("\tIndividual:"); + for (size_t i = 0; i < actions->len; i++) { DEBUG_PRINT(" %s[%d]", - predictions->labels[i], - (int)(predictions->predictions[i] * 100)); + actions->action[i].label, + (int)(predictions->prediction[i] * 100)); } DEBUG_PRINT("\n\n"); - MicroBitEvent evt(MlRunnerIds::MlRunnerInference, predictions->max_index + 2); + MicroBitEvent evt(MlRunnerIds::MlRunnerInference, predictions->index + 2); } void recordAccData(MicroBitEvent) { @@ -84,7 +94,7 @@ namespace mlrunner { uBit.accelerometer.getY() / 1000.0f, uBit.accelerometer.getZ() / 1000.0f, }; - MldpReturn_t recordDataResult = mlDataProcessor.recordAccData(accData, 3); + MldpReturn_t recordDataResult = mlDataProcessor.recordData(accData, 3); if (recordDataResult != MLDP_SUCCESS) { DEBUG_PRINT("Failed to record accelerometer data\n"); return; @@ -108,17 +118,12 @@ namespace mlrunner { #endif if (initialised) return; -#if DEVICE_MLRUNNER_USE_EXAMPLE_MODEL != 0 - DEBUG_PRINT("Using example model... "); - void *model_address = (void *)example_model; -#else DEBUG_PRINT("Using embedded model...\n"); if (model_str == NULL || model_str->length <= 0 || model_str->data == NULL) { DEBUG_PRINT("Model string not present\n"); uBit.panic(MlRunnerError::ErrorModelNotPresent); } void *model_address = (void *)model_str->data; -#endif const bool setModelSuccess = ml_setModel(model_address); if (!setModelSuccess) { @@ -154,12 +159,37 @@ namespace mlrunner { uBit.panic(MlRunnerError::ErrorInputLength); } + if (actions != NULL) { + free(actions); + } + actions = ml_allocateActions(); + if (actions == NULL) { + DEBUG_PRINT("Failed to allocate memory for actions\n"); + uBit.panic(MlRunnerError::ErrorMemAlloc); + } + const bool actionsSuccess = ml_getActions(actions); + if (!actionsSuccess) { + DEBUG_PRINT("Failed to retrieve actions\n"); + uBit.panic(MlRunnerError::ErrorActions); + } + DEBUG_PRINT("\tActions (%d):\n", actions->len); + for (size_t i = 0; i < actions->len; i++) { + DEBUG_PRINT("\t\tAction '%s' ", actions->action[i].label); + DEBUG_PRINT("threshold = %d %%\n", (int)(actions->action[i].threshold * 100)); + } + + predictions = ml_allocatePredictions(); + if (predictions == NULL) { + DEBUG_PRINT("Failed to allocate memory for predictions\n"); + uBit.panic(MlRunnerError::ErrorMemAlloc); + } + const MlDataProcessorConfig_t mlDataConfig = { .samples = samplesLen, .dimensions = sampleDimensions, .output_length = modelInputLen, - .filter_size = mlDataFiltersLen, - .filters = mlDataFilters, + .filter_size = mlTrainerDataFiltersLen, + .filters = mlTrainerDataFilters, }; MldpReturn_t mlInitResult = mlDataProcessor.init(&mlDataConfig); if (mlInitResult != MLDP_SUCCESS) { @@ -174,7 +204,7 @@ namespace mlrunner { initialised = true; - DEBUG_PRINT("\tModel loaded\n"); + DEBUG_PRINT("\tModel loaded\n\n"); } //% blockId=mlrunner_stop_model_running @@ -194,6 +224,8 @@ namespace mlrunner { // Clean up mlDataProcessor.deinit(); + free(actions); + free(predictions); initialised = false; DEBUG_PRINT("Done\n\n");