{"id":20738073,"url":"https://github.com/developeracademy-postech/2024-nc2-m29-coremotion","last_synced_at":"2026-04-27T04:32:23.250Z","repository":{"id":244628888,"uuid":"815788103","full_name":"DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion","owner":"DeveloperAcademy-POSTECH","description":"NC2 Team 100Mile(Miles\u0026Tanya)","archived":false,"fork":false,"pushed_at":"2024-06-25T11:14:51.000Z","size":618,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-12-26T16:42:51.969Z","etag":null,"topics":["coremotion","ios","pullup","swiftui"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DeveloperAcademy-POSTECH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-16T06:43:25.000Z","updated_at":"2024-06-25T11:14:54.000Z","dependencies_parsed_at":"2024-06-25T12:38:54.974Z","dependency_job_id":"6d8ca534-249e-4e4a-ab1f-51c6b3d81a54","html_url":"https://github.com/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion","commit_stats":null,"previous_names":["developeracademy-postech/2024-nc2-m29-coremotion"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeveloperAcademy-POSTECH%2F2024-NC2-M29-CoreMotion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeveloperAcademy-POSTECH%2F2024-NC2-M29-CoreMotion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeveloperAcademy-POSTECH%2F2024-NC2-M29-CoreMotion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeveloperAcademy-POSTECH%2F2024-NC2-M29-CoreMotion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DeveloperAcademy-POSTECH","download_url":"https://codeload.github.com/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeveloperAcademy-POSTECH%2F2024-NC2-M29-CoreMotion/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32323213,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coremotion","ios","pullup","swiftui"],"created_at":"2024-11-17T06:16:30.403Z","updated_at":"2026-04-27T04:32:23.234Z","avatar_url":"https://github.com/DeveloperAcademy-POSTECH.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 2024-NC2-M29-CoreMotion\n\n![image](https://github.com/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion/assets/63441374/dece1c1e-78f8-40ff-b071-f5206836291a)      \n      \n\n\n\u003e Team 100Mile의 풀업 세기 어플 만들기 프로젝트\n\n\n## ⚾️ 100Mile      \n- 디자인 - [Miles](https://github.com/by-h00n)\n- 개발 - [Tanya](https://github.com/seoyounghan)\n\n## 🎥 Youtube Link\n(추후 만들어진 유튜브 링크 추가)\n\n## 💡 About Core Motion\n- **기기내에서 물리적 데이터 센서를 이용할 수 있는 기술**\n- 지원 센서(기기에 따라서 지원하는 센서 다름)\n    - 가속도계\n    - 자이로스코프\n    - 자력계\n    - 보수계 및 피트니스\n    - 운동 장애 관리\n    - 침수 센서\n- [공식문서](https://developer.apple.com/documentation/coremotion)\n\n## 🎯 What we focus on?\n- [Tanya](https://github.com/seoyounghan) - Core Motion을 통해 센서 데이터를 받아서 앱을 만들어보기\n- [Miles](https://github.com/by-h00n) - 실시간 데이터에 따라 변화하는 UI\n\n\n## 💼 Use Case\n**머리의 움직임으로 턱걸이 개수를 세어 주자**\n\n\n## 🖼️ Prototype\n\n|뷰|설명|\n|------|---|\n|![MainView](https://github.com/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion/assets/63441374/017033e4-e699-4b2b-98f6-90105e54fc21)|**MainView**\u003cbr\u003e\u003cbr\u003e앱 시작 화면\u003cbr\u003estart 버튼으로 턱걸이 시작\u003cbr\u003e우측 상단 버튼으로 기록 보기\u003cbr\u003e목표 숫자 설정|\n|![PullUpCountView](https://github.com/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion/assets/63441374/a587dd04-47e4-4c14-8909-704d2bfa0dca)|**PullUpCountView**\u003cbr\u003e\u003cbr\u003eCount로 풀업 갯수 표시\u003cbr\u003e중앙 원들로 목표 달성도 표시\u003cbr\u003estop 버튼으로 결과 화면으로 이동|\n|![ResultView](https://github.com/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion/assets/63441374/1ab28e43-9af3-45bf-ab60-149bef04133e)|**ResultView**\u003cbr\u003e\u003cbr\u003e진행한 풀업 갯수, 목표, 진행 시간 표시|\n|![ActivityView](https://github.com/DeveloperAcademy-POSTECH/2024-NC2-M29-CoreMotion/assets/63441374/0401dab1-da8a-45d6-9ba4-eb72cdb6e07d)|**ActivityView**\u003cbr\u003e\u003cbr\u003e풀업 기록 표시\u003cbr\u003e 밀어서 삭제|\n\n\n\n\n## 🛠️ About Code\n\n### PullUpCounter: ObservableObject 클래스 설명\n\n#### 헤드폰 모션 매니저 초기화\nCMHeadphoneMotionManager()를 사용하여 헤드폰 모션 매니저를 초기화합니다.\n\n```swift\nvar headphoneMotionManager = CMHeadphoneMotionManager()\n```\n\n#### startUpdates() 함수\n헤드폰 모션 정보를 받아오는 함수입니다.\n\n- 디바이스에서 불러올 수 있는 경우 업데이트를 시작합니다.\n- 헤드폰에서 데이터가 갱신되는 주기대로 업데이트를 통해 구문을 실행합니다.\n- 현재는 가속도 데이터를 받아와서 턱걸이 데이터를 처리합니다.\n\n```swift\nfunc startUpdates() {\n    if headphoneMotionManager.isDeviceMotionAvailable {\n        headphoneMotionManager.startDeviceMotionUpdates(to: .main) { [weak self] motion, error in\n            guard let self = self, let motion = motion, error == nil else { return }\n\n            self.accelData = motion.userAcceleration\n            self.processAccelData(motion.userAcceleration)\n            if headphoneMotionManager.isDeviceMotionActive {\n                isHeadPhoneDetected = true\n            }\n        }\n    } else {\n        stopUpdates()\n        print(\"not available\")\n    }\n}\n```\n\n#### 턱걸이 감지 함수\n턱걸이를 감지하는 로직입니다.\n\n- `integralZ` 변수에 적분 값을 업데이트합니다. (적분 값은 속도)\n- 적분 값의 최대값과 최솟값의 차이가 기준 값(threshold)을 초과하면, 사용자가 올라가거나 내려갈 때 횟수를 0.5씩 증가시킵니다.\n- 내려갈 때 기준 값을 넘으면, 최소/최대 값을 초기화하여 다음 카운팅을 준비합니다.\n\n```swift\nprivate func processAccelData(_ acceleration: CMAcceleration) {\n    let currentAccelZ = acceleration.z\n    let dt = 0.04\n\n    integralZ += ((currentAccelZ + lastAccelZ) * 0.5 * dt)\n    lastAccelZ = currentAccelZ\n\n    if integralZ \u003e maxIntegralZ {\n        maxIntegralZ = integralZ\n    }\n\n    if integralZ \u003c minIntegralZ {\n        minIntegralZ = integralZ\n    }\n\n    let goingUp = currentAccelZ \u003e 0\n\n    if (maxIntegralZ - minIntegralZ) \u003e threshold {\n        if !pullUpInProgress \u0026\u0026 goingUp {\n            pullUpCount += 0.5\n            print(\"Pull-Up Count: \\(pullUpCount)\")\n            pullUpInProgress = true\n        } else if pullUpInProgress \u0026\u0026 !goingUp {\n            minIntegralZ = integralZ\n            maxIntegralZ = integralZ\n            pullUpInProgress = false\n        }\n    }\n    lastIntegralZ = integralZ\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloperacademy-postech%2F2024-nc2-m29-coremotion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeveloperacademy-postech%2F2024-nc2-m29-coremotion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloperacademy-postech%2F2024-nc2-m29-coremotion/lists"}