Open bhunt2 opened 8 years ago
WIKI : https://github.com/bhunt2/QC1.0/wiki/Flight-Automation-Overview
Tests: https://github.com/bhunt2/QC1.0/wiki/Flight-Automation-Overview#tests . There are lots of commands but I only want to test couple for now. Those commands have already been documented here http://www.multiwii.com/wiki/index.php?title=Multiwii_Serial_Protocol in details.
My Code : https://github.com/bhunt2/QC1.0/blob/master/Sabin-Code/sendCmdConverted.cpp The code has lots of comments and not pretty. I want to get it working before I refactor and make it "pretty". Lots of hard coded variable and values are used. For testing purposes, I have this bare bone as possible.
Output 1 (with ground wire connected):https://github.com/bhunt2/QC1.0/blob/master/Sabin-Code/Capture_with_ground.PNG
Output 2 (without ground wire connected):https://github.com/bhunt2/QC1.0/blob/master/Sabin-Code/Capture_without_ground.PNG
I do not see any headers "$M<" with ground wire connected. There are no "frame" or patterns. It looks like bunch of garbage data.
For ground wire not connected, I just get back what I send.
Also, When Flight controller has no power (no power to drone), when I sent the commands, I get the same outputs back like I stated above.
UART info: UART @ dev/ttyMFD1. 115200 baudrate .
I can see header now on the jumbled data. Still don't have any structure as expected.
Sabin, this output is looking better than what I was seeing before. Please add a print out of the command being sent such as: "Sending 100" or something like that so it is understand what the response is for.
In the two images you posted above, the second one is with ground unattached/the power is off on the Flip. The first image is with the ground attached and what seems like some kind of response from the Flip, but it is unclear if it means anything. If I read your code correctly, you are only sending one command that is hard-coded into the code and then running an infinite while loop while you wait for a response. If you are only sending one command that has a specific return size and type, why does it seem like you are getting back way more than you should be? Again, I don't know which command/request this picture is issuing to get this response so it is difficult for me to determine anything from this. From the looks of it, the first several bytes that come through are an appropriate response. We just don't know what the rest is.
Also, please load the data received into a struct that stores the data in its appropriate frame. This will facilitate much faster debugging and clear outputs. Do you have everything connected so that I would be able to run your code myself and see what is happening?
Yea, you can run my code . it is under @root Drone/drone.cpp (this is my old code). @root Drone/drone1.cpp is the refactored version. it has struct datatypes for each test commands. The only thing is Drone needs to be turned on and battery doesn't last that long . I have to recharge it constantly. So, testing is difficult remotely.
I thought you had these connected and powered via USB right now while are figuring this stuff out. Especially while the drone cannot be flown, there is no reason why the two boards can't be connected by wall power or something else that doesn't need to be charged. Right now we need as much access to the Edison, Flip, and camera as possible to accomplish the current tasks.
Also, thanks for the update on where your code is and that it is ok for me to run it. Please answer the other questions I had in regards to what we are seeing and update the documentation to show the new outputs. We can figure this out quick if we work together on it.
I think I figured out why you have to use the drone to power, it is because the USB is not repaired yet. Correct?
Yes, I was trying to connect the Flip with USB adapter and that's when it broke. Hau will pick it up Monday and fix it soon as possible because my tasks depends on Flip. I still don't know What I'm seeing on the outputs. I'm looking online to see if I miss anything. I will update if any new output comes out. Thanks!
What is the plan for getting the system back online for us to begin working on this again? I know that a few things need to be fixed, but hopefully in a day or two right?
Yes, I'm hoping Hau gets it fixed quickly so that I can work on it.
@bhunt2 @spesialstyrker @hautruong36 @Kekahuna I have been having problems on communicating with Flip MWC 1.5 as I have stated in this issue https://github.com/bhunt2/QC1.0/issues/24 I researched the specs on FLIP MWC FLIGHT CONTROLLER 1.5 and found out that the there is only one serial port for Bluetooth. Does this mean this is only used for Bluetooth protocols? I am hooking my tx/rx pins from Edison to the Flip's serial port. Also, I looked through their firmware code, it looks like its listening to the USB port.
@sabmah
What happened to your comments that were in issue #27? Your comments were important in and of themselves. They also help in understanding why I wrote my comments. Also, I am still waiting on answers to some of my earlier questions. Please provide you input as soon as possible.
Oh! I thought you meant just copy your comment over. I'll re post all threads here from #27
I found this global constant on https://github.com/sabmah/multiwii/blob/master/MultiWii_shared/config.h#L708 but it was on the GPS section of the code.
//Enables the MSP_WP command set , which is used by WinGUI for displaying an setting up navigation //#define USE_MSP_WP
@sabmah @Kekahuna @hautruong36
This should not be in a new issue. It is just more discussion about the same issue. Please move this information to issue #24 and we will continue the discussion there. I will put my comments in regards to these concerns here, so please move them with it so everything stays in order. Once it is moved close this issue.
My comments to be copied:
Bluetooth UART: First of all, what bluetooth is the Flip trying to work with. There is no reference to BT in the firmware or documentation and nothing about it in the description of its capabilities. There is a reference saying that you can connect a BT device, but it is an optional device. The only device I see that is using serial by default is GPS. The GPS also can be configured to use I2C. Since at this point you will not be connecting it, you can find out in the firmware or in the multiwii software how to disable it. The additional data being transferred that we saw in a couple of your screen shots that didn't make sense may have been the Flip trying to communicate with the GPS. I am not sure because I haven't looked that thoroughly through the code.
Firmware is listening to USB port: ATmega328 only has one serial port available. This means that it will be used for both USB and other device communications. This may be the other possible reason why we see erroneous data in the output. I have not looked at everything so I don't know all the protocol and exactly how it is connected, but there may be some other setup needed to communicate properly. Remember you chose a different path than I had, so we are all learning together here.
Communication with the Flip: Remember, the Flip allows for SPI, I2C, and UART communication. Any one of these should have the libraries available for the Edison. They are pretty straight forward methods of communication, so it shouldn't be too much to get something going with any one of them.
For determining proper communications: Serial - You can use Putty setup to the appropriate port and speed to see what is being transmitted. I2C/SPI - There are two of the logic analyzers in the Willow Creek lab that have decoders that can tell you if the protocol is correct and tell you what the data is that is being sent in real-time.
These are the following things I found:
I've recorded an attitude output. It is running on python code. https://youtu.be/chRzSkRgi4Y
@sabmah
That looks good. Is this the code that you found in Python and just decided to try it out as is? I only see the Flip1.5 in the video, but it is connected to the Edison sitting on your desk or something right?
Please post information about what you did and how it worked and add the code to the repository. Also, updated Taiga appropriately. Then, please provide your plans for moving forward with this issue as we still need to test all commands and decide how to integrate with everything else. Are you going to stick with this Python code or will you be converting it to C++?
@bhunt2 @spesialstyrker @Kekahuna
Yes, I used the python code that I found before (https://github.com/alduxvm/pyMultiWii). The Edison is out of frame on video but it is connected to Edison.
The C++ code that I have wrote is about the same except I used mraa library while python just using pyserial library.
On python code, struct.pack and struct.unpack for packet conversions. On my c++ code, I'm casting for packet conversions. I'm suspecting if type conversions are the cause.
kainoa's image processing is on c++. That's why I went with c++. Python is much easier to use with their awesome libraries and if I use python, I might have to tell kai to write his code on python or use some other method to communicate with kainoa's c++ code.
I will update the plans on my wiki but here is brief:
@sabmah @Kekahuna @hautruong36 @spesialstyrker
I think that it is totally unreasonable to have Kainoa switch his code just to make your task easier. It would take far more time for him to port all of his work to Python than it would for you to debug your code. Also, communicating between programs would take processing power that you don't want to waste so that really isn't an option. It is possible to write C/C++ wrappers to extend Python code but I don't think that is a good option here either especially because you don't have much experience with either.
I would like to try and help but with the current circumstances it is difficult because I don't know when the Edison is connected to the Flip. If you guys can work out a schedule to know when things are going to be connected then we can try things out. If you need help with anything specific that would be easier to have someone beside you, I am sure Michael would be happy to work through it with you.
In regards to your plans to write Arm and Disarm code for the drone, that really isn't something you should be thinking of yet and doesn't follow the given stories as we have discussed. You must first complete the basic code that establishes communication. Then, develop a test that will ensure that all communications that will be needed for drone flight works and run the test. Then, think about Arm and Disarm code. If you need Arm and Disarm code for the final testing, then you would want to add that into your test plan as a necessary element to be written. Otherwise, it can wait until after testing.
Flip is always connected to Edison and Kainoa has it at this moment. We can try debugging the C++ Code like you said. I don't know if michael @spesialstyrker has looked at the code and would be helpful if I get any comment on the code.
I said Arm and Disarm because, it would be part of the next command I was going to test -MSP_SET_RAW_RC. I can just isolate the test to just test that one command.
Ok, if you need to do the arm and disarm code it is fine. If you can write the test plan with notes as to why you will test the way you are and how you will move forward with it that would be great. Michael @spesialstyrker and I will try to see what we can find in your code. Please update your Wiki to tell us what code we should be looking at and how it is suppose to work (pseudo code unless the pseudo code for your algorithm is already in the code).
@spesialstyrker @bhunt2 This is the pseudo code. I have link to my code in the wiki. https://github.com/bhunt2/QC1.0/wiki/Flight-Automation-Overview#test-code-algorithmflow
On Edison itself, it is located @root/Drone/drone.cpp
@sabmah @Kekahuna @hautruong36
Please provide the settings for connecting to the Edison. Now that Kainoa has it, the IP has changed. Maybe you could have a wiki page for the connection information and instructions on how to do it.
@bhunt2 @spesialstyrker @hautruong36 @Kekahuna Here are the ssh information for edison : https://github.com/bhunt2/QC1.0/wiki/Edison-SSH
@sabmah @Kekahuna @spesialstyrker
Hi guys, I tried playing with a bit but I don't like using the same workspace so I tried copying the code to my home directory. It compiles fine, but trying to run the program in either my home directory or in the roots directory using my account I get a segmentation fault. I don't have the time right now to look into this further, but I thought you might like to know.
When the program runs by root, it freezes after sending the command. Meaning it never gets anything back. When using my user, it gets the segmentation fault when going through the UART initialization.
@bhunt2 @spesialstyrker I do not get seg fault but I did encounter problem where it waits for response. I updated this on the known issue section of the autonomous drone overview wiki. This is caused by the Voltage supplied to Vin pin of the Flip. When it is unplugged, I get the response back.
@sabmah @Kekahuna @hautruong36 @spesialstyrker
I looked at your code. Here are a few questions that I have:
56 const char* cs = reinterpret_cast<const char>(&checksum); (gdb) n 57 dev->writeStr(cs); (gdb) print cs $4 = 100 'd' (gdb) print /x *cs $5 = 0x64
The questions is, does the function writeStr() see this properly as a string object? If you look into the differences between a const char* and a string object you will find that this is possibly part of the problem. It can easily be seen if you connect a logic analyzer and observe the bits that are being sent.
@sabmah @Kekahuna @hautruong36 @spesialstyrker
@sabmah
I have rewritten the code using common classes like string and ostringstream that are better able to deal with what we are trying to do. It is in my directory under dronex.cpp. Please take a look at it. I still don't see any response, but I do at least see that it is sending something and it should be in the appropriate format. I also made it so that it is packed just like in the python code. Now we just need to see if it should be reversed. The one issue that I didn't have time to work out is that currently it displays the packed frame being sent as a string. That means an integer displays as a number instead of hex. This may be ok, but it might be better to show as Hex.
@sabmah
Looking at the video I see a few items that don't seem like the logic analyzer is set correctly. When a byte value is blank that commonly means that the analyzer was unable to determine the value with a good level of certainty. When I look at the first few bytes being transmitted on either the TX or RX it is often shown as an incorrect value. The first three bytes of the TX should be 24:4D:3C and Rx should be 24:4D:3E. This discrepancy is likely due to the hi/lo and lo/hi transition voltage levels set in the analyzer software.
Please take a look at this and ensure that the bytes show correctly using the Python code before we move on to using it for troubleshooting the C++ code.
@sabmah
I played with the Python code because I don't have an Edison and Flip here to work with and found the for sure order that everything is being sent in.
Sending
It doesn't actually pack the data, it interprets a string as binary and essentially makes it typeless for a variety of uses. When it is placed into a struct it looks just like what we have done. Then when it sends it, it interprets the frame according to the packed formatting.
struct.pack('<3c2B%dhB'... means:
I know what everything except the final unsigned char is.
When the struct is printed before being sent, it looks just like what we have.
Receiving
The header comes in first with three bytes '$' -> 'M' -> '>'.
Then the data length as one byte.
Followed by the opcode as one byte.
Then the data in little endian format. In the case of the attitude we get back three values of two bytes each with the LSByte first. X -> Y -> Heading.
The python code completely ignores the CRC for received data.
I am getting back a response now, it just isn't what we want yet. Will update more later.
@sabmah @Kekahuna @hautruong36 @spesialstyrker
OK, I have it working. It is in my directory under dronex.cpp. I don't like how I did everything, but it can be optimized later. It was the fastest way I could think of for getting what I wanted done. If you can set it up with a better conversion from the string to floats it would be great. Currently this output matches the output from the Python code except for the fact that on occasion there is an extra byte or two received that offset the attitude bytes. I don't have the time until next week to look into that, but for now you should be able to work with it and maybe look into that issue a bit.
I would like you to pay attention to what I have to say after this. It has to do with something Faust said in the meeting and what could have made this take much less time to debug.
Essentially what I did was go back through the documentation and the Python code to verify what is to be sent and what would be received. This gave me a clear picture of what needed to be done. Initially I thought that the data portion of what I was receiving was wrong, but it was actually correct. I just needed to display it properly. So, after a little more playing around I figured a quick and dirty way to display everything correctly. The lesson we learn from this is that proper documentation and a clear test plan will ease collaboration and help get things done faster.
From here, we need to discuss how you plan to develop the code. Currently my code is using simple data structures and really no objects. You can look at the Python code for some ideas on how to setup the code framework. I would like to see what you can get together by our Monday meeting.
Good luck! Onward and upward!
Oh and please update the wiki accordingly. place my notes in where you think they would fit and change or summarize them if needed. Also, update the test plan information to be more clear.
@bhunt2 @spesialstyrker @Kekahuna @hautruong36 I have checked in all my latest code in my branch "develop_sabin" under Sabin-Code/src.
The attitude values comes in just fine. I'm trying to read RC values from FC and I compared it with the python code. It looks like it almost matches except the first two numbers. For some reason instead of 1500, i get 65500 (see outputs below). The conversion is from const char* to uint16_t.
On the arm/disarm, I'm sending arm values {1500, 1500, 2000, 1000} to the FC. I compared it to python code and when I run python code, the light on the FC lits up as it should because when we arm with RC, it does the same thing. The blue light on the FC lits up. For disarming, I'm sending {1500, 1500, 1000, 1000}
Please state exactly what you have done to troubleshoot this issue. Did you update the test plan according to my suggestions? It should now include exact bits being sent and exact bits expected and bits received. The bits seen by your program should match the bits seen by the logic analyzer. When you run the python code with the logic analyzer does it now see the same bit stream? If not, the logic analyzer has not been configured correctly. If it does, you need to use GDB to debug your code to see where it is screwing up.
The code I wrote was done quickly and was not generalized for all data types. From your screen shots it looks like the concersion for display isnt happening correctly so you can't ue that for help until you fix it.
Please look into these things and update before the meeting today and I will see what can find out. I am off to bed now.
See you in a few hours. On May 9, 2016 6:09 PM, "Sabin Maharjan" notifications@github.com wrote:
@bhunt2 https://github.com/bhunt2 @spesialstyrker https://github.com/spesialstyrker @Kekahuna https://github.com/Kekahuna @hautruong36 https://github.com/hautruong36 I have checked in all my latest code in my branch _"developsabin" under Sabin-Code/src.
The attitude values comes in just fine. I'm trying to read RC values from FC and I compared it with the python code. It looks like it almost matches except the first two numbers. For some reason instead of 1500, i get 65500 (see outputs below). The conversion is from const char* to uint16_t.
[image: c++ output rc] https://camo.githubusercontent.com/e90a6ab3c197b624222083ba139d1ee744f6b5d7/687474703a2f2f696d6775722e636f6d2f5967684a6544452e706e67 [image: python output rc] https://camo.githubusercontent.com/dfb18af54b6f1ea2592bdfd1fc6e69a7aea4ec54/687474703a2f2f696d6775722e636f6d2f4b4e6a4b714b652e706e67
On the arm/disarm, I'm sending arm values {1500, 1500, 2000, 1000} to the FC. I compared it to python code and when I run python code, the light on the FC lits up as it should because when we arm with RC, it does the same thing. The blue light on the FC lits up. For disarming, I'm sending {1500, 1500, 1000, 1000}
[image: Arm/Disarm] https://camo.githubusercontent.com/e17e12f541139167fbb536de46c30efe701655ad/687474703a2f2f692e696d6775722e636f6d2f714e74333864452e706e67
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/bhunt2/QC1.0/issues/24#issuecomment-217813693
@bhunt2 @spesialstyrker
So, the response in plain string from the output image below when I gdb is
$M>\020i\334\005\340\005\340\005\340\005\312\006\272\003\334\005\334\005\060
hex:0x0804f8d4
I can't figure out what format those numbers are inside \ \
Also Here is the gdb steps:
those values are not in hex. please update with the 22 byte hex value.
we should talk for a couple minutes. call me at 5412218929 or on hangouts if you can.
thanks On May 10, 2016 12:37 PM, "Sabin Maharjan" notifications@github.com wrote:
@bhunt2 https://github.com/bhunt2 @spesialstyrker https://github.com/spesialstyrker
So the response in plain string when I gdb is
$M>\020i\334\005\340\005\340\005\340\005\312\006\272\003\334\005\334\005\060
I can't figure out what format are those numbers inside \ \
[image: c++ output rc] https://camo.githubusercontent.com/e90a6ab3c197b624222083ba139d1ee744f6b5d7/687474703a2f2f696d6775722e636f6d2f5967684a6544452e706e67
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/bhunt2/QC1.0/issues/24#issuecomment-218051241
@bhunt2 ok. I'm finishing up the test plan. I'll call on hangout.
@bhunt2 @spesialstyrker
$M>\020i\334\005\340\005\340\005\340\005\312\006\272\003\334\005\334\005\060
Hex:
0x24 0x4d 0x3e 0x10 0x69 0xdc 0x05 0xe0 0x05 0xe0 0x05 0xe0 0x05 0xca 0x06 0xba 0x03 0xdc 0xdc 0x05 0x30 0x00
ASCII: (when I post this comment, the ASCII below is converted by github. I converted using this website: https://www.branah.com/ascii-converter)
$ M > i Ü à à à Ê º Ü Ü 0
Decimal:
36 | 77 | 62 | 16 | 105 | 220 | 5 | 224 | 5 | 224 | 5 | 224 | 5 | 202 | 6 | 186 | 3 | 220 | 220 | 5 | 48 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
r | r | p | p | y | y | t | t | a1 | a1 | a2 | a2 | a3 | a3 | a4 | a4 |
Binary:
00100100 01001101 00111110 00010000 01101001 11011100 00000101 11100000 00000101 11100000 00000101 11100000 00000101 11001010 00000110 10111010 00000011 11011100 11011100 00000101 00110000 00000000
@sabmah @spesialstyrker
Looking at this, we see that the first three bytes of header are correct and then the size (1 byte) says 16 bytes (0x10) of data should be received. This should then be followed by 1 byte for the command, in this case, dec. 105 or (0x69). That is also correct. We then see the 16 bytes of data come through. Followed by one byte for CRC which is 0x00 in this case. If I add all that up I get 22 bytes of data. Is this not correct?
It looks to me that you are getting what you should be. I would say your issue again is with how you are interpreting the data being received.
@bhunt2 @spesialstyrker
I forgot about the crc byte on response. I didn't count that in. But yes, 22 bytes is correct.
I just took the first part of the first data and converted below:
const char* foo = "\340\005";
printf("0x%x 0x%x %d %d\n",foo[0],foo[1], (int)foo[0], (int)foo[1]);
printf("0x%x 0x%x %d %d\n",foo[0],foo[1], (uint8_t)foo[0], (uint8_t)foo[1]);
printf("0x%x 0x%x %d %d\n",foo[0],foo[1], (uint16_t)foo[0], (uint16_t)foo[1]);
OUTPUTS
0xffffffe0 0x5 -32 5 0xffffffe0 0x5 224 5 0xffffffe0 0x5 65504 5
Also, on their documentation, they said UINT16 are LSB first. I don't know if they are talking about LSB first data when sending the data as parameter or LSB first data on both request and response. I tried the conversion below with LSB first.
I took the binary part of the first data, reversed it and converted below:
original:11011100 00000101 (0xdc 0x05 )
LSB first: 10100000 00111011 (0xa0 0x3b) (160 59)
By LSB first I think they are talking about the ordering of the bytes not the bits. so you just need to reverse the byte order. you can check the python code to make sure, but that is how I see their documentation. On May 11, 2016 2:04 AM, "Sabin Maharjan" notifications@github.com wrote:
@bhunt2 https://github.com/bhunt2 @spesialstyrker https://github.com/spesialstyrker
I forgot about the crc byte on response. I didn't count that in. But yes, 22 bytes is correct.
I just took the part of the first data and converted below:
const char* foo = "\340\005"; printf("0x%x 0x%x %d %d\n",foo[0],foo[1], (int)foo[0], (int)foo[1]); printf("0x%x 0x%x %d %d\n",foo[0],foo[1], (uint8_t)foo[0], (uint8_t)foo[1]); printf("0x%x 0x%x %d %d\n",foo[0],foo[1], (uint16_t)foo[0], (uint16_t)foo[1]);
OUTPUTS
0xffffffe0 0x5 -32 5 0xffffffe0 0x5 224 5 0xffffffe0 0x5 65504 5
Also, on their documentation, they said UINT16 are LSB first. I don't know if they are talking about when sending the data or on both request and response. But I tried the conversion below with LSB first.
I took the binary part of the first data, reversed it and converted below:
original:11011100 00000101 (0xdc 0x05 )
LSB first: 10100000 00111011 (0xa0 0x3b) (160 59)
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/bhunt2/QC1.0/issues/24#issuecomment-218223796
@bhunt2 @spesialstyrker 0xdc 0x05 with LSB byte is 0x05 0xdc.
0x5dc Is 1500 in decimal which is the value we expected.
Great, you should be able to move forward now. I will be available in a couple of hours to help if you need.
@sabmah
How are things going? Please regularly update how you are doing and if you need any assistance. Also, please push your code to the repository regularly so that I can look it over.
Thanks.
I'm trying to get it working on my code right now. I'll update if I have anything new
@sabmah
I was just looking through your documentation and I don't believe you made the change we discussed yesterday regarding the test plan. Each test should be written with clear criteria as to what is being sent and what is expected to received, along with what the final completion criteria is for each test.
The first test, which has been completed, has not been updated with the results stating it has passed.
The second test, is a little confusing as it does not really state what the plan is, but rather just describes what each of the steps could be.
In the third test, you again explain possible steps to take but do not clearly lay out what you will do. This leaves open many holes where issues may make it through your test and cause problems later on. You should decide on one option for obtaining height/throttle ratio and work with it, explaining why you have chosen that option and then test to see if that works with enough accuracy for the use case. If you will be increasing the throttle value in steps, don't forget you need to also state the timing for those increases. If you increase too quickly, the drone won't have time to move and settle before you take your measurements. It seems like this test would be for throttle only.
As discussed when we talked earlier, there should be a couple of other tests. For example I would think that there should be at least these two, Pitch Test and Task Completion Test.
If you look at my example test plan and previous comments you will see a good test plan clearly states the order and purpose of each step, along with the exact parameters of the test (i.e. what is being sent and received, expected and actual). The test should be written so that anyone can follow it and perform the exact same test. This means that the test is completely repeatable. This is necessary so that if in the test you discover a problem, you will be able to reproduce it by following your test plan. You know that it is fixed when it no longer appears when following the same test plan.
Please let me know if you have any questions about this. I want to make sure that the tests are very clear and understood before you ever trying to fly the drone via software control because it can be very dangerous. That is why the initial flight tests should all be done with short tethers so the drone can only move so far.
Please post information about what is happening here. Even just links to your documentation and tests is acceptable. This issue is a place for us to be able to work communicate with each other about the problem.