├── .gitignore ├── render.png ├── easy-esc.jpg ├── hardware ├── .gitignore ├── stm32f103.pdf ├── assembly │ ├── stm32f103-bottom-pos.csv │ ├── stm32f103-BOM.csv │ └── stm32f103-top-pos.csv ├── stm32f103.kicad_prl └── stm32f103.kicad_pro ├── firmware ├── .gitignore ├── test │ └── README ├── include │ ├── stm32f1xxMT6071_NCP81155.h │ └── README ├── lib │ ├── README │ └── MT6701 │ │ ├── MT6701_I2C.h │ │ └── MT6701_I2C.cpp └── src │ ├── clock.c │ └── main.cpp ├── mechanical ├── motormount_b.stl ├── motormount_back.stl ├── motormount_test.stl ├── motormount_front.FCStd ├── stm32f103-motormount_top.stl ├── motormount-back-stlinkcutout.stl ├── stm32f103-motormount-back.FCStd ├── stm32f103-motormount-back.FCStd1 ├── stm32f103-motormount-back-rotor.stl └── aliexpress-motor.step ├── controller ├── src │ ├── preload.ts │ ├── index.html │ ├── app.tsx │ ├── renderer.ts │ ├── Home.tsx │ └── index.ts ├── README.md ├── webpack.plugins.ts ├── .eslintrc.json ├── webpack.renderer.config.ts ├── tsconfig.json ├── webpack.main.config.ts ├── webpack.rules.ts ├── forge.config.ts ├── .gitignore └── package.json ├── .vscode └── extensions.json ├── README.md └── platformio.ini /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .pio/ 3 | c_cpp_properties.json 4 | launch.json 5 | 6 | -------------------------------------------------------------------------------- /render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/render.png -------------------------------------------------------------------------------- /easy-esc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/easy-esc.jpg -------------------------------------------------------------------------------- /hardware/.gitignore: -------------------------------------------------------------------------------- 1 | assembly/ 2 | gerbers/ 3 | *backups/ 4 | fp-info-cache 5 | *.kicad_pcb-bak 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /firmware/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /hardware/stm32f103.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/hardware/stm32f103.pdf -------------------------------------------------------------------------------- /mechanical/motormount_b.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/motormount_b.stl -------------------------------------------------------------------------------- /mechanical/motormount_back.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/motormount_back.stl -------------------------------------------------------------------------------- /mechanical/motormount_test.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/motormount_test.stl -------------------------------------------------------------------------------- /mechanical/motormount_front.FCStd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/motormount_front.FCStd -------------------------------------------------------------------------------- /mechanical/stm32f103-motormount_top.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/stm32f103-motormount_top.stl -------------------------------------------------------------------------------- /mechanical/motormount-back-stlinkcutout.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/motormount-back-stlinkcutout.stl -------------------------------------------------------------------------------- /mechanical/stm32f103-motormount-back.FCStd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/stm32f103-motormount-back.FCStd -------------------------------------------------------------------------------- /mechanical/stm32f103-motormount-back.FCStd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/stm32f103-motormount-back.FCStd1 -------------------------------------------------------------------------------- /mechanical/stm32f103-motormount-back-rotor.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VIPQualityPost/easy-esc-stm32f103-mt6701-ncp81155/HEAD/mechanical/stm32f103-motormount-back-rotor.stl -------------------------------------------------------------------------------- /controller/src/preload.ts: -------------------------------------------------------------------------------- 1 | // See the Electron documentation for details on how to use preload scripts: 2 | // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts 3 | -------------------------------------------------------------------------------- /controller/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | easy-esc-stm32f103-mt6701-ncp81155 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /controller/src/app.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from "react-dom/client"; 2 | import { Home } from "./Home"; 3 | 4 | function render() { 5 | const root = createRoot(document.getElementById("app")); 6 | root.render(); 7 | } 8 | 9 | render(); 10 | -------------------------------------------------------------------------------- /hardware/assembly/stm32f103-bottom-pos.csv: -------------------------------------------------------------------------------- 1 | Ref,Val,Package,PosX,PosY,Rot,Side 2 | "J201","MOTOR","PinHeader_1x03_P1.27mm_Vertical",145.935600,-82.307000,90.000000,bottom 3 | "J202","FPC","FPC-SMD_3P-P1.00_HDGC_1.0K-LS-3PWB-BOTTOMCONTACT",153.530200,-81.697400,180.000000,bottom 4 | -------------------------------------------------------------------------------- /controller/README.md: -------------------------------------------------------------------------------- 1 | # Controller UI 2 | 3 | ## Run locally 4 | 5 | ```sh 6 | # Install the Yarn dependency manager using NPM 7 | npm install --global yarn 8 | 9 | # Navigate to the controller folder 10 | cd ./controller 11 | 12 | # Install dependencies 13 | yarn 14 | 15 | # Run development server 16 | yarn start 17 | ``` 18 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /controller/webpack.plugins.ts: -------------------------------------------------------------------------------- 1 | import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-var-requires 4 | const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | export const plugins = [ 7 | new ForkTsCheckerWebpackPlugin({ 8 | logger: 'webpack-infrastructure', 9 | }), 10 | ]; 11 | -------------------------------------------------------------------------------- /controller/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended", 11 | "plugin:import/recommended", 12 | "plugin:import/electron", 13 | "plugin:import/typescript" 14 | ], 15 | "parser": "@typescript-eslint/parser" 16 | } 17 | -------------------------------------------------------------------------------- /controller/webpack.renderer.config.ts: -------------------------------------------------------------------------------- 1 | import type { Configuration } from 'webpack'; 2 | 3 | import { rules } from './webpack.rules'; 4 | import { plugins } from './webpack.plugins'; 5 | 6 | rules.push({ 7 | test: /\.css$/, 8 | use: [{ loader: 'style-loader' }, { loader: 'css-loader' }], 9 | }); 10 | 11 | export const rendererConfig: Configuration = { 12 | module: { 13 | rules, 14 | }, 15 | plugins, 16 | resolve: { 17 | extensions: ['.js', '.ts', '.jsx', '.tsx', '.css'], 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /controller/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "allowJs": true, 5 | "module": "commonjs", 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "noImplicitAny": true, 9 | "sourceMap": true, 10 | "baseUrl": ".", 11 | "outDir": "dist", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "paths": { 15 | "*": ["node_modules/*"] 16 | }, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src/**/*"] 20 | } 21 | -------------------------------------------------------------------------------- /controller/webpack.main.config.ts: -------------------------------------------------------------------------------- 1 | import type { Configuration } from 'webpack'; 2 | 3 | import { rules } from './webpack.rules'; 4 | 5 | export const mainConfig: Configuration = { 6 | /** 7 | * This is the main entry point for your application, it's the first file 8 | * that runs in the main process. 9 | */ 10 | entry: './src/index.ts', 11 | // Put your normal webpack config below here 12 | module: { 13 | rules, 14 | }, 15 | resolve: { 16 | extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.json'], 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /firmware/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # easy-esc-stm32f103-mt6701-ncp81155 2 | 3 | Small, closed loop simpleFOC driver board, that can be assembled for <$10 with mostly basic components at LCSC. has support for current sensing and mounting WS2812 RGBLED for indicating, as well as USB C for serial communication and programming. SWD + UART via STLINK 14 pin connector. 4 | 5 | The targe for this project was to create an all-in-one simpleFOC board with high resolution magnetic encoder, current sensing, simpleFOC BLDC driver board which can be assembled with top-side only components, 2 layers, mostly basic components from LCSC library, and which can be powered entirely from USB 2.0 specification (500mA) for mostly use with haptic texture type applications. Additionally, it has a compact size of 38x38mm. 6 | 7 | ![3D render of PCB](/easy-esc.jpg) 8 | -------------------------------------------------------------------------------- /controller/webpack.rules.ts: -------------------------------------------------------------------------------- 1 | import type { ModuleOptions } from 'webpack'; 2 | 3 | export const rules: Required['rules'] = [ 4 | // Add support for native node modules 5 | { 6 | // We're specifying native_modules in the test because the asset relocator loader generates a 7 | // "fake" .node file which is really a cjs file. 8 | test: /native_modules[/\\].+\.node$/, 9 | use: 'node-loader', 10 | }, 11 | { 12 | test: /[/\\]node_modules[/\\].+\.(m?js|node)$/, 13 | parser: { amd: false }, 14 | use: { 15 | loader: '@vercel/webpack-asset-relocator-loader', 16 | options: { 17 | outputAssetBase: 'native_modules', 18 | }, 19 | }, 20 | }, 21 | { 22 | test: /\.tsx?$/, 23 | exclude: /(node_modules|\.webpack)/, 24 | use: { 25 | loader: 'ts-loader', 26 | options: { 27 | transpileOnly: true, 28 | }, 29 | }, 30 | }, 31 | ]; 32 | -------------------------------------------------------------------------------- /controller/src/renderer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file will automatically be loaded by webpack and run in the "renderer" context. 3 | * To learn more about the differences between the "main" and the "renderer" context in 4 | * Electron, visit: 5 | * 6 | * https://electronjs.org/docs/latest/tutorial/process-model 7 | * 8 | * By default, Node.js integration in this file is disabled. When enabling Node.js integration 9 | * in a renderer process, please be aware of potential security implications. You can read 10 | * more about security risks here: 11 | * 12 | * https://electronjs.org/docs/tutorial/security 13 | * 14 | * To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration` 15 | * flag: 16 | * 17 | * ``` 18 | * // Create the browser window. 19 | * mainWindow = new BrowserWindow({ 20 | * width: 800, 21 | * height: 600, 22 | * webPreferences: { 23 | * nodeIntegration: true 24 | * } 25 | * }); 26 | * ``` 27 | */ 28 | 29 | import "./app"; 30 | -------------------------------------------------------------------------------- /firmware/include/stm32f1xxMT6071_NCP81155.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // encoder interface 4 | #define ENC_A PC13 5 | #define ENC_B PC14 6 | #define ENC_Z PC15 7 | 8 | #define ENC_PUSH PB1 9 | #define ENC_MODE PB0 10 | #define ENC_I2C_EN PB2 11 | 12 | // mosfet driver pins 13 | // allow for dir switch to match encoder on build flag MOTOR_CW 14 | 15 | #define PWM_U PA9 16 | #define EN_U PB14 17 | #define PWM_V PA8 18 | #define EN_V PB13 19 | #define PWM_W PA10 20 | #define EN_W PB15 21 | 22 | // current sensing pins 23 | #define CUR_U PA1 24 | #define CUR_V PA0 25 | #define CUR_W PA4 26 | 27 | // ws2812E 28 | #define RGB_LED PA15 29 | 30 | // SPI1 31 | #define SPI1_MOSI PA7 32 | #define SPI1_MISO PA6 33 | #define SPI1_SCLK PA5 34 | 35 | // UART1 36 | #define UART1_TX PB6 37 | #define UART1_RX PB7 38 | 39 | // CANBUS1 40 | #define CAN_TX PB9 41 | #define CAN_RX PB8 42 | 43 | // I2C2 44 | #define I2C2_SDA PB11 45 | #define I2C2_SCL PB10 46 | 47 | // UART2 48 | #define UART2_TX PA2 49 | #define UART2_RX PA3 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /hardware/assembly/stm32f103-BOM.csv: -------------------------------------------------------------------------------- 1 | Comment,Designator,Footprint,LCSC 2 | 5K,"R102,R101",0402_R, 3 | 22R,"R106,R107",0402_R, 4 | 1uF,"C206,C201,C210,C107,C106",0402_C, 5 | WS2812,D101,SMD_5050, 6 | 0R,"R209,R207,R223,R203,R201,R217,R213,R202,R113,R220,R218,R208,R112,R214,R110,R109",0402_R, 7 | NCP81155,"U205,U201,U206",DFN-8_3x3mm,C173765 8 | 0.1uF,"C101,C212,C218,C211,C109,C111,C110,C108",0402_C, 9 | 1N5819WS,"D201,D202,D203",D_SOD-323,C191023 10 | 22R,"R215,R216,R221",1206_R, 11 | 47pF,"C105,C104",0402_C, 12 | 10k,"R219,R108,R103,R222",0402_R, 13 | RESET,SW101,TS-1187A-B-A-B,C318884 14 | LT199,"U204,U203,U202",SOT-363_SC-70-6,C2888104 15 | 10uF,"C214,C215",0402_C, 16 | AO3400A,"Q201,Q205,Q203,Q202,Q101,Q206,Q204",SOT-23,C20917 17 | 470nF,"C222,C205,C223",0402_C, 18 | 5.1k,"R105,R104",0402_R, 19 | 20pF,"C102,C103",0402_C, 20 | 12MHz,Y101,Crystal_SMD_3225, 21 | HIROSE TYPE C ,J101,HRO_TYPE-C-31-M-12,C165948 22 | 100uF,"C221,C220,C213",1206_C, 23 | STM32F103,U103,LQFP-48_7x7mm,C8734 24 | XC6206,U102,SOT-23,C5446 25 | B5819W SL,D204,D_SOD-123,C8598 26 | MT6701,U101,QFN-16-1EP_3x3mm,C2913974 -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = easyesc_stm32f1xx_MT6701_NCP81155 13 | src_dir = firmware/src 14 | lib_dir = firmware/lib 15 | include_dir = firmware/include 16 | test_dir = firmware/test 17 | 18 | [env:easyesc_stm32f1xx_MT6701_NCP81155] 19 | platform = ststm32@~15.6.0 20 | board = genericSTM32F103C8 21 | framework = arduino 22 | monitor_speed = 115200 23 | upload_protocol = stlink 24 | debug_tool = stlink 25 | lib_deps = 26 | askuric/Simple FOC@^2.3.0 27 | 28 | lib_archive = false 29 | build_flags = 30 | -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC 31 | -D USBCON 32 | -D HAS_MONITOR 33 | -D MT6701_I2C 34 | -D HAL_QSPI_MODULE_DISABLED 35 | -D HAL_RTC_MODULE_DISABLED 36 | -D HAL_DAC_MODULE_DISABLED 37 | -D HAL_ETH_MODULE_DISABLED 38 | -D HAL_SD_MODULE_DISABLED 39 | -flto 40 | -------------------------------------------------------------------------------- /firmware/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /controller/forge.config.ts: -------------------------------------------------------------------------------- 1 | import type { ForgeConfig } from '@electron-forge/shared-types'; 2 | import { MakerSquirrel } from '@electron-forge/maker-squirrel'; 3 | import { MakerZIP } from '@electron-forge/maker-zip'; 4 | import { MakerDeb } from '@electron-forge/maker-deb'; 5 | import { MakerRpm } from '@electron-forge/maker-rpm'; 6 | import { AutoUnpackNativesPlugin } from '@electron-forge/plugin-auto-unpack-natives'; 7 | import { WebpackPlugin } from '@electron-forge/plugin-webpack'; 8 | 9 | import { mainConfig } from './webpack.main.config'; 10 | import { rendererConfig } from './webpack.renderer.config'; 11 | 12 | const config: ForgeConfig = { 13 | packagerConfig: { 14 | asar: true, 15 | }, 16 | rebuildConfig: {}, 17 | makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})], 18 | plugins: [ 19 | new AutoUnpackNativesPlugin({}), 20 | new WebpackPlugin({ 21 | mainConfig, 22 | renderer: { 23 | config: rendererConfig, 24 | entryPoints: [ 25 | { 26 | html: './src/index.html', 27 | js: './src/renderer.ts', 28 | name: 'main_window', 29 | preload: { 30 | js: './src/preload.ts', 31 | }, 32 | }, 33 | ], 34 | }, 35 | }), 36 | ], 37 | }; 38 | 39 | export default config; 40 | -------------------------------------------------------------------------------- /firmware/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /hardware/stm32f103.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "All Layers", 5 | "auto_track_width": true, 6 | "hidden_netclasses": [], 7 | "hidden_nets": [], 8 | "high_contrast_mode": 0, 9 | "net_color_mode": 1, 10 | "opacity": { 11 | "images": 0.6, 12 | "pads": 0.6200000047683716, 13 | "tracks": 1.0, 14 | "vias": 1.0, 15 | "zones": 0.6 16 | }, 17 | "selection_filter": { 18 | "dimensions": true, 19 | "footprints": true, 20 | "graphics": true, 21 | "keepouts": true, 22 | "lockedItems": false, 23 | "otherItems": true, 24 | "pads": true, 25 | "text": true, 26 | "tracks": true, 27 | "vias": true, 28 | "zones": true 29 | }, 30 | "visible_items": [ 31 | 0, 32 | 1, 33 | 2, 34 | 3, 35 | 4, 36 | 5, 37 | 8, 38 | 9, 39 | 10, 40 | 11, 41 | 12, 42 | 13, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36, 64 | 39, 65 | 40 66 | ], 67 | "visible_layers": "fffffff_ffffffff", 68 | "zone_display_mode": 0 69 | }, 70 | "meta": { 71 | "filename": "stm32f103.kicad_prl", 72 | "version": 3 73 | }, 74 | "project": { 75 | "files": [] 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /controller/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | .DS_Store 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # TypeScript cache 43 | *.tsbuildinfo 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | .env.test 63 | 64 | # parcel-bundler cache (https://parceljs.org/) 65 | .cache 66 | 67 | # next.js build output 68 | .next 69 | 70 | # nuxt.js build output 71 | .nuxt 72 | 73 | # vuepress build output 74 | .vuepress/dist 75 | 76 | # Serverless directories 77 | .serverless/ 78 | 79 | # FuseBox cache 80 | .fusebox/ 81 | 82 | # DynamoDB Local files 83 | .dynamodb/ 84 | 85 | # Webpack 86 | .webpack/ 87 | 88 | # Vite 89 | .vite/ 90 | 91 | # Electron-Forge 92 | out/ -------------------------------------------------------------------------------- /controller/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "controller", 3 | "productName": "controller", 4 | "version": "1.0.0", 5 | "description": "My Electron application description", 6 | "main": ".webpack/main", 7 | "scripts": { 8 | "start": "electron-forge start", 9 | "package": "electron-forge package", 10 | "make": "electron-forge make", 11 | "publish": "electron-forge publish", 12 | "lint": "eslint --ext .ts,.tsx ." 13 | }, 14 | "keywords": [], 15 | "license": "MIT", 16 | "devDependencies": { 17 | "@electron-forge/cli": "^6.2.1", 18 | "@electron-forge/maker-deb": "^6.2.1", 19 | "@electron-forge/maker-rpm": "^6.2.1", 20 | "@electron-forge/maker-squirrel": "^6.2.1", 21 | "@electron-forge/maker-zip": "^6.2.1", 22 | "@electron-forge/plugin-auto-unpack-natives": "^6.2.1", 23 | "@electron-forge/plugin-webpack": "^6.2.1", 24 | "@types/dom-serial": "^1.0.3", 25 | "@types/react": "^18.2.14", 26 | "@types/react-dom": "^18.2.6", 27 | "@typescript-eslint/eslint-plugin": "^5.0.0", 28 | "@typescript-eslint/parser": "^5.0.0", 29 | "@vercel/webpack-asset-relocator-loader": "1.7.3", 30 | "css-loader": "^6.0.0", 31 | "electron": "25.2.0", 32 | "eslint": "^8.0.1", 33 | "eslint-plugin-import": "^2.25.0", 34 | "fork-ts-checker-webpack-plugin": "^7.2.13", 35 | "node-loader": "^2.0.0", 36 | "style-loader": "^3.0.0", 37 | "ts-loader": "^9.2.2", 38 | "ts-node": "^10.0.0", 39 | "typescript": "~4.5.4" 40 | }, 41 | "dependencies": { 42 | "electron-squirrel-startup": "^1.0.0", 43 | "react": "^18.2.0", 44 | "react-dom": "^18.2.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /firmware/src/clock.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * @brief System Clock Configuration 5 | * @retval None 6 | */ 7 | void SystemClock_Config(void) 8 | { 9 | RCC_OscInitTypeDef RCC_OscInitStruct = {}; 10 | RCC_ClkInitTypeDef RCC_ClkInitStruct = {}; 11 | RCC_PeriphCLKInitTypeDef PeriphClkInit = {}; 12 | 13 | /** Initializes the RCC Oscillators according to the specified parameters 14 | * in the RCC_OscInitTypeDef structure. 15 | */ 16 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 17 | RCC_OscInitStruct.HSEState = RCC_HSE_ON; 18 | RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; 19 | RCC_OscInitStruct.HSIState = RCC_HSI_ON; 20 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 21 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 22 | RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4; 23 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 24 | { 25 | Error_Handler(); 26 | } 27 | 28 | /** Initializes the CPU, AHB and APB buses clocks 29 | */ 30 | RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 31 | |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; 32 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 33 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2; 34 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; 35 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 36 | 37 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) 38 | { 39 | Error_Handler(); 40 | } 41 | PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_USB; 42 | PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2; 43 | PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; 44 | if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) 45 | { 46 | Error_Handler(); 47 | } 48 | } -------------------------------------------------------------------------------- /firmware/lib/MT6701/MT6701_I2C.h: -------------------------------------------------------------------------------- 1 | #ifndef MT6701_I2C_H 2 | #define MT6701_I2C_H 3 | 4 | #include "Arduino.h" 5 | #include "SimpleFOC.h" 6 | // #include "SimpleFOCDrivers.h" 7 | #include 8 | 9 | struct MT6701_I2CConfig_s { 10 | int chip_address; 11 | int bit_resolution; 12 | int angle_register; 13 | int data_start_bit; 14 | }; 15 | // some predefined structures 16 | 17 | #if defined(TARGET_RP2040) 18 | #define SDA I2C_SDA 19 | #define SCL I2C_SCL 20 | #endif 21 | 22 | 23 | class MT6701_Serial_I2C: public Sensor{ 24 | public: 25 | /** 26 | * MagneticSensorI2C class constructor 27 | * @param chip_address I2C chip address 28 | * @param bits number of bits of the sensor resolution 29 | * @param angle_register_msb angle read register msb 30 | * @param _bits_used_msb number of used bits in msb 31 | */ 32 | MT6701_Serial_I2C(uint8_t _chip_address, int _bit_resolution, uint8_t _angle_register_msb, int _msb_bits_used); 33 | 34 | /** 35 | * MagneticSensorI2C class constructor 36 | * @param config I2C config 37 | */ 38 | MT6701_Serial_I2C(MT6701_I2CConfig_s config); 39 | 40 | /** sensor initialise pins */ 41 | void init(TwoWire* _wire = &Wire); 42 | 43 | // implementation of abstract functions of the Sensor class 44 | /** get current angle (rad) */ 45 | float getSensorAngle() override; 46 | 47 | /** experimental function to check and fix SDA locked LOW issues */ 48 | int checkBus(byte sda_pin , byte scl_pin ); 49 | 50 | int getRawCount(); 51 | 52 | int readRegister(uint8_t reg_addr, byte data_len_bits, byte start_bit); 53 | 54 | private: 55 | float cpr; //!< Maximum range of the magnetic sensor 56 | uint16_t lsb_used; //!< Number of bits used in LSB register 57 | uint8_t lsb_mask; 58 | uint8_t msb_mask; 59 | 60 | // I2C variables 61 | uint8_t angle_register_msb; //!< I2C angle register to read 62 | uint8_t chip_address; //!< I2C chip select pins 63 | 64 | // I2C functions 65 | /** Read one I2C register value */ 66 | int read(uint8_t angle_register_msb); 67 | 68 | /** 69 | * Function getting current angle register value 70 | * it uses angle_register variable 71 | */ 72 | // int getRawCount(); 73 | 74 | /* the two wire instance for this sensor */ 75 | TwoWire* wire; 76 | 77 | 78 | }; 79 | 80 | 81 | #endif -------------------------------------------------------------------------------- /controller/src/Home.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from "react"; 2 | 3 | const baudRate = 115200; 4 | 5 | export const Home = () => { 6 | const [ports, setPorts] = useState([]); 7 | const [connectedPort, setConnectedPort] = useState(null); 8 | const [serialOutput, setSerialOutput] = useState(""); 9 | const reader = useRef>(); 10 | const readableStreamClosed = useRef>(); 11 | 12 | const changePort = async (port?: SerialPort) => { 13 | if (connectedPort) { 14 | try { 15 | reader.current.cancel(); 16 | await readableStreamClosed.current.catch(() => { 17 | /* Ignore the error */ 18 | }); 19 | await connectedPort.close(); 20 | setConnectedPort(null); 21 | console.log("closed port"); 22 | } catch (e) { 23 | console.log(e); 24 | } 25 | } 26 | 27 | if (port) { 28 | await port.open({ 29 | baudRate, 30 | }); 31 | console.log("opened port"); 32 | setConnectedPort(port); 33 | 34 | const decoder = new TextDecoderStream(); 35 | readableStreamClosed.current = port.readable.pipeTo(decoder.writable); 36 | reader.current = decoder.readable.getReader(); 37 | while (true) { 38 | const { value, done } = await reader.current.read(); 39 | if (value) { 40 | setSerialOutput((serialOutput) => serialOutput + value); 41 | } 42 | if (done) { 43 | console.log("[readLoop] DONE", done); 44 | reader.current.releaseLock(); 45 | break; 46 | } 47 | } 48 | } 49 | }; 50 | 51 | useEffect(() => { 52 | navigator.serial.getPorts().then((ports) => setPorts(ports)); 53 | }, []); 54 | 55 | return ( 56 | <> 57 |

Controller

58 | Ports:{" "} 59 | 73 |
74 |

Output

75 | {serialOutput.split("\n").map((line) => ( 76 |
77 | {line} 78 |
79 | ))} 80 |
81 | 82 | ); 83 | }; 84 | -------------------------------------------------------------------------------- /firmware/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "MT6701_I2C.h" 4 | #include "stm32f1xxMT6071_NCP81155.h" 5 | 6 | // Motor specific parameters 7 | #define POLEPAIRS 4 8 | #define RPHASE 0.7 9 | #define MOTOR_KV 1000 10 | 11 | #ifdef MT6701_I2C 12 | MT6701_I2CConfig_s mt6701_config = { 13 | .chip_address = 0b0000110, 14 | .bit_resolution = 14, 15 | .angle_register = 0x03, 16 | .data_start_bit = 8}; 17 | MT6701_Serial_I2C mt6701 = MT6701_Serial_I2C(mt6701_config); 18 | TwoWire enc_i2c(I2C2_SDA, I2C2_SCL); 19 | #endif 20 | 21 | // Prepare SimpleFOC constructors. 22 | BLDCDriver3PWM driver = BLDCDriver3PWM(PWM_U, PWM_V, PWM_W, EN_U, EN_V, EN_W); 23 | BLDCMotor motor = BLDCMotor(POLEPAIRS,RPHASE,MOTOR_KV); 24 | Commander commander = Commander(Serial); 25 | 26 | void doMotor(char *cmd){ 27 | commander.motor(&motor,cmd); 28 | } 29 | 30 | void mt6701_i2c_enable(bool state) 31 | { 32 | digitalWrite(ENC_MODE, state); 33 | digitalWrite(ENC_I2C_EN, state); 34 | } 35 | 36 | void setup(){ 37 | Serial.begin(); 38 | commander.add('M',doMotor,"motor"); 39 | 40 | #ifdef SIMPLEFOC_STM32_DEBUG 41 | SimpleFOCDebug::enable(&Serial); 42 | #endif 43 | 44 | pinMode(ENC_MODE, OUTPUT); 45 | pinMode(ENC_I2C_EN, OUTPUT); 46 | 47 | #ifdef MT6701_I2C 48 | // set the MT6701 to Serial mode 49 | mt6701_i2c_enable(1); 50 | delay(1000); // let chip settle 51 | mt6701.init(&enc_i2c); 52 | motor.linkSensor(&mt6701); 53 | #endif 54 | 55 | // setup the driver 56 | driver.pwm_frequency = 25000; 57 | driver.voltage_power_supply = 5; 58 | driver.voltage_limit = 3; 59 | driver.init(); 60 | motor.linkDriver(&driver); 61 | 62 | // closed loop parameters 63 | motor.PID_velocity.P = 0.3; 64 | motor.PID_velocity.I = 20; 65 | motor.PID_velocity.D = 0.003; 66 | motor.PID_velocity.output_ramp = 50; 67 | motor.LPF_velocity.Tf = 0.2; 68 | motor.LPF_angle.Tf = 0; // try to avoid 69 | 70 | // motor parameters 71 | motor.voltage_sensor_align = 2; 72 | motor.current_limit = 0.8; 73 | motor.velocity_limit = 50; 74 | motor.controller = MotionControlType::angle; 75 | 76 | motor.init(); 77 | motor.initFOC(); 78 | 79 | // Monitor initialization 80 | #ifdef HAS_MONITOR 81 | motor.useMonitoring(Serial); 82 | motor.monitor_start_char = 'M'; 83 | motor.monitor_end_char = 'M'; 84 | motor.monitor_downsample = 200; 85 | commander.verbose = VerboseMode::machine_readable; 86 | #endif 87 | 88 | motor.target = 2; 89 | } 90 | 91 | void loop() 92 | { 93 | motor.loopFOC(); 94 | motor.move(); 95 | 96 | commander.run(); 97 | 98 | #ifdef HAS_MONITOR 99 | motor.monitor(); 100 | #endif 101 | } -------------------------------------------------------------------------------- /hardware/assembly/stm32f103-top-pos.csv: -------------------------------------------------------------------------------- 1 | Designator,Mid X,Mid Y,Layer,Rotation 2 | C101,150.6092,-96.8866,T ,90 3 | C102,167.0684,-85.5836,T ,0 4 | C103,163.2076,-87.0568,T ,90 5 | C104,162.4456,-106.3374,T ,0 6 | C105,160.5406,-106.3374,T ,180 7 | C106,154.1906,-108.3166,T ,180 8 | C107,154.1906,-107.326,T ,180 9 | C108,169.9894,-91.4002,T ,90 10 | C109,160.693,-87.0568,T ,90 11 | C110,160.3374,-101.202,T ,-90 12 | C111,167.3758,-101.1792,T ,180 13 | C201,150.6092,-98.8424,T ,-90 14 | C202,144.3496,-91.5428,T ,180 15 | C203,144.4004,-98.93275,T ,180 16 | C204,144.4746,-106.2592,T ,180 17 | C205,138.4086,-90.984,T ,180 18 | C206,153.706,-102.5308,T ,180 19 | C207,144.3496,-87.682,T ,180 20 | C208,144.3869,-94.99575,T ,180 21 | C209,144.4492,-102.373,T ,180 22 | C210,152.381,-105.5058,T ,-90 23 | C211,152.8374,-93.60275,T ,180 24 | C212,149.9392,-93.59005,T ,180 25 | C213,144.2592,-111.4662,T ,-90 26 | C214,138.4934,-101.357,T ,180 27 | C215,138.4426,-93.9656,T ,180 28 | C216,152.8374,-89.25935,T ,180 29 | C217,149.9418,-89.22125,T ,180 30 | C218,155.7226,-93.6113,T ,180 31 | C219,155.7226,-89.2679,T ,180 32 | C220,146.4944,-87.1058,T ,-90 33 | C221,142.9638,-85.9646,T ,0 34 | C222,138.5468,-105.675,T ,180 35 | C223,138.4706,-98.2582,T ,180 36 | D101,148.3742,-112.951,T ,90 37 | D201,138.4426,-88.818,T ,90 38 | D202,138.468,-96.1078,T ,90 39 | D203,138.5442,-103.4992,T ,90 40 | D204,141.8716,-111.4146,T ,-90 41 | J101,160.8454,-114.1332,T ,0 42 | J102,169.9132,-108.0118,T ,180 43 | J104,137.2234,-108.0238,T ,90 44 | Q101,157.8505,-100.3918,T ,0 45 | Q201,141.386,-92.3744,T ,180 46 | Q202,141.4444,-99.73575,T ,180 47 | Q203,141.4932,-107.0876,T ,180 48 | Q204,141.386,-88.9012,T ,180 49 | Q205,141.4309,-96.23015,T ,180 50 | Q206,141.4932,-103.5922,T ,180 51 | R101,157.9244,-94.626,T ,180 52 | R102,157.9244,-93.61,T ,180 53 | R103,161.7344,-87.0568,T ,90 54 | R104,159.55,-107.834,T ,90 55 | R105,162.6742,-107.834,T ,90 56 | R106,160.5914,-107.832,T ,90 57 | R107,161.6328,-107.836,T ,90 58 | R108,168.567,-86.0408,T ,90 59 | R109,170.8022,-96.8104,T ,180 60 | R110,170.8022,-95.7944,T ,0 61 | R112,157.9244,-98.1058,T ,0 62 | R113,157.9244,-97.0898,T ,0 63 | R201,144.3496,-93.6002,T ,180 64 | R202,144.4004,-100.96575,T ,180 65 | R203,144.4746,-108.3176,T ,180 66 | R204,144.3496,-92.5588,T ,180 67 | R205,144.4004,-99.94875,T ,180 68 | R206,144.4746,-107.2752,T ,180 69 | R207,144.3496,-89.7394,T ,180 70 | R208,144.3869,-97.02775,T ,180 71 | R209,144.4746,-104.4558,T ,180 72 | R210,144.3496,-88.698,T ,180 73 | R211,144.3869,-96.01175,T ,180 74 | R212,144.4746,-103.389,T ,180 75 | R213,153.2692,-87.76075,T ,-90 76 | R214,150.3736,-87.72065,T ,-90 77 | R215,152.7682,-84.3644,T ,-45 78 | R216,149.4408,-84.3136,T ,-45 79 | R217,152.2532,-87.75875,T ,-90 80 | R218,149.3322,-87.72465,T ,-90 81 | R219,149.9692,-94.63145,T ,180 82 | R220,156.1544,-87.7693,T ,-90 83 | R221,156.0448,-84.3644,T ,-45 84 | R222,148.4686,-94.04725,T ,90 85 | R223,155.113,-87.7713,T ,-90 86 | SW101,162.3186,-83.4246,T ,180 87 | U101,153.581,-98.1058,T ,90 88 | U102,157.0862,-107.0618,T ,180 89 | U103,164.2713,-95.3826,T ,-90 90 | U201,148.247,-98.309,T ,90 91 | U202,152.3468,-91.42725,T ,90 92 | U203,149.4512,-91.41455,T ,90 93 | U204,155.232,-91.4358,T ,90 94 | U205,149.7202,-103.1096,T ,180 95 | U206,149.7202,-107.2244,T ,180 96 | Y101,165.8746,-87.8442,T ,180 -------------------------------------------------------------------------------- /controller/src/index.ts: -------------------------------------------------------------------------------- 1 | import { app, BrowserWindow } from "electron"; 2 | // This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Webpack 3 | // plugin that tells the Electron app where to look for the Webpack-bundled app code (depending on 4 | // whether you're running in development or production). 5 | declare const MAIN_WINDOW_WEBPACK_ENTRY: string; 6 | declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string; 7 | 8 | // Handle creating/removing shortcuts on Windows when installing/uninstalling. 9 | if (require("electron-squirrel-startup")) { 10 | app.quit(); 11 | } 12 | 13 | const setupSerialDevice = (mainWindow: BrowserWindow) => { 14 | mainWindow.webContents.session.on( 15 | "select-serial-port", 16 | (event, portList, webContents, callback) => { 17 | // Add listeners to handle ports being added or removed before the callback for `select-serial-port` 18 | // is called. 19 | mainWindow.webContents.session.on("serial-port-added", (event, port) => { 20 | console.log("serial-port-added FIRED WITH", port); 21 | // Optionally update portList to add the new port 22 | }); 23 | 24 | mainWindow.webContents.session.on( 25 | "serial-port-removed", 26 | (event, port) => { 27 | console.log("serial-port-removed FIRED WITH", port); 28 | // Optionally update portList to remove the port 29 | } 30 | ); 31 | 32 | event.preventDefault(); 33 | } 34 | ); 35 | 36 | mainWindow.webContents.session.setPermissionCheckHandler( 37 | (webContents, permission, requestingOrigin, details) => { 38 | return true; 39 | // if (permission === "serial" && details.securityOrigin === "file:///") { 40 | // return true; 41 | // } 42 | 43 | // return false; 44 | } 45 | ); 46 | 47 | mainWindow.webContents.session.setDevicePermissionHandler((details) => { 48 | return true; 49 | 50 | // if (details.deviceType === "serial" && details.origin === "file://") { 51 | // return true; 52 | // } 53 | 54 | // return false; 55 | }); 56 | }; 57 | 58 | const createWindow = (): void => { 59 | // Create the browser window. 60 | const mainWindow = new BrowserWindow({ 61 | height: 600, 62 | width: 800, 63 | webPreferences: { 64 | preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY, 65 | }, 66 | }); 67 | 68 | setupSerialDevice(mainWindow); 69 | 70 | // and load the index.html of the app. 71 | mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY); 72 | 73 | // Open the DevTools. 74 | mainWindow.webContents.openDevTools(); 75 | }; 76 | 77 | // This method will be called when Electron has finished 78 | // initialization and is ready to create browser windows. 79 | // Some APIs can only be used after this event occurs. 80 | app.on("ready", createWindow); 81 | 82 | // Quit when all windows are closed, except on macOS. There, it's common 83 | // for applications and their menu bar to stay active until the user quits 84 | // explicitly with Cmd + Q. 85 | app.on("window-all-closed", () => { 86 | if (process.platform !== "darwin") { 87 | app.quit(); 88 | } 89 | }); 90 | 91 | app.on("activate", () => { 92 | // On OS X it's common to re-create a window in the app when the 93 | // dock icon is clicked and there are no other windows open. 94 | if (BrowserWindow.getAllWindows().length === 0) { 95 | createWindow(); 96 | } 97 | }); 98 | 99 | // In this file you can include the rest of your app's specific main process 100 | // code. You can also put them in separate files and import them here. 101 | -------------------------------------------------------------------------------- /firmware/lib/MT6701/MT6701_I2C.cpp: -------------------------------------------------------------------------------- 1 | #include "MT6701_I2C.h" 2 | 3 | // MagneticSensorI2C(uint8_t _chip_address, float _cpr, uint8_t _angle_register_msb) 4 | // @param _chip_address I2C chip address 5 | // @param _bit_resolution bit resolution of the sensor 6 | // @param _angle_register_msb angle read register 7 | // @param _bits_used_msb number of used bits in msb 8 | MT6701_Serial_I2C::MT6701_Serial_I2C(uint8_t _chip_address, int _bit_resolution, uint8_t _angle_register_msb, int _bits_used_msb){ 9 | // chip I2C address 10 | chip_address = _chip_address; 11 | // angle read register of the magnetic sensor 12 | angle_register_msb = _angle_register_msb; 13 | // register maximum value (counts per revolution) 14 | cpr = pow(2, _bit_resolution); 15 | 16 | // depending on the sensor architecture there are different combinations of 17 | // LSB and MSB register used bits 18 | // AS5600 uses 0..7 LSB and 8..11 MSB 19 | // AS5048 uses 0..5 LSB and 6..13 MSB 20 | // used bits in LSB 21 | lsb_used = _bit_resolution - _bits_used_msb; 22 | // extraction masks 23 | lsb_mask = (uint8_t)( (2 << lsb_used) - 1 ); 24 | msb_mask = (uint8_t)( (2 << _bits_used_msb) - 1 ); 25 | wire = &Wire; 26 | } 27 | 28 | MT6701_Serial_I2C::MT6701_Serial_I2C(MT6701_I2CConfig_s config){ 29 | chip_address = config.chip_address; 30 | 31 | // angle read register of the magnetic sensor 32 | angle_register_msb = config.angle_register; 33 | // register maximum value (counts per revolution) 34 | cpr = pow(2, config.bit_resolution); 35 | 36 | int bits_used_msb = config.data_start_bit - 7; 37 | lsb_used = config.bit_resolution - bits_used_msb; 38 | // extraction masks 39 | lsb_mask = (uint8_t)( (2 << lsb_used) - 1 ); 40 | msb_mask = (uint8_t)( (2 << bits_used_msb) - 1 ); 41 | wire = &Wire; 42 | } 43 | 44 | void MT6701_Serial_I2C::init(TwoWire* _wire){ 45 | 46 | wire = _wire; 47 | 48 | // I2C communication begin 49 | wire->begin(); 50 | 51 | this->Sensor::init(); // call base class init 52 | } 53 | 54 | // Shaft angle calculation 55 | // angle is in radians [rad] 56 | float MT6701_Serial_I2C::getSensorAngle(){ 57 | // (number of full rotations)*2PI + current sensor angle 58 | return ( getRawCount() / (float)cpr) * _2PI ; 59 | } 60 | 61 | 62 | 63 | // function reading the raw counter of the magnetic sensor 64 | int MT6701_Serial_I2C::getRawCount(){ 65 | return (int)MT6701_Serial_I2C::read(angle_register_msb); 66 | } 67 | 68 | // I2C functions 69 | /* 70 | * Read a register from the sensor 71 | * Takes the address of the register as a uint8_t 72 | * Returns the value of the register 73 | */ 74 | int MT6701_Serial_I2C::read(uint8_t angle_reg_msb) { 75 | // read the angle register first MSB then LSB 76 | byte angle_raw[2]; 77 | uint16_t readValue = 0; 78 | wire->beginTransmission(chip_address); 79 | wire->write(angle_reg_msb); 80 | wire->endTransmission(false); 81 | wire->requestFrom(chip_address, (uint8_t)2); 82 | 83 | for(byte i=0; i<2; i++){ 84 | // Read the two sequential registers 85 | angle_raw[i] = wire->read(); 86 | } 87 | 88 | // Stack the upper and lower bits 89 | readValue = angle_raw[0] << 8; 90 | readValue = (readValue | angle_raw[1]) >> 2; 91 | return readValue; 92 | } 93 | 94 | /** 95 | * Read a specific register and return the value at the address. 96 | */ 97 | int MT6701_Serial_I2C::readRegister(uint8_t reg_addr, byte data_len_bits, byte start_bit) { 98 | byte reg_data; 99 | uint16_t readValue = 0; 100 | wire->beginTransmission(chip_address); 101 | wire->write(reg_addr); 102 | wire->endTransmission(false); 103 | 104 | wire->requestFrom(chip_address, (uint8_t)1); 105 | 106 | reg_data = wire->read(); 107 | 108 | readValue = reg_data; 109 | return readValue; 110 | } 111 | /* 112 | * Checks whether other devices have locked the bus. Can clear SDA locks. 113 | * This should be called before sensor.init() on devices that suffer i2c slaves locking sda 114 | * e.g some stm32 boards with AS5600 chips 115 | * Takes the sda_pin and scl_pin 116 | * Returns 0 for OK, 1 for other master and 2 for unfixable sda locked LOW 117 | */ 118 | int MT6701_Serial_I2C::checkBus(byte sda_pin, byte scl_pin) { 119 | 120 | pinMode(scl_pin, INPUT_PULLUP); 121 | pinMode(sda_pin, INPUT_PULLUP); 122 | delay(250); 123 | 124 | if (digitalRead(scl_pin) == LOW) { 125 | // Someone else has claimed master!"); 126 | return 1; 127 | } 128 | 129 | if(digitalRead(sda_pin) == LOW) { 130 | // slave is communicating and awaiting clocks, we are blocked 131 | pinMode(scl_pin, OUTPUT); 132 | for (byte i = 0; i < 16; i++) { 133 | // toggle clock for 2 bytes of data 134 | digitalWrite(scl_pin, LOW); 135 | delayMicroseconds(20); 136 | digitalWrite(scl_pin, HIGH); 137 | delayMicroseconds(20); 138 | } 139 | pinMode(sda_pin, INPUT); 140 | delayMicroseconds(20); 141 | if (digitalRead(sda_pin) == LOW) { 142 | // SDA still blocked 143 | return 2; 144 | } 145 | _delay(1000); 146 | } 147 | // SDA is clear (HIGH) 148 | pinMode(sda_pin, INPUT); 149 | pinMode(scl_pin, INPUT); 150 | 151 | return 0; 152 | } -------------------------------------------------------------------------------- /hardware/stm32f103.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "3dviewports": [], 4 | "design_settings": { 5 | "defaults": { 6 | "board_outline_line_width": 0.09999999999999999, 7 | "copper_line_width": 0.19999999999999998, 8 | "copper_text_italic": false, 9 | "copper_text_size_h": 1.5, 10 | "copper_text_size_v": 1.5, 11 | "copper_text_thickness": 0.3, 12 | "copper_text_upright": false, 13 | "courtyard_line_width": 0.049999999999999996, 14 | "dimension_precision": 4, 15 | "dimension_units": 3, 16 | "dimensions": { 17 | "arrow_length": 1270000, 18 | "extension_offset": 500000, 19 | "keep_text_aligned": true, 20 | "suppress_zeroes": false, 21 | "text_position": 0, 22 | "units_format": 1 23 | }, 24 | "fab_line_width": 0.09999999999999999, 25 | "fab_text_italic": false, 26 | "fab_text_size_h": 1.0, 27 | "fab_text_size_v": 1.0, 28 | "fab_text_thickness": 0.15, 29 | "fab_text_upright": false, 30 | "other_line_width": 0.15, 31 | "other_text_italic": false, 32 | "other_text_size_h": 1.0, 33 | "other_text_size_v": 1.0, 34 | "other_text_thickness": 0.15, 35 | "other_text_upright": false, 36 | "pads": { 37 | "drill": 0.762, 38 | "height": 1.524, 39 | "width": 1.524 40 | }, 41 | "silk_line_width": 0.15, 42 | "silk_text_italic": false, 43 | "silk_text_size_h": 1.0, 44 | "silk_text_size_v": 1.0, 45 | "silk_text_thickness": 0.15, 46 | "silk_text_upright": false, 47 | "zones": { 48 | "min_clearance": 0.5 49 | } 50 | }, 51 | "diff_pair_dimensions": [ 52 | { 53 | "gap": 0.0, 54 | "via_gap": 0.0, 55 | "width": 0.0 56 | } 57 | ], 58 | "drc_exclusions": [], 59 | "meta": { 60 | "version": 2 61 | }, 62 | "rule_severities": { 63 | "annular_width": "error", 64 | "clearance": "error", 65 | "connection_width": "warning", 66 | "copper_edge_clearance": "error", 67 | "copper_sliver": "warning", 68 | "courtyards_overlap": "ignore", 69 | "diff_pair_gap_out_of_range": "error", 70 | "diff_pair_uncoupled_length_too_long": "error", 71 | "drill_out_of_range": "error", 72 | "duplicate_footprints": "warning", 73 | "extra_footprint": "warning", 74 | "footprint": "error", 75 | "footprint_type_mismatch": "ignore", 76 | "hole_clearance": "error", 77 | "hole_near_hole": "error", 78 | "invalid_outline": "error", 79 | "isolated_copper": "warning", 80 | "item_on_disabled_layer": "error", 81 | "items_not_allowed": "error", 82 | "length_out_of_range": "error", 83 | "lib_footprint_issues": "warning", 84 | "lib_footprint_mismatch": "warning", 85 | "malformed_courtyard": "error", 86 | "microvia_drill_out_of_range": "error", 87 | "missing_courtyard": "ignore", 88 | "missing_footprint": "warning", 89 | "net_conflict": "warning", 90 | "npth_inside_courtyard": "ignore", 91 | "padstack": "warning", 92 | "pth_inside_courtyard": "ignore", 93 | "shorting_items": "error", 94 | "silk_edge_clearance": "ignore", 95 | "silk_over_copper": "warning", 96 | "silk_overlap": "ignore", 97 | "skew_out_of_range": "error", 98 | "solder_mask_bridge": "error", 99 | "starved_thermal": "error", 100 | "text_height": "warning", 101 | "text_thickness": "warning", 102 | "through_hole_pad_without_hole": "error", 103 | "too_many_vias": "error", 104 | "track_dangling": "warning", 105 | "track_width": "error", 106 | "tracks_crossing": "error", 107 | "unconnected_items": "error", 108 | "unresolved_variable": "error", 109 | "via_dangling": "warning", 110 | "zones_intersect": "error" 111 | }, 112 | "rules": { 113 | "max_error": 0.005, 114 | "min_clearance": 0.0, 115 | "min_connection": 0.0, 116 | "min_copper_edge_clearance": 0.0, 117 | "min_hole_clearance": 0.25, 118 | "min_hole_to_hole": 0.25, 119 | "min_microvia_diameter": 0.19999999999999998, 120 | "min_microvia_drill": 0.09999999999999999, 121 | "min_resolved_spokes": 1, 122 | "min_silk_clearance": 0.0, 123 | "min_text_height": 0.7999999999999999, 124 | "min_text_thickness": 0.08, 125 | "min_through_hole_diameter": 0.3, 126 | "min_track_width": 0.0, 127 | "min_via_annular_width": 0.09999999999999999, 128 | "min_via_diameter": 0.5, 129 | "solder_mask_clearance": 0.0, 130 | "solder_mask_min_width": 0.0, 131 | "solder_mask_to_copper_clearance": 0.0, 132 | "use_height_for_length_calcs": true 133 | }, 134 | "teardrop_options": [ 135 | { 136 | "td_allow_use_two_tracks": true, 137 | "td_curve_segcount": 5, 138 | "td_on_pad_in_zone": false, 139 | "td_onpadsmd": true, 140 | "td_onroundshapesonly": false, 141 | "td_ontrackend": false, 142 | "td_onviapad": true 143 | } 144 | ], 145 | "teardrop_parameters": [ 146 | { 147 | "td_curve_segcount": 0, 148 | "td_height_ratio": 1.0, 149 | "td_length_ratio": 0.5, 150 | "td_maxheight": 2.0, 151 | "td_maxlen": 1.0, 152 | "td_target_name": "td_round_shape", 153 | "td_width_to_size_filter_ratio": 0.9 154 | }, 155 | { 156 | "td_curve_segcount": 0, 157 | "td_height_ratio": 1.0, 158 | "td_length_ratio": 0.5, 159 | "td_maxheight": 2.0, 160 | "td_maxlen": 1.0, 161 | "td_target_name": "td_rect_shape", 162 | "td_width_to_size_filter_ratio": 0.9 163 | }, 164 | { 165 | "td_curve_segcount": 0, 166 | "td_height_ratio": 1.0, 167 | "td_length_ratio": 0.5, 168 | "td_maxheight": 2.0, 169 | "td_maxlen": 1.0, 170 | "td_target_name": "td_track_end", 171 | "td_width_to_size_filter_ratio": 0.9 172 | } 173 | ], 174 | "track_widths": [ 175 | 0.0, 176 | 0.3, 177 | 0.5, 178 | 0.75, 179 | 1.0 180 | ], 181 | "via_dimensions": [ 182 | { 183 | "diameter": 0.0, 184 | "drill": 0.0 185 | } 186 | ], 187 | "zones_allow_external_fillets": true 188 | }, 189 | "layer_presets": [], 190 | "viewports": [] 191 | }, 192 | "boards": [], 193 | "cvpcb": { 194 | "equivalence_files": [] 195 | }, 196 | "erc": { 197 | "erc_exclusions": [], 198 | "meta": { 199 | "version": 0 200 | }, 201 | "pin_map": [ 202 | [ 203 | 0, 204 | 0, 205 | 0, 206 | 0, 207 | 0, 208 | 0, 209 | 1, 210 | 0, 211 | 0, 212 | 0, 213 | 0, 214 | 2 215 | ], 216 | [ 217 | 0, 218 | 2, 219 | 0, 220 | 1, 221 | 0, 222 | 0, 223 | 1, 224 | 0, 225 | 2, 226 | 2, 227 | 2, 228 | 2 229 | ], 230 | [ 231 | 0, 232 | 0, 233 | 0, 234 | 0, 235 | 0, 236 | 0, 237 | 1, 238 | 0, 239 | 1, 240 | 0, 241 | 1, 242 | 2 243 | ], 244 | [ 245 | 0, 246 | 1, 247 | 0, 248 | 0, 249 | 0, 250 | 0, 251 | 1, 252 | 1, 253 | 2, 254 | 1, 255 | 1, 256 | 2 257 | ], 258 | [ 259 | 0, 260 | 0, 261 | 0, 262 | 0, 263 | 0, 264 | 0, 265 | 1, 266 | 0, 267 | 0, 268 | 0, 269 | 0, 270 | 2 271 | ], 272 | [ 273 | 0, 274 | 0, 275 | 0, 276 | 0, 277 | 0, 278 | 0, 279 | 0, 280 | 0, 281 | 0, 282 | 0, 283 | 0, 284 | 2 285 | ], 286 | [ 287 | 1, 288 | 1, 289 | 1, 290 | 1, 291 | 1, 292 | 0, 293 | 1, 294 | 1, 295 | 1, 296 | 1, 297 | 1, 298 | 2 299 | ], 300 | [ 301 | 0, 302 | 0, 303 | 0, 304 | 1, 305 | 0, 306 | 0, 307 | 1, 308 | 0, 309 | 0, 310 | 0, 311 | 0, 312 | 2 313 | ], 314 | [ 315 | 0, 316 | 2, 317 | 1, 318 | 2, 319 | 0, 320 | 0, 321 | 1, 322 | 0, 323 | 2, 324 | 2, 325 | 2, 326 | 2 327 | ], 328 | [ 329 | 0, 330 | 2, 331 | 0, 332 | 1, 333 | 0, 334 | 0, 335 | 1, 336 | 0, 337 | 2, 338 | 0, 339 | 0, 340 | 2 341 | ], 342 | [ 343 | 0, 344 | 2, 345 | 1, 346 | 1, 347 | 0, 348 | 0, 349 | 1, 350 | 0, 351 | 2, 352 | 0, 353 | 0, 354 | 2 355 | ], 356 | [ 357 | 2, 358 | 2, 359 | 2, 360 | 2, 361 | 2, 362 | 2, 363 | 2, 364 | 2, 365 | 2, 366 | 2, 367 | 2, 368 | 2 369 | ] 370 | ], 371 | "rule_severities": { 372 | "bus_definition_conflict": "error", 373 | "bus_entry_needed": "error", 374 | "bus_to_bus_conflict": "error", 375 | "bus_to_net_conflict": "error", 376 | "conflicting_netclasses": "error", 377 | "different_unit_footprint": "error", 378 | "different_unit_net": "error", 379 | "duplicate_reference": "error", 380 | "duplicate_sheet_names": "error", 381 | "endpoint_off_grid": "warning", 382 | "extra_units": "error", 383 | "global_label_dangling": "warning", 384 | "hier_label_mismatch": "error", 385 | "label_dangling": "error", 386 | "lib_symbol_issues": "warning", 387 | "missing_bidi_pin": "warning", 388 | "missing_input_pin": "warning", 389 | "missing_power_pin": "error", 390 | "missing_unit": "warning", 391 | "multiple_net_names": "warning", 392 | "net_not_bus_member": "warning", 393 | "no_connect_connected": "warning", 394 | "no_connect_dangling": "warning", 395 | "pin_not_connected": "error", 396 | "pin_not_driven": "error", 397 | "pin_to_pin": "warning", 398 | "power_pin_not_driven": "error", 399 | "similar_labels": "warning", 400 | "simulation_model_issue": "error", 401 | "unannotated": "error", 402 | "unit_value_mismatch": "error", 403 | "unresolved_variable": "error", 404 | "wire_dangling": "error" 405 | } 406 | }, 407 | "libraries": { 408 | "pinned_footprint_libs": [], 409 | "pinned_symbol_libs": [] 410 | }, 411 | "meta": { 412 | "filename": "stm32f103.kicad_pro", 413 | "version": 1 414 | }, 415 | "net_settings": { 416 | "classes": [ 417 | { 418 | "bus_width": 12, 419 | "clearance": 0.2, 420 | "diff_pair_gap": 0.25, 421 | "diff_pair_via_gap": 0.25, 422 | "diff_pair_width": 0.2, 423 | "line_style": 0, 424 | "microvia_diameter": 0.3, 425 | "microvia_drill": 0.1, 426 | "name": "Default", 427 | "pcb_color": "rgba(0, 0, 0, 0.000)", 428 | "schematic_color": "rgba(0, 0, 0, 0.000)", 429 | "track_width": 0.25, 430 | "via_diameter": 0.8, 431 | "via_drill": 0.4, 432 | "wire_width": 6 433 | } 434 | ], 435 | "meta": { 436 | "version": 3 437 | }, 438 | "net_colors": null, 439 | "netclass_assignments": null, 440 | "netclass_patterns": [] 441 | }, 442 | "pcbnew": { 443 | "last_paths": { 444 | "gencad": "", 445 | "idf": "", 446 | "netlist": "", 447 | "specctra_dsn": "", 448 | "step": "stm32f103.step", 449 | "vrml": "" 450 | }, 451 | "page_layout_descr_file": "" 452 | }, 453 | "schematic": { 454 | "annotate_start_num": 0, 455 | "drawing": { 456 | "dashed_lines_dash_length_ratio": 12.0, 457 | "dashed_lines_gap_length_ratio": 3.0, 458 | "default_line_thickness": 6.0, 459 | "default_text_size": 50.0, 460 | "field_names": [], 461 | "intersheets_ref_own_page": false, 462 | "intersheets_ref_prefix": "", 463 | "intersheets_ref_short": false, 464 | "intersheets_ref_show": false, 465 | "intersheets_ref_suffix": "", 466 | "junction_size_choice": 3, 467 | "label_size_ratio": 0.375, 468 | "operating_point_overlay_i_precision": 3, 469 | "operating_point_overlay_i_range": "~A", 470 | "operating_point_overlay_v_precision": 3, 471 | "operating_point_overlay_v_range": "~V", 472 | "pin_symbol_size": 25.0, 473 | "text_offset_ratio": 0.15 474 | }, 475 | "legacy_lib_dir": "", 476 | "legacy_lib_list": [], 477 | "meta": { 478 | "version": 1 479 | }, 480 | "net_format_name": "", 481 | "page_layout_descr_file": "", 482 | "plot_directory": "", 483 | "spice_current_sheet_as_root": false, 484 | "spice_external_command": "spice \"%I\"", 485 | "spice_model_current_sheet_as_root": true, 486 | "spice_save_all_currents": false, 487 | "spice_save_all_dissipations": false, 488 | "spice_save_all_voltages": false, 489 | "subpart_first_id": 65, 490 | "subpart_id_separator": 0 491 | }, 492 | "sheets": [ 493 | [ 494 | "a2811dd7-4266-496a-832b-7a7f6af8583e", 495 | "" 496 | ], 497 | [ 498 | "17dbf9dd-18e6-4e1a-9835-ecd5b9028b5a", 499 | "MOTOR STAGE" 500 | ] 501 | ], 502 | "text_variables": {} 503 | } 504 | -------------------------------------------------------------------------------- /mechanical/aliexpress-motor.step: -------------------------------------------------------------------------------- 1 | ISO-10303-21; 2 | HEADER; 3 | FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); 4 | FILE_NAME('Open CASCADE Shape Model','2023-04-03T18:58:35',('Author'),( 5 | ''),'Open CASCADE STEP processor 7.5','FreeCAD','Unknown'); 6 | FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); 7 | ENDSEC; 8 | DATA; 9 | #1 = APPLICATION_PROTOCOL_DEFINITION('international standard', 10 | 'automotive_design',2000,#2); 11 | #2 = APPLICATION_CONTEXT( 12 | 'core data for automotive mechanical design processes'); 13 | #3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); 14 | #4 = PRODUCT_DEFINITION_SHAPE('','',#5); 15 | #5 = PRODUCT_DEFINITION('design','',#6,#9); 16 | #6 = PRODUCT_DEFINITION_FORMATION('','',#7); 17 | #7 = PRODUCT('BLDC','BLDC','',(#8)); 18 | #8 = PRODUCT_CONTEXT('',#2,'mechanical'); 19 | #9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); 20 | #10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#512); 21 | #11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); 22 | #12 = CARTESIAN_POINT('',(0.,0.,0.)); 23 | #13 = DIRECTION('',(0.,0.,1.)); 24 | #14 = DIRECTION('',(1.,0.,-0.)); 25 | #15 = MANIFOLD_SOLID_BREP('',#16); 26 | #16 = CLOSED_SHELL('',(#17,#50,#114,#178,#203,#228,#253,#278,#303,#328, 27 | #353,#378,#403,#428,#437,#446,#458,#467,#476,#485,#494,#503)); 28 | #17 = ADVANCED_FACE('',(#18),#45,.T.); 29 | #18 = FACE_BOUND('',#19,.F.); 30 | #19 = EDGE_LOOP('',(#20,#30,#37,#38)); 31 | #20 = ORIENTED_EDGE('',*,*,#21,.T.); 32 | #21 = EDGE_CURVE('',#22,#24,#26,.T.); 33 | #22 = VERTEX_POINT('',#23); 34 | #23 = CARTESIAN_POINT('',(17.25,0.,0.)); 35 | #24 = VERTEX_POINT('',#25); 36 | #25 = CARTESIAN_POINT('',(17.25,0.,15.)); 37 | #26 = LINE('',#27,#28); 38 | #27 = CARTESIAN_POINT('',(17.25,0.,0.)); 39 | #28 = VECTOR('',#29,1.); 40 | #29 = DIRECTION('',(0.,0.,1.)); 41 | #30 = ORIENTED_EDGE('',*,*,#31,.T.); 42 | #31 = EDGE_CURVE('',#24,#24,#32,.T.); 43 | #32 = CIRCLE('',#33,17.25); 44 | #33 = AXIS2_PLACEMENT_3D('',#34,#35,#36); 45 | #34 = CARTESIAN_POINT('',(0.,0.,15.)); 46 | #35 = DIRECTION('',(0.,0.,1.)); 47 | #36 = DIRECTION('',(1.,0.,0.)); 48 | #37 = ORIENTED_EDGE('',*,*,#21,.F.); 49 | #38 = ORIENTED_EDGE('',*,*,#39,.F.); 50 | #39 = EDGE_CURVE('',#22,#22,#40,.T.); 51 | #40 = CIRCLE('',#41,17.25); 52 | #41 = AXIS2_PLACEMENT_3D('',#42,#43,#44); 53 | #42 = CARTESIAN_POINT('',(0.,0.,0.)); 54 | #43 = DIRECTION('',(0.,0.,1.)); 55 | #44 = DIRECTION('',(1.,0.,0.)); 56 | #45 = CYLINDRICAL_SURFACE('',#46,17.25); 57 | #46 = AXIS2_PLACEMENT_3D('',#47,#48,#49); 58 | #47 = CARTESIAN_POINT('',(0.,0.,0.)); 59 | #48 = DIRECTION('',(-0.,-0.,-1.)); 60 | #49 = DIRECTION('',(1.,0.,0.)); 61 | #50 = ADVANCED_FACE('',(#51,#54,#65,#76,#87,#98),#109,.F.); 62 | #51 = FACE_BOUND('',#52,.F.); 63 | #52 = EDGE_LOOP('',(#53)); 64 | #53 = ORIENTED_EDGE('',*,*,#39,.T.); 65 | #54 = FACE_BOUND('',#55,.F.); 66 | #55 = EDGE_LOOP('',(#56)); 67 | #56 = ORIENTED_EDGE('',*,*,#57,.T.); 68 | #57 = EDGE_CURVE('',#58,#58,#60,.T.); 69 | #58 = VERTEX_POINT('',#59); 70 | #59 = CARTESIAN_POINT('',(-8.25,-5.8533E-11,0.)); 71 | #60 = CIRCLE('',#61,1.25); 72 | #61 = AXIS2_PLACEMENT_3D('',#62,#63,#64); 73 | #62 = CARTESIAN_POINT('',(-9.5,-5.853273E-11,0.)); 74 | #63 = DIRECTION('',(0.,0.,-1.)); 75 | #64 = DIRECTION('',(1.,0.,0.)); 76 | #65 = FACE_BOUND('',#66,.F.); 77 | #66 = EDGE_LOOP('',(#67)); 78 | #67 = ORIENTED_EDGE('',*,*,#68,.T.); 79 | #68 = EDGE_CURVE('',#69,#69,#71,.T.); 80 | #69 = VERTEX_POINT('',#70); 81 | #70 = CARTESIAN_POINT('',(1.25,-9.5,0.)); 82 | #71 = CIRCLE('',#72,1.25); 83 | #72 = AXIS2_PLACEMENT_3D('',#73,#74,#75); 84 | #73 = CARTESIAN_POINT('',(0.,-9.5,0.)); 85 | #74 = DIRECTION('',(0.,0.,-1.)); 86 | #75 = DIRECTION('',(1.,0.,0.)); 87 | #76 = FACE_BOUND('',#77,.F.); 88 | #77 = EDGE_LOOP('',(#78)); 89 | #78 = ORIENTED_EDGE('',*,*,#79,.T.); 90 | #79 = EDGE_CURVE('',#80,#80,#82,.T.); 91 | #80 = VERTEX_POINT('',#81); 92 | #81 = CARTESIAN_POINT('',(6.,0.,0.)); 93 | #82 = CIRCLE('',#83,6.); 94 | #83 = AXIS2_PLACEMENT_3D('',#84,#85,#86); 95 | #84 = CARTESIAN_POINT('',(0.,0.,0.)); 96 | #85 = DIRECTION('',(0.,0.,-1.)); 97 | #86 = DIRECTION('',(1.,0.,0.)); 98 | #87 = FACE_BOUND('',#88,.F.); 99 | #88 = EDGE_LOOP('',(#89)); 100 | #89 = ORIENTED_EDGE('',*,*,#90,.T.); 101 | #90 = EDGE_CURVE('',#91,#91,#93,.T.); 102 | #91 = VERTEX_POINT('',#92); 103 | #92 = CARTESIAN_POINT('',(10.75,5.635E-11,0.)); 104 | #93 = CIRCLE('',#94,1.25); 105 | #94 = AXIS2_PLACEMENT_3D('',#95,#96,#97); 106 | #95 = CARTESIAN_POINT('',(9.5,5.634959E-11,0.)); 107 | #96 = DIRECTION('',(0.,0.,-1.)); 108 | #97 = DIRECTION('',(1.,0.,0.)); 109 | #98 = FACE_BOUND('',#99,.F.); 110 | #99 = EDGE_LOOP('',(#100)); 111 | #100 = ORIENTED_EDGE('',*,*,#101,.T.); 112 | #101 = EDGE_CURVE('',#102,#102,#104,.T.); 113 | #102 = VERTEX_POINT('',#103); 114 | #103 = CARTESIAN_POINT('',(1.250000000002,9.5,0.)); 115 | #104 = CIRCLE('',#105,1.25); 116 | #105 = AXIS2_PLACEMENT_3D('',#106,#107,#108); 117 | #106 = CARTESIAN_POINT('',(2.18492E-12,9.5,0.)); 118 | #107 = DIRECTION('',(0.,0.,-1.)); 119 | #108 = DIRECTION('',(1.,0.,0.)); 120 | #109 = PLANE('',#110); 121 | #110 = AXIS2_PLACEMENT_3D('',#111,#112,#113); 122 | #111 = CARTESIAN_POINT('',(-6.3E-16,5.6E-16,0.)); 123 | #112 = DIRECTION('',(0.,0.,1.)); 124 | #113 = DIRECTION('',(1.,0.,0.)); 125 | #114 = ADVANCED_FACE('',(#115,#118,#129,#140,#151,#162),#173,.T.); 126 | #115 = FACE_BOUND('',#116,.T.); 127 | #116 = EDGE_LOOP('',(#117)); 128 | #117 = ORIENTED_EDGE('',*,*,#31,.T.); 129 | #118 = FACE_BOUND('',#119,.T.); 130 | #119 = EDGE_LOOP('',(#120)); 131 | #120 = ORIENTED_EDGE('',*,*,#121,.F.); 132 | #121 = EDGE_CURVE('',#122,#122,#124,.T.); 133 | #122 = VERTEX_POINT('',#123); 134 | #123 = CARTESIAN_POINT('',(1.25,-7.5,15.)); 135 | #124 = CIRCLE('',#125,1.25); 136 | #125 = AXIS2_PLACEMENT_3D('',#126,#127,#128); 137 | #126 = CARTESIAN_POINT('',(8.9E-16,-7.5,15.)); 138 | #127 = DIRECTION('',(0.,0.,1.)); 139 | #128 = DIRECTION('',(1.,0.,0.)); 140 | #129 = FACE_BOUND('',#130,.T.); 141 | #130 = EDGE_LOOP('',(#131)); 142 | #131 = ORIENTED_EDGE('',*,*,#132,.F.); 143 | #132 = EDGE_CURVE('',#133,#133,#135,.T.); 144 | #133 = VERTEX_POINT('',#134); 145 | #134 = CARTESIAN_POINT('',(8.75,-1.E-15,15.)); 146 | #135 = CIRCLE('',#136,1.25); 147 | #136 = AXIS2_PLACEMENT_3D('',#137,#138,#139); 148 | #137 = CARTESIAN_POINT('',(7.5,-8.9E-16,15.)); 149 | #138 = DIRECTION('',(0.,0.,1.)); 150 | #139 = DIRECTION('',(1.,0.,0.)); 151 | #140 = FACE_BOUND('',#141,.T.); 152 | #141 = EDGE_LOOP('',(#142)); 153 | #142 = ORIENTED_EDGE('',*,*,#143,.F.); 154 | #143 = EDGE_CURVE('',#144,#144,#146,.T.); 155 | #144 = VERTEX_POINT('',#145); 156 | #145 = CARTESIAN_POINT('',(-6.25,1.E-15,15.)); 157 | #146 = CIRCLE('',#147,1.25); 158 | #147 = AXIS2_PLACEMENT_3D('',#148,#149,#150); 159 | #148 = CARTESIAN_POINT('',(-7.5,8.9E-16,15.)); 160 | #149 = DIRECTION('',(0.,0.,1.)); 161 | #150 = DIRECTION('',(1.,0.,0.)); 162 | #151 = FACE_BOUND('',#152,.T.); 163 | #152 = EDGE_LOOP('',(#153)); 164 | #153 = ORIENTED_EDGE('',*,*,#154,.T.); 165 | #154 = EDGE_CURVE('',#155,#155,#157,.T.); 166 | #155 = VERTEX_POINT('',#156); 167 | #156 = CARTESIAN_POINT('',(2.75,0.,15.)); 168 | #157 = CIRCLE('',#158,2.75); 169 | #158 = AXIS2_PLACEMENT_3D('',#159,#160,#161); 170 | #159 = CARTESIAN_POINT('',(0.,0.,15.)); 171 | #160 = DIRECTION('',(0.,0.,-1.)); 172 | #161 = DIRECTION('',(1.,0.,0.)); 173 | #162 = FACE_BOUND('',#163,.T.); 174 | #163 = EDGE_LOOP('',(#164)); 175 | #164 = ORIENTED_EDGE('',*,*,#165,.F.); 176 | #165 = EDGE_CURVE('',#166,#166,#168,.T.); 177 | #166 = VERTEX_POINT('',#167); 178 | #167 = CARTESIAN_POINT('',(1.25,7.5,15.)); 179 | #168 = CIRCLE('',#169,1.25); 180 | #169 = AXIS2_PLACEMENT_3D('',#170,#171,#172); 181 | #170 = CARTESIAN_POINT('',(0.,7.5,15.)); 182 | #171 = DIRECTION('',(0.,0.,1.)); 183 | #172 = DIRECTION('',(1.,0.,0.)); 184 | #173 = PLANE('',#174); 185 | #174 = AXIS2_PLACEMENT_3D('',#175,#176,#177); 186 | #175 = CARTESIAN_POINT('',(-6.3E-16,5.6E-16,15.)); 187 | #176 = DIRECTION('',(0.,0.,1.)); 188 | #177 = DIRECTION('',(1.,0.,0.)); 189 | #178 = ADVANCED_FACE('',(#179),#198,.F.); 190 | #179 = FACE_BOUND('',#180,.F.); 191 | #180 = EDGE_LOOP('',(#181,#189,#196,#197)); 192 | #181 = ORIENTED_EDGE('',*,*,#182,.T.); 193 | #182 = EDGE_CURVE('',#58,#183,#185,.T.); 194 | #183 = VERTEX_POINT('',#184); 195 | #184 = CARTESIAN_POINT('',(-8.25,-5.8533E-11,5.)); 196 | #185 = LINE('',#186,#187); 197 | #186 = CARTESIAN_POINT('',(-8.25,-5.853273E-11,0.)); 198 | #187 = VECTOR('',#188,1.); 199 | #188 = DIRECTION('',(0.,0.,1.)); 200 | #189 = ORIENTED_EDGE('',*,*,#190,.T.); 201 | #190 = EDGE_CURVE('',#183,#183,#191,.T.); 202 | #191 = CIRCLE('',#192,1.25); 203 | #192 = AXIS2_PLACEMENT_3D('',#193,#194,#195); 204 | #193 = CARTESIAN_POINT('',(-9.5,-5.853273E-11,5.)); 205 | #194 = DIRECTION('',(0.,0.,-1.)); 206 | #195 = DIRECTION('',(1.,0.,0.)); 207 | #196 = ORIENTED_EDGE('',*,*,#182,.F.); 208 | #197 = ORIENTED_EDGE('',*,*,#57,.F.); 209 | #198 = CYLINDRICAL_SURFACE('',#199,1.25); 210 | #199 = AXIS2_PLACEMENT_3D('',#200,#201,#202); 211 | #200 = CARTESIAN_POINT('',(-9.5,-5.853273E-11,0.)); 212 | #201 = DIRECTION('',(0.,0.,-1.)); 213 | #202 = DIRECTION('',(1.,0.,0.)); 214 | #203 = ADVANCED_FACE('',(#204),#223,.F.); 215 | #204 = FACE_BOUND('',#205,.F.); 216 | #205 = EDGE_LOOP('',(#206,#214,#221,#222)); 217 | #206 = ORIENTED_EDGE('',*,*,#207,.T.); 218 | #207 = EDGE_CURVE('',#69,#208,#210,.T.); 219 | #208 = VERTEX_POINT('',#209); 220 | #209 = CARTESIAN_POINT('',(1.25,-9.5,5.)); 221 | #210 = LINE('',#211,#212); 222 | #211 = CARTESIAN_POINT('',(1.25,-9.5,0.)); 223 | #212 = VECTOR('',#213,1.); 224 | #213 = DIRECTION('',(0.,0.,1.)); 225 | #214 = ORIENTED_EDGE('',*,*,#215,.T.); 226 | #215 = EDGE_CURVE('',#208,#208,#216,.T.); 227 | #216 = CIRCLE('',#217,1.25); 228 | #217 = AXIS2_PLACEMENT_3D('',#218,#219,#220); 229 | #218 = CARTESIAN_POINT('',(0.,-9.5,5.)); 230 | #219 = DIRECTION('',(0.,0.,-1.)); 231 | #220 = DIRECTION('',(1.,0.,0.)); 232 | #221 = ORIENTED_EDGE('',*,*,#207,.F.); 233 | #222 = ORIENTED_EDGE('',*,*,#68,.F.); 234 | #223 = CYLINDRICAL_SURFACE('',#224,1.25); 235 | #224 = AXIS2_PLACEMENT_3D('',#225,#226,#227); 236 | #225 = CARTESIAN_POINT('',(0.,-9.5,0.)); 237 | #226 = DIRECTION('',(0.,0.,-1.)); 238 | #227 = DIRECTION('',(1.,0.,0.)); 239 | #228 = ADVANCED_FACE('',(#229),#248,.T.); 240 | #229 = FACE_BOUND('',#230,.F.); 241 | #230 = EDGE_LOOP('',(#231,#239,#246,#247)); 242 | #231 = ORIENTED_EDGE('',*,*,#232,.T.); 243 | #232 = EDGE_CURVE('',#80,#233,#235,.T.); 244 | #233 = VERTEX_POINT('',#234); 245 | #234 = CARTESIAN_POINT('',(6.,0.,-10.)); 246 | #235 = LINE('',#236,#237); 247 | #236 = CARTESIAN_POINT('',(6.,0.,0.)); 248 | #237 = VECTOR('',#238,1.); 249 | #238 = DIRECTION('',(0.,0.,-1.)); 250 | #239 = ORIENTED_EDGE('',*,*,#240,.T.); 251 | #240 = EDGE_CURVE('',#233,#233,#241,.T.); 252 | #241 = CIRCLE('',#242,6.); 253 | #242 = AXIS2_PLACEMENT_3D('',#243,#244,#245); 254 | #243 = CARTESIAN_POINT('',(0.,0.,-10.)); 255 | #244 = DIRECTION('',(0.,0.,-1.)); 256 | #245 = DIRECTION('',(1.,0.,0.)); 257 | #246 = ORIENTED_EDGE('',*,*,#232,.F.); 258 | #247 = ORIENTED_EDGE('',*,*,#79,.F.); 259 | #248 = CYLINDRICAL_SURFACE('',#249,6.); 260 | #249 = AXIS2_PLACEMENT_3D('',#250,#251,#252); 261 | #250 = CARTESIAN_POINT('',(0.,0.,0.)); 262 | #251 = DIRECTION('',(0.,0.,1.)); 263 | #252 = DIRECTION('',(1.,0.,0.)); 264 | #253 = ADVANCED_FACE('',(#254),#273,.F.); 265 | #254 = FACE_BOUND('',#255,.F.); 266 | #255 = EDGE_LOOP('',(#256,#264,#271,#272)); 267 | #256 = ORIENTED_EDGE('',*,*,#257,.T.); 268 | #257 = EDGE_CURVE('',#91,#258,#260,.T.); 269 | #258 = VERTEX_POINT('',#259); 270 | #259 = CARTESIAN_POINT('',(10.75,5.635E-11,5.)); 271 | #260 = LINE('',#261,#262); 272 | #261 = CARTESIAN_POINT('',(10.75,5.634959E-11,0.)); 273 | #262 = VECTOR('',#263,1.); 274 | #263 = DIRECTION('',(0.,0.,1.)); 275 | #264 = ORIENTED_EDGE('',*,*,#265,.T.); 276 | #265 = EDGE_CURVE('',#258,#258,#266,.T.); 277 | #266 = CIRCLE('',#267,1.25); 278 | #267 = AXIS2_PLACEMENT_3D('',#268,#269,#270); 279 | #268 = CARTESIAN_POINT('',(9.5,5.634959E-11,5.)); 280 | #269 = DIRECTION('',(0.,0.,-1.)); 281 | #270 = DIRECTION('',(1.,0.,0.)); 282 | #271 = ORIENTED_EDGE('',*,*,#257,.F.); 283 | #272 = ORIENTED_EDGE('',*,*,#90,.F.); 284 | #273 = CYLINDRICAL_SURFACE('',#274,1.25); 285 | #274 = AXIS2_PLACEMENT_3D('',#275,#276,#277); 286 | #275 = CARTESIAN_POINT('',(9.5,5.634959E-11,0.)); 287 | #276 = DIRECTION('',(0.,0.,-1.)); 288 | #277 = DIRECTION('',(1.,0.,0.)); 289 | #278 = ADVANCED_FACE('',(#279),#298,.F.); 290 | #279 = FACE_BOUND('',#280,.F.); 291 | #280 = EDGE_LOOP('',(#281,#289,#296,#297)); 292 | #281 = ORIENTED_EDGE('',*,*,#282,.T.); 293 | #282 = EDGE_CURVE('',#102,#283,#285,.T.); 294 | #283 = VERTEX_POINT('',#284); 295 | #284 = CARTESIAN_POINT('',(1.250000000002,9.5,5.)); 296 | #285 = LINE('',#286,#287); 297 | #286 = CARTESIAN_POINT('',(1.250000000002,9.5,0.)); 298 | #287 = VECTOR('',#288,1.); 299 | #288 = DIRECTION('',(0.,0.,1.)); 300 | #289 = ORIENTED_EDGE('',*,*,#290,.T.); 301 | #290 = EDGE_CURVE('',#283,#283,#291,.T.); 302 | #291 = CIRCLE('',#292,1.25); 303 | #292 = AXIS2_PLACEMENT_3D('',#293,#294,#295); 304 | #293 = CARTESIAN_POINT('',(2.18492E-12,9.5,5.)); 305 | #294 = DIRECTION('',(0.,0.,-1.)); 306 | #295 = DIRECTION('',(1.,0.,0.)); 307 | #296 = ORIENTED_EDGE('',*,*,#282,.F.); 308 | #297 = ORIENTED_EDGE('',*,*,#101,.F.); 309 | #298 = CYLINDRICAL_SURFACE('',#299,1.25); 310 | #299 = AXIS2_PLACEMENT_3D('',#300,#301,#302); 311 | #300 = CARTESIAN_POINT('',(2.18492E-12,9.5,0.)); 312 | #301 = DIRECTION('',(0.,0.,-1.)); 313 | #302 = DIRECTION('',(1.,0.,0.)); 314 | #303 = ADVANCED_FACE('',(#304),#323,.F.); 315 | #304 = FACE_BOUND('',#305,.F.); 316 | #305 = EDGE_LOOP('',(#306,#314,#321,#322)); 317 | #306 = ORIENTED_EDGE('',*,*,#307,.T.); 318 | #307 = EDGE_CURVE('',#122,#308,#310,.T.); 319 | #308 = VERTEX_POINT('',#309); 320 | #309 = CARTESIAN_POINT('',(1.25,-7.5,10.)); 321 | #310 = LINE('',#311,#312); 322 | #311 = CARTESIAN_POINT('',(1.25,-7.5,15.)); 323 | #312 = VECTOR('',#313,1.); 324 | #313 = DIRECTION('',(-0.,-0.,-1.)); 325 | #314 = ORIENTED_EDGE('',*,*,#315,.T.); 326 | #315 = EDGE_CURVE('',#308,#308,#316,.T.); 327 | #316 = CIRCLE('',#317,1.25); 328 | #317 = AXIS2_PLACEMENT_3D('',#318,#319,#320); 329 | #318 = CARTESIAN_POINT('',(8.9E-16,-7.5,10.)); 330 | #319 = DIRECTION('',(0.,0.,1.)); 331 | #320 = DIRECTION('',(1.,0.,0.)); 332 | #321 = ORIENTED_EDGE('',*,*,#307,.F.); 333 | #322 = ORIENTED_EDGE('',*,*,#121,.F.); 334 | #323 = CYLINDRICAL_SURFACE('',#324,1.25); 335 | #324 = AXIS2_PLACEMENT_3D('',#325,#326,#327); 336 | #325 = CARTESIAN_POINT('',(8.9E-16,-7.5,15.)); 337 | #326 = DIRECTION('',(0.,0.,1.)); 338 | #327 = DIRECTION('',(1.,0.,-0.)); 339 | #328 = ADVANCED_FACE('',(#329),#348,.F.); 340 | #329 = FACE_BOUND('',#330,.F.); 341 | #330 = EDGE_LOOP('',(#331,#339,#346,#347)); 342 | #331 = ORIENTED_EDGE('',*,*,#332,.T.); 343 | #332 = EDGE_CURVE('',#133,#333,#335,.T.); 344 | #333 = VERTEX_POINT('',#334); 345 | #334 = CARTESIAN_POINT('',(8.75,-1.E-15,10.)); 346 | #335 = LINE('',#336,#337); 347 | #336 = CARTESIAN_POINT('',(8.75,-8.9E-16,15.)); 348 | #337 = VECTOR('',#338,1.); 349 | #338 = DIRECTION('',(-0.,-0.,-1.)); 350 | #339 = ORIENTED_EDGE('',*,*,#340,.T.); 351 | #340 = EDGE_CURVE('',#333,#333,#341,.T.); 352 | #341 = CIRCLE('',#342,1.25); 353 | #342 = AXIS2_PLACEMENT_3D('',#343,#344,#345); 354 | #343 = CARTESIAN_POINT('',(7.5,-8.9E-16,10.)); 355 | #344 = DIRECTION('',(0.,0.,1.)); 356 | #345 = DIRECTION('',(1.,0.,0.)); 357 | #346 = ORIENTED_EDGE('',*,*,#332,.F.); 358 | #347 = ORIENTED_EDGE('',*,*,#132,.F.); 359 | #348 = CYLINDRICAL_SURFACE('',#349,1.25); 360 | #349 = AXIS2_PLACEMENT_3D('',#350,#351,#352); 361 | #350 = CARTESIAN_POINT('',(7.5,-8.9E-16,15.)); 362 | #351 = DIRECTION('',(0.,0.,1.)); 363 | #352 = DIRECTION('',(1.,0.,-0.)); 364 | #353 = ADVANCED_FACE('',(#354),#373,.F.); 365 | #354 = FACE_BOUND('',#355,.F.); 366 | #355 = EDGE_LOOP('',(#356,#364,#371,#372)); 367 | #356 = ORIENTED_EDGE('',*,*,#357,.T.); 368 | #357 = EDGE_CURVE('',#144,#358,#360,.T.); 369 | #358 = VERTEX_POINT('',#359); 370 | #359 = CARTESIAN_POINT('',(-6.25,1.E-15,10.)); 371 | #360 = LINE('',#361,#362); 372 | #361 = CARTESIAN_POINT('',(-6.25,8.9E-16,15.)); 373 | #362 = VECTOR('',#363,1.); 374 | #363 = DIRECTION('',(-0.,-0.,-1.)); 375 | #364 = ORIENTED_EDGE('',*,*,#365,.T.); 376 | #365 = EDGE_CURVE('',#358,#358,#366,.T.); 377 | #366 = CIRCLE('',#367,1.25); 378 | #367 = AXIS2_PLACEMENT_3D('',#368,#369,#370); 379 | #368 = CARTESIAN_POINT('',(-7.5,8.9E-16,10.)); 380 | #369 = DIRECTION('',(0.,0.,1.)); 381 | #370 = DIRECTION('',(1.,0.,0.)); 382 | #371 = ORIENTED_EDGE('',*,*,#357,.F.); 383 | #372 = ORIENTED_EDGE('',*,*,#143,.F.); 384 | #373 = CYLINDRICAL_SURFACE('',#374,1.25); 385 | #374 = AXIS2_PLACEMENT_3D('',#375,#376,#377); 386 | #375 = CARTESIAN_POINT('',(-7.5,8.9E-16,15.)); 387 | #376 = DIRECTION('',(0.,0.,1.)); 388 | #377 = DIRECTION('',(1.,0.,-0.)); 389 | #378 = ADVANCED_FACE('',(#379),#398,.F.); 390 | #379 = FACE_BOUND('',#380,.F.); 391 | #380 = EDGE_LOOP('',(#381,#390,#396,#397)); 392 | #381 = ORIENTED_EDGE('',*,*,#382,.F.); 393 | #382 = EDGE_CURVE('',#383,#383,#385,.T.); 394 | #383 = VERTEX_POINT('',#384); 395 | #384 = CARTESIAN_POINT('',(2.75,0.,-10.)); 396 | #385 = CIRCLE('',#386,2.75); 397 | #386 = AXIS2_PLACEMENT_3D('',#387,#388,#389); 398 | #387 = CARTESIAN_POINT('',(0.,0.,-10.)); 399 | #388 = DIRECTION('',(0.,0.,-1.)); 400 | #389 = DIRECTION('',(1.,0.,0.)); 401 | #390 = ORIENTED_EDGE('',*,*,#391,.T.); 402 | #391 = EDGE_CURVE('',#383,#155,#392,.T.); 403 | #392 = LINE('',#393,#394); 404 | #393 = CARTESIAN_POINT('',(2.75,0.,-10.)); 405 | #394 = VECTOR('',#395,1.); 406 | #395 = DIRECTION('',(0.,0.,1.)); 407 | #396 = ORIENTED_EDGE('',*,*,#154,.T.); 408 | #397 = ORIENTED_EDGE('',*,*,#391,.F.); 409 | #398 = CYLINDRICAL_SURFACE('',#399,2.75); 410 | #399 = AXIS2_PLACEMENT_3D('',#400,#401,#402); 411 | #400 = CARTESIAN_POINT('',(0.,0.,-10.)); 412 | #401 = DIRECTION('',(0.,0.,-1.)); 413 | #402 = DIRECTION('',(1.,0.,0.)); 414 | #403 = ADVANCED_FACE('',(#404),#423,.F.); 415 | #404 = FACE_BOUND('',#405,.F.); 416 | #405 = EDGE_LOOP('',(#406,#414,#421,#422)); 417 | #406 = ORIENTED_EDGE('',*,*,#407,.T.); 418 | #407 = EDGE_CURVE('',#166,#408,#410,.T.); 419 | #408 = VERTEX_POINT('',#409); 420 | #409 = CARTESIAN_POINT('',(1.25,7.5,10.)); 421 | #410 = LINE('',#411,#412); 422 | #411 = CARTESIAN_POINT('',(1.25,7.5,15.)); 423 | #412 = VECTOR('',#413,1.); 424 | #413 = DIRECTION('',(-0.,-0.,-1.)); 425 | #414 = ORIENTED_EDGE('',*,*,#415,.T.); 426 | #415 = EDGE_CURVE('',#408,#408,#416,.T.); 427 | #416 = CIRCLE('',#417,1.25); 428 | #417 = AXIS2_PLACEMENT_3D('',#418,#419,#420); 429 | #418 = CARTESIAN_POINT('',(0.,7.5,10.)); 430 | #419 = DIRECTION('',(0.,0.,1.)); 431 | #420 = DIRECTION('',(1.,0.,0.)); 432 | #421 = ORIENTED_EDGE('',*,*,#407,.F.); 433 | #422 = ORIENTED_EDGE('',*,*,#165,.F.); 434 | #423 = CYLINDRICAL_SURFACE('',#424,1.25); 435 | #424 = AXIS2_PLACEMENT_3D('',#425,#426,#427); 436 | #425 = CARTESIAN_POINT('',(0.,7.5,15.)); 437 | #426 = DIRECTION('',(0.,0.,1.)); 438 | #427 = DIRECTION('',(1.,0.,-0.)); 439 | #428 = ADVANCED_FACE('',(#429),#432,.T.); 440 | #429 = FACE_BOUND('',#430,.T.); 441 | #430 = EDGE_LOOP('',(#431)); 442 | #431 = ORIENTED_EDGE('',*,*,#190,.T.); 443 | #432 = PLANE('',#433); 444 | #433 = AXIS2_PLACEMENT_3D('',#434,#435,#436); 445 | #434 = CARTESIAN_POINT('',(-9.5,-5.853288E-11,5.)); 446 | #435 = DIRECTION('',(-0.,-0.,-1.)); 447 | #436 = DIRECTION('',(-1.,0.,0.)); 448 | #437 = ADVANCED_FACE('',(#438),#441,.T.); 449 | #438 = FACE_BOUND('',#439,.T.); 450 | #439 = EDGE_LOOP('',(#440)); 451 | #440 = ORIENTED_EDGE('',*,*,#215,.T.); 452 | #441 = PLANE('',#442); 453 | #442 = AXIS2_PLACEMENT_3D('',#443,#444,#445); 454 | #443 = CARTESIAN_POINT('',(-1.7E-16,-9.5,5.)); 455 | #444 = DIRECTION('',(-0.,-0.,-1.)); 456 | #445 = DIRECTION('',(-1.,0.,0.)); 457 | #446 = ADVANCED_FACE('',(#447,#450),#453,.T.); 458 | #447 = FACE_BOUND('',#448,.T.); 459 | #448 = EDGE_LOOP('',(#449)); 460 | #449 = ORIENTED_EDGE('',*,*,#240,.T.); 461 | #450 = FACE_BOUND('',#451,.T.); 462 | #451 = EDGE_LOOP('',(#452)); 463 | #452 = ORIENTED_EDGE('',*,*,#382,.F.); 464 | #453 = PLANE('',#454); 465 | #454 = AXIS2_PLACEMENT_3D('',#455,#456,#457); 466 | #455 = CARTESIAN_POINT('',(-4.6E-16,-6.7E-16,-10.)); 467 | #456 = DIRECTION('',(-0.,-0.,-1.)); 468 | #457 = DIRECTION('',(-1.,0.,0.)); 469 | #458 = ADVANCED_FACE('',(#459),#462,.T.); 470 | #459 = FACE_BOUND('',#460,.T.); 471 | #460 = EDGE_LOOP('',(#461)); 472 | #461 = ORIENTED_EDGE('',*,*,#265,.T.); 473 | #462 = PLANE('',#463); 474 | #463 = AXIS2_PLACEMENT_3D('',#464,#465,#466); 475 | #464 = CARTESIAN_POINT('',(9.5,5.634941E-11,5.)); 476 | #465 = DIRECTION('',(-0.,-0.,-1.)); 477 | #466 = DIRECTION('',(-1.,0.,0.)); 478 | #467 = ADVANCED_FACE('',(#468),#471,.T.); 479 | #468 = FACE_BOUND('',#469,.T.); 480 | #469 = EDGE_LOOP('',(#470)); 481 | #470 = ORIENTED_EDGE('',*,*,#290,.T.); 482 | #471 = PLANE('',#472); 483 | #472 = AXIS2_PLACEMENT_3D('',#473,#474,#475); 484 | #473 = CARTESIAN_POINT('',(2.18472E-12,9.5,5.)); 485 | #474 = DIRECTION('',(-0.,-0.,-1.)); 486 | #475 = DIRECTION('',(-1.,0.,0.)); 487 | #476 = ADVANCED_FACE('',(#477),#480,.T.); 488 | #477 = FACE_BOUND('',#478,.T.); 489 | #478 = EDGE_LOOP('',(#479)); 490 | #479 = ORIENTED_EDGE('',*,*,#315,.T.); 491 | #480 = PLANE('',#481); 492 | #481 = AXIS2_PLACEMENT_3D('',#482,#483,#484); 493 | #482 = CARTESIAN_POINT('',(8.5E-16,-7.5,10.)); 494 | #483 = DIRECTION('',(0.,0.,1.)); 495 | #484 = DIRECTION('',(0.,1.,0.)); 496 | #485 = ADVANCED_FACE('',(#486),#489,.T.); 497 | #486 = FACE_BOUND('',#487,.T.); 498 | #487 = EDGE_LOOP('',(#488)); 499 | #488 = ORIENTED_EDGE('',*,*,#340,.T.); 500 | #489 = PLANE('',#490); 501 | #490 = AXIS2_PLACEMENT_3D('',#491,#492,#493); 502 | #491 = CARTESIAN_POINT('',(7.5,-7.5E-16,10.)); 503 | #492 = DIRECTION('',(0.,0.,1.)); 504 | #493 = DIRECTION('',(1.,0.,0.)); 505 | #494 = ADVANCED_FACE('',(#495),#498,.T.); 506 | #495 = FACE_BOUND('',#496,.T.); 507 | #496 = EDGE_LOOP('',(#497)); 508 | #497 = ORIENTED_EDGE('',*,*,#365,.T.); 509 | #498 = PLANE('',#499); 510 | #499 = AXIS2_PLACEMENT_3D('',#500,#501,#502); 511 | #500 = CARTESIAN_POINT('',(-7.5,9.2E-16,10.)); 512 | #501 = DIRECTION('',(0.,0.,1.)); 513 | #502 = DIRECTION('',(1.,0.,0.)); 514 | #503 = ADVANCED_FACE('',(#504),#507,.T.); 515 | #504 = FACE_BOUND('',#505,.T.); 516 | #505 = EDGE_LOOP('',(#506)); 517 | #506 = ORIENTED_EDGE('',*,*,#415,.T.); 518 | #507 = PLANE('',#508); 519 | #508 = AXIS2_PLACEMENT_3D('',#509,#510,#511); 520 | #509 = CARTESIAN_POINT('',(-1.7E-16,7.5,10.)); 521 | #510 = DIRECTION('',(0.,0.,1.)); 522 | #511 = DIRECTION('',(0.,1.,0.)); 523 | #512 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) 524 | GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#516)) GLOBAL_UNIT_ASSIGNED_CONTEXT 525 | ((#513,#514,#515)) REPRESENTATION_CONTEXT('Context #1', 526 | '3D Context with UNIT and UNCERTAINTY') ); 527 | #513 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); 528 | #514 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); 529 | #515 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); 530 | #516 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#513, 531 | 'distance_accuracy_value','confusion accuracy'); 532 | #517 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); 533 | #518 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#519) 534 | ,#512); 535 | #519 = STYLED_ITEM('color',(#520),#15); 536 | #520 = PRESENTATION_STYLE_ASSIGNMENT((#521,#527)); 537 | #521 = SURFACE_STYLE_USAGE(.BOTH.,#522); 538 | #522 = SURFACE_SIDE_STYLE('',(#523)); 539 | #523 = SURFACE_STYLE_FILL_AREA(#524); 540 | #524 = FILL_AREA_STYLE('',(#525)); 541 | #525 = FILL_AREA_STYLE_COLOUR('',#526); 542 | #526 = COLOUR_RGB('',0.949019609525,0.619607859787,0.399999997426); 543 | #527 = CURVE_STYLE('',#528,POSITIVE_LENGTH_MEASURE(0.1),#529); 544 | #528 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous'); 545 | #529 = COLOUR_RGB('',9.803921802644E-02,9.803921802644E-02, 546 | 9.803921802644E-02); 547 | ENDSEC; 548 | END-ISO-10303-21; 549 | --------------------------------------------------------------------------------