3228

[Training Camp] Four-legged robot dog based on OpenHarmony system

 
Overview
## Modular quadruped robot dog based on OpenHarmony system#### Uses HiSilicon Hi3861 as the main control chip and PCA9685 for servo control, supporting up to 16 channels of servo control. Module composition: Hi3861 core board, PCA9685 steering gear control board, ultrasonic ranging board, MPU-6050 module, etc. (Currently completed HCR-S04 ultrasonic ranging and realized autonomous obstacle avoidance function) ## Core board PCB 3d preview: ![Screenshot (30).png] ## Quadruped robot shell 3d preview:![Screenshot (35) .png] ## Physical display: ![19410ed5fe0cecbd2d68ed38a7fc0e6.jpg] Front: ![2f498569e373b618a7609dbff0ae8c2.jpg] Left: ![bc875cafc39ec0055efae9d4ba4a2c9.jpg] After: ![c575dfa0ebe51d1ef22c706ff6cb516.jpg] Crouching position: ![22dc99d9c45b2555e7958edf312fa01.jpg] ## Web page Display: ![Screenshot(38).png] ## Program description: #### 1. Basic action code: ``` fe(g('a'), () => {fg(u('/dog/init'), () => {} );}); fe(g('b'), () => {let data = {"type": 3, "count": 10, "list": [[-15, 130, -35, 150 , -35, 150, -15, 130, 100], [-35, 150, -15, 130, -15, 130, -35, 150, 100]]};fp(u('/dog/cmds' ), JSON.stringify(data), () => {});}); fe(g('b'), () => {let data = {"type": 3, "count": 1, "list": [[-15, 130, -15, 130, -15, 130, -15, 130, 300]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('c'), () => {let data = {"type": 3, "count": 10, "list": [[31, 96 , 54, 144, 63, 139, 19, 100, 50], [35, 112, 5, 134, 15, 136, 25, 115, 50], [60, 138, 5, 106, 16, 104, 51 , 142, 50], [48, 144, 20, 103, 31, 98, 40, 147, 50], [-1, 118, 38, 132, 48, 128, -12, 118, 50]]}; fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('c'), () => {let data = {"type ": 3, "count": 1, "list": [[-15, 130, -15, 130, -15, 130, -15, 130, 300]]};fp(u('/dog/cmds '), JSON.stringify(data), () => {});}); fe(g('d'), () => {let data = {"type": 3, "count": 10 , "list": [[63, 139, 19, 100, 31, 96, 54, 144, 50], [48, 128, -37, 115, -22, 116, 38, 132, 50], [31 , 98, 35, 148, 42, 146, 20, 103, 50], [9, 106, 51, 142, 60, 138, -1, 107, 50], [-2, 132, 25, 115, 35 , 112, -14, 125, 50]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('d' ), () => {let data = {"type": 3, "count": 1, "list": [[-15, 130, -15, 130, -15, 130, -15, 130, 300 ]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('e'), () => {let data = {"type": 3, "count": 10, "list": [[56, 135, 21, 107, 56, 135, 21, 107, 50], [46, 126, -11, 119, 12 , 133, 26, 117, 50], [32, 104, 33, 142, 18, 109, 45, 138, 50], [42, 139, 22, 108, 32, 104, 33, 142, 50], [0, 120, 36, 130, 46, 126, -11, 119, 50]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {}); }); fe(g('e'), () => {let data = {"type": 3, "count": 1, "list": [[-15, 130, -15, 130, - 15, 130, -15, 130, 300]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('f '), () => {let data = {"type": 3, "count": 10, "list": [[32, 103, 47, 139, 32, 103, 47, 139, 50], [ 36, 114, 3, 132, 0, 120, 36, 130, 50], [54, 134, 7, 111, 42, 139, 22, 108, 50], [18, 109, 45, 138, 54, 134, 7, 111, 50], [12, 133, 26, 117, 36, 114, 3, 132, 50]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('f'), () => {let data = {"type": 3, "count": 1, "list": [[-15, 130, -15, 130, -15, 130, -15, 130, 300]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('g'), () => {let data = {"type": 3, "count": 1, "list": [[-15, 130, -15, 130, -15, 130, -15, 130, 500]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('h'), () => {let data = {"type": 3, "count": 1, "list": [[45, 130, -45, 180, 45, 130, -45, 180, 700]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g( 'i'), () => {let data = {"type": 3, "count": 1, "list": [[-45, 180, -45, 180, -45, 180, -45, 180, 700]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});}); fe(g('j'), () => {let data = {"type": 3, "count": 1, "list": [[60, 210, 60, 225, 60, 210, 60, 225, 700]]};fp(u('/ dog/cmds'), JSON.stringify(data), () => {});}); fe(g('k'), () => {fg(u('/dog/auto'), () => {});}); fe(g('k'), () => {let data = {"type": 3, "count": 1, "list": [[-15, 130, -15, 130, -15, 130, -15, 130, 300]]};fp(u('/dog/cmds'), JSON.stringify(data), () => {});} ); ``` Use json strings to implement basic steps, forward, backward and other actions. #### 2.1 HCSR-04 ranging part: ``` cs #include #include #include #include "ohos_init.h" #include "cmsis_os2.h " #include "iot_gpio.h" #include "iot_io.h" #include "genki_pin.h" #include "dog.h" #include "iot_time.h" #include "pca9685.h" #include "hi_nvm.h" #include #include #include #include "cJSON.h" #include "kinematics.h" #define Echo 8 //Echo //GPIO8 #define Trig 7 / /Trig //GPIO7 #define GPIO_FUNC 0 float distance; float GetDistance (void) { static unsigned long start_time = 0, time = 0; distance = 0.0; IotGpioValue value = IOT_GPIO_VALUE0; unsigned int flag = 0; IoTIoSetFunc(Echo, GPIO_FUNC) ;//Set Echo connection IO to normal GPIO mode, no reuse IoTGpioSetDir(Echo, IOT_GPIO_DIR_IN);//Set Echo connection IO to input mode IoTGpioSetDir(Trig, IOT_GPIO_DIR_OUT);//Set Trig connection IO to output mode IoTGpioSetOutputVal(Trig , IOT_GPIO_VALUE1);//Pull Trig high IoTUdelay(20);//20us IoTGpioSetOutputVal(Trig, IOT_GPIO_VALUE0);//Pull Trig low while (1) { IoTGpioGetInputVal(Echo, &value);//Read the level of Echo pin Status if (value == IOT_GPIO_VALUE1 && flag == 0) {//If it is high start_time = IoTGetUs();//Get the time at this time flag = 1; } if (value == IOT_GPIO_VALUE0 && flag == 1) {/ /High level ends and becomes low level time = IoTGetUs() - start_time;//Calculate the high level maintenance time start_time = 0; break; } } distance = time * 0.034 / 2;//Calculate the distance printf("distance is %f cm ", distance);//Print distance} ```` This part is a general code and can be applied to different codes according to the device conditions, without going into details. #### 2.2 Obstacle avoidance part: ``` cs void dog_auto () { while (1) { if (distance <= 5) { dog_execJson("{"type": 3, "count": 1, "list": [[63 , 139, 19, 100, 31, 96, 54, 144, 50], [48, 128, -37, 115, -22, 116, 38, 132, 50], [31, 98, 35, 148, 42 , 146, 20, 103, 50], [9, 106, 51, 142, 60, 138, -1, 107, 50], [-2, 132, 25, 115, 35, 112, -14, 125, 50]]}", 294); break; } else { if (distance <= 20) { dog_execJson("{"type": 3, "count": 5, "list": [[56, 135, 21, 107, 56, 135, 21, 107, 50], [46, 126, -11, 119, 12, 133, 26, 117, 50], [32, 104, 33, 142, 18, 109, 45, 138 , 50], [42, 139, 22, 108, 32, 104, 33, 142, 50], [0, 120, 36, 130, 46, 126, -11, 119, 50]]}", 294) ; break; } else { dog_execJson("{"type": 3, "count": 1, "list": [[31, 96, 54, 144, 63, 139, 19, 100, 50], [35, 112, 5, 134, 15, 136, 25, 115, 50], [60, 138, 5, 106, 16, 104, 51, 142, 50], [48, 144, 20, 103, 31, 98, 40, 147, 50], [-1, 118, 38, 132, 48, 128, -12, 118, 50]]}", 294); break; } } } } ``` This part of the principle is based on the above The distance calculated by the ranging part is used to judge the distance to avoid obstacles. ###### ** For example: if the distance is less than or equal to 5cm, then move backward until the measured distance is greater than 5cm; if the distance is less than or equal to 20cm, then turn left on the spot 5 times until the measured distance is greater than 20cm; if the distance is greater than 20cm, proceed forward. ** However, although this part of the code can theoretically implement obstacle avoidance actions, how to put it into the web to implement button calls is an area that I have not covered. For this reason, I searched aimlessly on the Internet for a long time, and finally After an unintentional reminder from an Internet of Things classmate and careful reading of the source code, I finally implemented it. The code is as follows: ``` cs //Add the following function to the genki_web_ohosdog.c file: static int doAuto (genki_web_request_t *request, genki_web_response_t *response ) { for(int k=1; k<=80; k=k+1) //Due to the uninterruptibility of web button calls, a fixed number of times is set to avoid the problem of serious heating of the voltage-reducing chip due to too long action time. { GetDistance();//Measure and calculate the distance dog_auto();//Make corresponding actions based on the measured distance IoTUdelay(100);//Delay 100ms }return 1; } //And add statements in the following function "service->addFilter(service, "/dog/auto", doAuto);" genki_web_service_t *newDogService(void) { genki_web_service_t *service = genki_web_newService("DOG"); service->addFilter(service, "/dog", doHtml ); service->addFilter(service, "/dog/init", doInit); service->addFilter(service, "/dog/cmds", doCmds); service->addFilter(service, "/dog/auto", doAuto); //Name the function "doAuto" as the service of "/dog/auto" //Finally add the button call statement fe(g('k'), () => {fg(u('/ dog/auto'),() => {});});//The button calls the service``` (all codes have been placed in the attachment) ## Summary: ###### As a student majoring in robotics, this is actually my first This is the first time I have such an in-depth understanding of the quadruped robot I made this time. Although some of the underlying logic codes were borrowed from others, I just modified them slightly after taking them. ###### In this process, I experienced from schematic drawing to PCB wiring, from physical soldering to the final successful implementation of the action. These are things I never thought I could do. I followed the teachings from the beginning. I drew a picture step by step in the video, and later I had my own ideas. I looked up pictures of quadruped robots on the Internet, and decided to make a unique robot of my own. I felt embarrassed when I saw the capacitors and resistors in the 0603 package, and my hands shook. Trial and error molding. I have experienced the wrong size of the printouts I received, the unreasonable design structure, accidentally burning the burner, thinking that the battery was broken, and after tinkering for a long time, it turned out that the battery was dead but I never found it because there was no charger. I was faced with a source that I couldn’t understand. I can only check the code bit by bit, and when faced with a program that keeps making errors, I can only keep looking for errors in the middle of the night. I don’t know how many times I stayed up until 4 o’clock in the morning and still felt very motivated, because this is what I like. But if you are dumber than others, you can only spend more time. Although this project took a long time to be completed due to my own reasons, I should continue to update the new progress in the future. I am very grateful to Lichuang for providing us with such an opportunity, which allowed me to not let myself be wasted during the holidays, and provided me with a valuable and interesting experience in my future studies and work. ## Physical demonstration:
参考设计图片
×
 
 
Search Datasheet?

Supported by EEWorld Datasheet

Forum More
Update:2025-05-20 15:37:01

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
community

Robot
development
community

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号