##대학의정석 추천 Tip(4/20).

** 꿀팁

**예전에 올렸던 the noun project가 왠일인지 문을 닫았길래 그럴싸한 아이콘 검색 툴들 급히 추가.


사용법이야 뭐 그냥 검색해서 다운받아 쓰면 되는 거고 복잡할 거 없지염 ㅇㅇ


개인적으로는 제일 심플한 Icomoon을 가장 좋아해서 캡처도 그걸로 했음!


[http://icomoon.io/app/]


[http://www.iconfinder.com/]


[http://www.iconarchive.com/]


그럼 중간고사 대체 발표를 준비하는 횽누나들에게 나름대로 도움이 되길 바라며 토요일 점심 먹으러 뿅! 


by ST_story 2013. 4. 20. 12:47

출처 http://blog.naver.com/tajideux/100113829791


아래의 글은 AutoCAD A2 (http://www.autodesksquare.co.kr/)에서 AutoCAD의 파워유저로 선정되어 활동하면서 쓴 글입니다제 블로그에도 계속해서 함께 게재할 예정입니다. A2 (에이스퀘어)에 아직 가입을 안하신 분들은 얼른 가입을 서두르세요앞으로 많은 관심 바랍니다원문은 아래 주소에서도 확인 가능합니다.

http://www.autodesksquare.co.kr/A2/a2Story/a2StoryView.jsp?seq=177&table=bbs_03

 

 

 필자는 이런 질문을 가장 많이 받는다. “어떻게 하면 AutoCAD를 정말 잘 할 수 있나요?” 라는 질문이다질문 속에는 숨은 뜻이 내포되어 있음을 필자는 알고 있다. “얼마나 잘하길래 저러나 두고 보자.” 라던가 한 방에 고수가 되는 마법의 알약 하나만 줘.” 라는 숨은 뜻이 있다이럴 때는 필자도 한 마디로 대답해주기 너무 난감해서 이렇게도 대답해 보고저렇게도 대답해 봤지만 이제 가장 확실한 방법을 하나 소개한다필자 혼자만 알고 있던 천기를 누설할 작정이다.

 

어느 정도 AutoCAD를 다뤄야 잘한다고 인정을 받을 수 있을까이 질문은 간단해 보이지만 그 대답은 천차만별이다손이 너무 빨라서 보이지 않을 정도가 되어야 할까모든 명령어를 모조리 외우고 있어야 할까프로그램을 개발할 줄 알아야 할까모두 틀린 얘기는 아닐 것이다하지만 분명히 기억해야 할 것은 AutoCAD를 사용하는 궁극적인 목적은 “CAD” 라는 것이다팔에 토시를 끼고 설계를 하다가 컴퓨터를 이용하여 설계하는 이유는 바로 정밀 설계와 대량 생산즉 정확성(accuracy), 효율성 (efficiency)과 생산성 (productivity) 때문이다쉽게 말하면 AutoCAD 를 이용해서 정확하고 빨리 일을 처리하는 사람이 결국 잘하는 사람일 것이다.

 

 최근의 CAD 산업은 IT 산업과 더불어 고도로 성장하여 산업 전반에 구조조정 바람이 불고 있다.산업 기반은 발전하고 있지만 이 발전은 실제로 피할 수 없는 업체들의 구조조정을 가져왔다현재 CAD 관련 산업 전반은 급속도로 체질을 개선하고 있는 중이다생산성은 유지하면서 끊임없이 자신의 몸집을 줄여 초(고효율을 추구하고 있다이런 추세는 속도가 점점 빨라져 한 동안 지속될 전망이다필자가 처음 취직할 때 이력서의 특기 항목에 “이 세상에서 AutoCAD를 제일 잘 합니다.” 라고 썼던 오만과 불손함이 최근의 추세에 비춰볼 때 이제는 모두에게 기본 덕목이 되어가고 있을지도 모르겠다.

 

얼마나 잘해야 AutoCAD를 잘하는 것이냐에 대한 질문을 많이 받는다때로는 얼마나 잘하길래 잘 한다는 얘기를 듣고 있나요?”와 같은 다소 공격적인 질문을 받기도 한다그럴 때마다 필자는 이렇게 대답한다. “하루에 도면을 몇 장 정도 그릴 수 있나요?”라고 반문한 후 저는 남들이 하루에 도면을 한 장 그린다면 저는 반 장도 못 그립니다하지만 예를 들어남들이 하루에 한 장씩 한 달 동안 30장 그릴 때, 10일을 투자해서 하루에 5장을 그릴 수 있는 프로그램을 개발해서 나머지 20일 동안 100장을 그릴 수 있습니다.”라고 대답한다. AutoCAD를 사용하는 목적과 앞으로의 목표는 바로 이 대답 안에 모두 들어 있다.

 

필자에게 가끔 인터뷰 요청이 온다그럴 때마다 꼭 빠지지 않는 질문이 하나 있는데 바로 서두에서 얘기했던 어떻게 하면 AutoCAD를 정말 잘 할 수 있나요?”라는 것이다. AutoCAD를 잘하기 위해 필자는 항상 영어 공부를 권하고 해외 사이트들과의 정보 교류를 주장한다그렇다면 정작 그런 주장을 하는 필자와 같은 고급 사용자들이 자주 가는 사이트들은 과연 어떤 곳들인가에 관한 질문들이 뒤따른다그렇다고 특별할 것은 없겠지만 어쨌든 몇 가지 추천하니 매일은 힘들더라도 최소한 일주일에 한 번쯤은 방문해야 한다대부분 미국 사용자들이고 블로그 위주로 정리했다내용의 참신함과 방대함을 유지하는 비결은 이들 중 다수가 Autodesk사의 직원들이기 때문이다자료를 저장하는 역할 뿐만 아니라 AutoCAD 홍보에도 노력하고 있기 때문이다특히 그들을 ‘내부자라고 표현했다아래 블로그들에 방문해서 이들의 모습을 사진으로 확인하면 놀랄 것이다왜냐하면 나이들이 대부분 40대 이상이기 때문이다필자의 멘토들이다. 40대를 훌쩍 넘어서도 AutoCAD를 사용하고진지하게 고민하고사용자들과 소통하는 모습이 아름답기까지 하다.

 

 드디어 한 방에 고수가 되는 마법의 알약을 공개한다아래의 사이트들을 메모해두고 열심히 방문해서 그들과 교류하고그들에게 배우면 된다.

 

1. http://autodesk.blogs.com/between_the_lines/

Shaan Hurley의 블로그이다. The Technical Marketing Manager for the Autodesk Platform Technologies Division (PTD)이다베타테스터로 임명될 때 Autodesk 코리아에서 직접 만났던 사람이고 이 사람의 블로그에는 AutoCAD에 관한 과거현재미래 모두가 총 망라되어 있다이곳은 내용들의 질적양적인 면이 상상을 초월한다. AutoCAD에 관해서는 감히 세계 최고의 블로그라 해도 과언이 아니다얼마 전 공개된 하루 평균 방문자 수가 수 천명 이상이라고 한다필자도 그 중 한 사람이다.

 

2. http://blog.naver.com/myautocad

대한민국 AutoCAD 공식 블로그 이다역시 내부자의 블로그답게 유익한 정보가 가득하다가장 좋은 점은 한글로 되어있다는 것이다하지만 안타깝게도 이 블로그를 제외하고는 안타깝게도 우리나라 안에서는 AutoCAD와 관련하여 괜찮은 블로그를 아직 발견하지 못했다사용자들의 분발을 희망한다.

 

3. http://civilcommunity.autodesk.com/blogs/blog/5/

Dominick Gallegos의 블로그이다. Civil 3D Technical Marketing Manager for Autodesk 이다역시 내부자이다필자가 토목 엔지니어인 관계로 가끔 들어가곤 하는데 토목 관련 3rd party 프로그램과Civil 3D등 방대한 자료가 있다.

 

4. http://lynn.blogs.com/

Lynn Allen의 블로그이다내부자로 보이지만 정확한 부서나 직책은 알지 못한다본인을Autodesk Technical Evangelist” 라고 소개하는 것을 찾을 수 있을 뿐이다본인이 AutoCAD를 전도하는 전도사라고 생각하는 모양이다. AutoCAD가 그녀에게는 신앙인 셈이다이곳은 정말 실전에 유용하고 다양한 기능 소개들이 포함되어 있다언젠가 글을 읽다가 궁금한 점이 있어서 메일을 보냈던 적이 있었는데 대단히 친절하게 답변해준다.

 

5. http://heidihewett.blogs.com/

Heidi Hewett의 블로그이다이 사람 역시 정확한 부서와 직책은 알지 못한다블로그의 제목부터AutoCAD insider이다얼마 전에 알게 되어 최근 자주 가고 있는 사이트이다. 2011버전에 관한 정보들이 많아서 베타테스터인 필자에게 유용한 곳이다물론 다른 유용한 자료도 너무나 많다특히 webcast 서비스가 가능한 점이 이색적이다.

 

6. http://rkmcswain.blogspot.com/

R.K. McSwain의 블로그이다내부자가 아닌 사용자의 블로그를 소개한다이 사람의 직업은 정확히 알려진 것이 없어서 추측하건대 AutoCAD 강사 정도되는 것 같다필자와 비슷한 성향을 가진 듯 보이다필자와 같이 캐드 재야인사라 불릴 자격이 있다정말 유용하고 다양한 정보가 가득하다특히 이 블로그에는 다른 주옥 같은 AutoCAD 관련 블로그들이 링크되어 있다는 점도 주목할 만 한다이곳에 링크된 사이트들 역시 필자가 자주 가는 곳들 이다.

 

7. http://lazydrafter.blogspot.com/

Todd Shackelford의 블로그이다직업은 건축 분야인 것으로 추정된다블로그 제목이 재미있다.하지만 블로그 운영은 전혀 게으르지 않다좋은 팁들이 많다.

 

8. http://www.integr-8.com/besidethecursor/

Richard Binning의 블로그이다역시 직업은 건축 분야이다이곳의 블로그 제목 역시 재미있다.이런 작은 부분에서 여유와 유머를 가진 문화가 때로는 부럽다커서 밖의 세상을 꿈꾸며 살아가는 멋진 사람이다이 사람은 알고 보면 AutoCAD 분야에서 유명한 사람이다해외 사이트 어디든 글을 읽다 보면 이 사람인 경우가 많다그만큼 활동의 폭이 넓은 사람이다.

 

9. http://www.caddmanager.com/CMB/

Mark W. Kiker의 블로그이다얼핏 보면 블로그가 아닌 듯이 보이지만 이 사람의 개인 블로그이다하지만 좀 더 자세히 보면 이 사이트의 존재 목적은 필자가 자주 강조해 온 우리에겐 생소한CAD 매니저들과의 정보 공유이다이 사이트를 추천하는 이유는 우리가 앞으로 나가야 할 방향이 여기에 있기 때문이다이곳에는 광범위한 AutoCAD에 대한 팁과 정보부터 협상 기술과 상대방을 설득시키는 방법 등과 같이 CAD 매니저가 갖추어야 할 덕목과 소양 등까지 총 망라되어 있다.

 

 여기까지는 필자 개인이 추천하는 사이트들이다가끔 필자의 덧글도 확인할 수 있을 것이다아래는 Shaan Hurley가 자신의 블로그인 http://autodesk.blogs.com/between_the_lines 에 포스팅한 글을 발췌한 것이다필자의 추천 사이트들과 겹치기도 하는데 정말 훌륭하고 소중한 사이트들의 주소, RSS 주소트위터 정보까지 포함되어 있다.

 

Shaan Hurley’s 
Between the Lines Blog

Blog:http://autodesk.blogs.com/ 
RSS: 
http://feeds2.feedburner.com/blogs/btl 
Twitter: 
http://twitter.com/mrcadman

Lynn Allen's Blog

Blog: http://lynn.blogs.com/ 
RSS: 
http://feeds.feedburner.com/typepad/lynnblog/lynn_allens_blog 
Twitter: 
http://twitter.com/lynn_allen

Heidi Hewett's 
AutoCAD Insider Blog

Blog: http://heidihewett.blogs.com/ 
RSS: 
http://feeds.feedburner.com/HeidiHewettsBlog 
Twitter: http://twitter.com/heidihewett

Guillermo Melantoni 
What a Mesh Blog

Blog: http://whatamesh.typepad.com/ 
RSS: 
http://feeds2.feedburner.com/WhatAMesh

Kate Morrical's 
LT Unlimited Blog

Blog: http://ltunlimited.typepad.com/ 
RSS: 
http://feeds.feedburner.com/ltunlimited 
Twitter: http://twitter.com/katemorrical

AutoCAD Support TeamWithout a Net Blog

Blog: http://withoutanet.typepad.com/ 
RSS: 
http://feeds2.feedburner.com/typepad/withoutanet 
Twitter: 
http://twitter.com/WithoutANet

Autodesk University Speakers Blog

Blog: http://auspeaker.wordpress.com/ 
RSS: 
http://auspeaker.wordpress.com/feed/

The AUGI Blog

Blog: http://augi.typepad.com/ 
RSS: 
http://augi.typepad.com/augi_news/rss.xml 
Twitter: 
http://twitter.com/BLAUGI

Brian Benton's 
CAD-a-Blog

Blog: http://cadablog.blogspot.com/ 
RSS: 
http://cadablog.blogspot.com/feeds/posts/default# 
Twitter: 
http://twitter.com/bcbenton


Robin Capper

Blog: http://rcd.typepad.com/rcd/ 
RSS: 
http://feeds.feedburner.com/RobinzBlog 
Twitter: 
http://twitter.com/robincapper

Edwin Prakoso 
CAD Notes

Blog: http://cad-notes.com/ 
RSS: 
http://feeds.feedblitz.com/CADNotes 
Twitter: 
http://twitter.com/cad_notes

Melanie Perry 
Mistress of Dorkness

Blog: http://mistressofthedorkness.blogspot.com/ 
RSS: 
http://feeds.feedburner.com/MistressOfTheDorkness 
Twitter: 
http://twitter.com/melanieperry

R.K. McSwain 
CAD Panacea

Blog: http://cadpanacea.com/ 
RSS: 
http://feeds.feedburner.com/cad_panacea

Curt Moreno 
Kung Fu Drafter

Blog: http://www.kungfudrafter.com/ 
RSS: 
http://feeds2.feedburner.com/kungfudrafter 
Twitter: http://twitter.com/wkfd

Mark Kiker 
CADDManager Blog

Blog: http://www.caddmanager.com/CMB/ 
RSS: 
http://feeds.feedburner.com/caddmanager/WP-feed 
Twitter: 
http://twitter.com/caddmanager

Jimmy Bergmark 
JTB World

Blog: http://blog.jtbworld.com/ 
RSS: 
http://feeds.feedburner.com/JtbWorld 
Twitter: 
http://twitter.com/jtbworld

Vladimír Michl 
Budweiser Blog

Blog: http://budweiser.xanadu.cz/ 
RSS: 
http://budweiser.xanadu.cz/feeds/posts/default# 
Twitter: 
http://twitter.com/VMichl

David Cohn 
CADman-DO

Blog: http://cadman-do.blogspot.com/ 
RSS: 
http://cadman-do.blogspot.com/feeds/posts/default#

Dean Saadallah 
LT is still AutoCAD

Blog: http://ltisacad.blogspot.com/ 
RSS: 
http://ltisacad.blogspot.com/feeds/posts/default#

 

이와 같이 AutoCAD를 잘 할 수 있는 마법의 알약을 소개했다나열된 사이트들을 자주 방문해서 글을 읽고 공부하면 단번에 최고의 유저가 될 수 있다이제 꼭꼭 숨겨두었던 필자만 알고 있는 비밀을 모조리 다 가르쳐줬는데 뭐가 더 필요한가공부는 자신이 하는 것이지 영화 매트릭스’ 처럼 가만히 누워 있으면 누군가 내 머리 속에 뭔가를 집어 넣어주는 것이 아니다.

 

 이것을 계기로 필자는 AutoCAD 관련 해외 유명 사이트들의 동향을 전달할 수 있는 코너를 기획하고 있다. “AutoCAD 해외 특파원 그림아이입니다.” (가제)라는 제목으로 그들의 생각의견최신 소식활동 모습 등을 그대로 번역하고때로는 필자 개인의 의견을 포함해서 전달할 생각이다이렇게 하려고 하는 이유는 그들이 AutoCAD를 어떻게 사용하고어떤 생각들을 하고 있는지를 전달해서 우리나라의 수많은 AutoCAD 전문가들을 움직여볼 생각이다우리는 왜 그런 생각을 못했는지왜 그렇게 지식들을 공유하고 있지 못했는지왜 그들보다 뒤쳐지고 있는지 끊임없이 성찰할 수 있는 계기가 되길 조심스럽게 희망해 본다.

by ST_story 2013. 4. 12. 20:09

출처 : http://www.nuclearprojects.com/ins/arduino_program.shtml


Programming Arduino To Read IMU
6/9/11

The very first step is figuring out how to read the 6DOF chip, which isn't too hard. The 6DOF outputs 6 analog channels, 3 for the gyros, and 3 for the accelerometers. I'm using the Arduino Deumilanove, which happens to have 6 analog pins.

Arduino and 6DOF IMU 
Arduino and 6DOF taped to back of CD case


Here's a bit of code for reading and displaying all 6 sensors:

//////////////////////////////////////////////////////////
// Simply reads the Razor 6DOF accelerometer/gyro and   //
// prints raw ADC values                                //
//////////////////////////////////////////////////////////

void setup(){
  analogReference(EXTERNAL);  // sets reference voltage to VREF
  Serial.begin(115200);
  delay(200);
}

void loop()
  {
  //Output the raw values
  Serial.print("Gyro x: ");
  Serial.print(analogRead(1));
  Serial.print(" | Gyro y: ");
  Serial.print(analogRead(0));
  Serial.print(" | Gyro z: ");
  Serial.print(analogRead(2));

  Serial.print("       Accel x: ");
  Serial.print(analogRead(5));
  Serial.print(" | Accel y: ");
  Serial.print(analogRead(4));
  Serial.print(" | Accel z: ");
  Serial.println(analogRead(3));

  delay(100);// slow down the serial output - Easier to read
}


If you use this code, just make sure to update the analogRead statements with your correct pins. With my board flat and close to level, I get the following 7 consecutive data readings: 

Gyro x: 379 | Gyro y: 380 | Gyro z: 377       Accel x: 504 | Accel y: 508 | Accel z: 617
Gyro x: 379 | Gyro y: 380 | Gyro z: 377       Accel x: 504 | Accel y: 508 | Accel z: 618
Gyro x: 378 | Gyro y: 380 | Gyro z: 378       Accel x: 504 | Accel y: 509 | Accel z: 619
Gyro x: 379 | Gyro y: 381 | Gyro z: 377       Accel x: 505 | Accel y: 509 | Accel z: 618
Gyro x: 379 | Gyro y: 380 | Gyro z: 377       Accel x: 504 | Accel y: 508 | Accel z: 618
Gyro x: 379 | Gyro y: 381 | Gyro z: 377       Accel x: 504 | Accel y: 508 | Accel z: 618
Gyro x: 379 | Gyro y: 380 | Gyro z: 377       Accel x: 504 | Accel y: 509 | Accel z: 618


The numbers will fluctuate a little bit as you can see from my data. It's normal, caused by noise. 

Next, turning those raw ADC values into useable numbers! The sensors each output a voltage somewhere between 0 and 3.3V. For the gyros, which measures rate (in deg/sec), they have a sensitivity of 3.33mV/deg/sec according to the spec sheet. The accelerometers, which measure gravitational acceleration (in g's), have a sensitivity of about 330mV/g. The ADC gives a value proportional to the voltage it receives, 0 to 1023 quids (10-bit resolution). Since the 6DOF board uses 3.3V, I hooked the Arduino's VREF pin to the 3.3V, which scales the ADC to the same 3.3V (as opposed to 5V). So the ADC will give me, for example, 1023 if it reads 3.3V. Or, about 512 quids for 1.65V (1023/1.65=512), etc. It's linear, so the math is easy. 


Here's the basic equations for doing the conversions: 

Gyro:
    Gyro_Rate = (Gyro_ADC_Value - Zero_Voltage_Value) * (3.3V/1023) / Gyro_Sensitivity
The zero_voltage_value is simply the initial ADC value of the sensor when it's not moving. You can read and store this value during setup. In the case of the gyro, when it's not moving, the rate should be zero, so we must zero out the gyro in the equation. 

Even though the math is easy, there is nothing better than a worked-out example! In this example, I've read an ADC value 411 from the x-axis gyro during a rotation. My zero_voltage_value is 379 from my data above. 

    GyroRateX = (411-379) * (3.3/1023) / 0.00333  ----> (0.00333 is 3.33mV)
    GyroRateX =  32 * 0.0032258 / 0.00333
    GyroRateX = 30.999 deg/s
    
From this, I can see I'm rotating at a rate of about 31 degrees/second. Now how do use this to keep track of my overall angle of rotation? Easy! This can be done by taking regular readings and integrating them over a specified period of time. 

Lets say I take readings every 20ms, or 0.020 seconds. My GyroRateX value gives me degrees/second. If I multiply that by 0.02sec, I'll get the total angle the sensor is rotated during that short period of time. This of course assumes the rate was constant over that time. I can keep track of my overall rotation angle by adding up these small rotations. Example:
     GyroAngleX += GyroRateX * 0.02
If you've not seen it, the "+=" symbology just says to add the calculated value on the right to GyroAngleX. 



Accelerometer 

I'm going to show two different ways of calculating angle of rotation from the accelerometer data. Although the common way of doing it is using force vectors, I wont show that here. 

First method: The first part of the calculation is exactly the same as for the gyro. I need to zero the ADC readings, convert any remaining ADC values into quids, then convert that into voltage. The voltage can then be divided by the accelerometer sensitivity, like we did with the gyro.
    Accel_X = (Accel_ADC_Value - Zero_Voltage_Value) * (3.3V/1023) / Accel_Sensitivity 
It should be noted that the zero_voltage_value in this case is with respect to the x-axis accelerometer. Now for a worked example:
    Accel_X = (558 - 504) * (3.3/1023) / 0.33 ----> (0.33 is 330mV)
    Accel_X = 54 * 0.0032258 / 0.33
    Accel_X = 0.528 G's
    
Now to convert this value into an angle, we can take the Arcsin of the value. The result will be in radians. Since 1 radian = 180/PI or 57.2957795 degrees, we can just multiply the result accordingly to get degrees.
    Accel_Angle_X = asin(Accel_X) * 57.2957795
    Accel_Angle_X = asin(0.528) * 57.2957795
    Accel_Angle_X = 0.556 * 57.2957795
    Accel_Angle_X = 31.87 degrees
    
I had found this calculation through my research. It took me a minute to think about how on earth you could go from a G-force directly to a precise angle. But it's really pretty simple...

Firstly, this only works for the X and Y axis's. Basically, the accelerometers measure the force caused by gravity along the axis of the sensor. When the X and Y accel's are parallel with the Earth's surface, the force of gravity on the sensors is zero. When either sensor is perpendicular to the Earth's surface, it then measures 1-G. While at any other angle, the measured force will be between 0 and 1. Hence, as long as we're only measuring gravity (tilt angles), this equation works well. 
Accelerometer perpendicular to gravity Accelerometer parallel with gravity 



Second method: This next method of calculation is what I've decided to use. It uses the Arduino's Map() function. I came upon this method here: bilder.org/?s=adxl335. It's simple, straight forward, and works really well. You'll want to read that page for a full explanation, which I'll only skim here. 

Basically, for each axis, the map() function will take two different ranges and "re-map" a value from one range to the other. The two ranges are the min/max ADC values for each axis, and the other range is -90 to 90 degrees, which we want to map to. This is done for all 3 accelerometer axis's. The results are fed through a couple atan2 functions, which give us a final X and Y angle. 

Here is the actual source code I use for this:
//The minimum and maximum values that came from
//the accelerometer...
//You very well may need to change these
int minValx = 403;
int maxValx = 610;

int minValy = 400;
int maxValy = 614;

int minValz = 413;
int maxValz = 619;
  //convert read values to degrees -90 to 90 - Needed for atan2
  int xAng = map(AN[3], minValx, maxValx, -90, 90);
  int yAng = map(AN[4], minValy, maxValy, -90, 90);
  int zAng = map(AN[5], minValz, maxValz, -90, 90);

  //Caculate 360deg values like so: atan2(-yAng, -zAng)
  //atan2 outputs the value of -π to π (radians)
  //We are then converting the radians to degrees
  AccAngleX = Rad2Deg * (atan2(-xAng, -zAng) + PI);
  AccAngleY = Rad2Deg * (atan2(-yAng, -zAng) + PI);

In the final AccAngle statements, the original code had -xAng and -yAng the other way around. It was causing my axis's to be reversed, so I swapped them, seems to have fixed it. I believe this is due to the physical orientaion that the sensor chips are mounted to each other. 



Min/Max Values... 

The above code showed the minimum and maximum values I obtained from my sensors. I created an easy Sketch for obtaining these. Run this following sketch and view the results in the Serial Monitor. For each axis, rotate it through its furthest extents (+-90deg). The numbers will update everytime a new min or max is read. Make sure not to exert any acceleration on the axis you're measuring though. You may need to support your board on a table as you're rotating it. The code:

// These hold accelerometer maximum/minimum values
int aX_max=0, aX_min=0, aY_max=0, aY_min=0, aZ_max=0, aZ_min=0;

// Raw data variables
int aX, aY, aZ;


void setup()
{
  analogReference(EXTERNAL);  // sets reference voltage to use voltage applied to VREF pin
  Serial.begin(115200);
  
  delay(100);  // give some time for warm-up

  // Read and set starting values
  aX = analogRead(5);	// <- make sure to set your pins here
  aY = analogRead(4);
  aZ = analogRead(3); 
  
  aX_max = aX;
  aX_min = aX;
  aY_max = aY;
  aY_min = aY;
  aZ_max = aZ;
  aZ_min = aZ;
  
}

void loop()
{
  
  aX = analogRead(5);
  aY = analogRead(4);
  aZ = analogRead(3);  
  

aX_max = max(aX_max, aX);
aX_min = min(aX_min, aX);
aY_max = max(aY_max, aY);
aY_min = min(aY_min, aY);
aZ_max = max(aZ_max, aZ);
aZ_min = min(aZ_min, aZ);
 
  Serial.print("Accelerometer... axis(min,max):    X(");
  Serial.print(aX_min);
  Serial.print(",");
  Serial.print(aX_max);
  Serial.print(")  Y(");
  Serial.print(aY_min);
  Serial.print(",");
  Serial.print(aY_max);
  Serial.print(")  Z(");
  Serial.print(aZ_min);
  Serial.print(",");
  Serial.print(aZ_max);

  
    Serial.println(" ");
delay(100);
}




Sensor Fusion 

The next step is to take the calculated angles from both the gyros and accelerometers and combine them in a way that I can get a stable, accurate result. The gyro angles are very good and stable for the short term, but they can quickly drift and become inaccurate. The accels give me good angles over a longer period of time, but in the short run, they can be noisy. So I'll need to use the gyros as the base of my result, and correct towards the angles produced by the accelerometers over time. For this, I'm using a complementary filter of sorts, as described in this document, filter.pdf. The general equation is: 

    angle = (0.98)*(angle + gyro * dt) + (0.02)*(x_acc);
I've had excellent results with this, with no noticeable lag time using readings at 10ms intervals. 

Here is the complete code for reading values from the 6DOF board and converting the ADC values to useable angles. The print output is formatted to be used with my attitude display software. Note: This code, and my software, do NOT provide full 360 degrees of freedom (other than Z-axis). This code gives me exactly what I need, and only what I need, which is +-90 degrees of both pitch and yaw. Remember, this entire project is purpose-built for fixed-wing UAV purposes, only. You can of course modify the code for full 360-degree resolution, but I can not assist with that. 

#define Gyro_Sens 0.00333 // Gyro sensitivity = 3.33mV/deg/s
#define VPQ 0.00322581 // Volts Per Quid --- value of 3.3V/1023
#define ADC_Avg_Num  100.// Number of averaging readings for calibration
#define Rad2Deg 57.2957795 // 1 radian = 57.2957795 degrees
#define Deg2Rad 0.0174532925 // 0.0174532925 rads = 1 deg

//The minimum and maximum values that came from
//the accelerometer...
//You very well may need to change these
int minValx = 403;
int maxValx = 610;

int minValy = 401;
int maxValy = 614;

int minValz = 413;
int maxValz = 619;

//Calibration variables
float Gx_Cal, Gy_Cal, Gz_Cal;

float GyroRateX=0, GyroRateY=0, GyroAngleZ=0, GyroAngleZ_dt=0;
float AccAngleX=0, AccAngleY=0, AccAngleZ=0;

float Pitch, Yaw, Roll;

int AN[6];  // Hold analogRead data

unsigned long pre_time, print_clock=0;
float dtime;


void setup()
{
  analogReference(EXTERNAL);  // sets reference voltage to use voltage applied to VREF pin
  Serial.begin(115200);
  delay(300);  // Give things time to "warm-up"

  Calibrate(); // Calibrate sensors
  pre_time = millis(); //store current time to be used as "previous" time
}



void loop()
{

  if(millis()-pre_time>=20) // Read ADC and does Calculations every 20ms
  {
    dtime=millis()-pre_time;  //current time - previous time
    pre_time = millis(); //store current time to be used as "previous" time
    dtime=dtime/1000.;

    Read_ADC();
    Calculate();
  }


  if(millis()-print_clock>=50)  //print every 50ms
  {
  Serial.print(Pitch);
  Serial.print(",");
  Serial.print(Roll);
  Serial.print(",");
  Serial.println(Yaw);
  
  print_clock=millis();  // store current time
  
  } //end if


}





///////////////////////////////////////////////////////////////////////
////////////////////////   Functions    ///////////////////////////////
///////////////////////////////////////////////////////////////////////



void Read_ADC(void)
{

  AN[0] = analogRead(1); // Gyro_X
  AN[1] = analogRead(0); // Gyro_Y
  AN[2] = analogRead(2); // Gyro_Z
  AN[3] = analogRead(5); // Acc_X
  AN[4] = analogRead(4); // Acc_Y
  AN[5] = analogRead(3); // Acc_Z
}



void Calculate(void)
{

// Gyro portion
//----------------------------------------------------------------
  GyroRateX = -1.0*dtime * (((AN[0]*3.3)/1023.-Gx_Cal)/Gyro_Sens);
  GyroRateY = dtime * (((AN[1]*3.3)/1023.-Gy_Cal)/Gyro_Sens);
  
  GyroAngleZ_dt = dtime * (((AN[2]*3.3)/1023.-Gz_Cal)/Gyro_Sens);
  GyroAngleZ += -1.0 * GyroAngleZ_dt * (1/(cos(Deg2Rad*Roll))); // convert Roll angle to Rads, find sin to use as scaler for Yaw

  if(GyroAngleZ<0) GyroAngleZ+=360;    // Keep within range of 0-360 deg
  if(GyroAngleZ>=360) GyroAngleZ-=360;
//----------------------------------------------------------------

  //convert read values to degrees -90 to 90 - Needed for atan2
  int xAng = map(AN[3], minValx, maxValx, -90, 90);
  int yAng = map(AN[4], minValy, maxValy, -90, 90);
  int zAng = map(AN[5], minValz, maxValz, -90, 90);

  //Caculate 360deg values like so: atan2(-yAng, -zAng)
  //atan2 outputs the value of -π to π (radians)
  //We are then converting the radians to degrees
  AccAngleX = Rad2Deg * (atan2(-xAng, -zAng) + PI);
  AccAngleY = Rad2Deg * (atan2(-yAng, -zAng) + PI);

  // Keep angles between +-180deg
  if(AccAngleX>180) AccAngleX=AccAngleX-360;

  if(AccAngleY<=180) AccAngleY=-1.0*AccAngleY;
  if(AccAngleY>180) AccAngleY=360-AccAngleY;

  // Final values...
  Roll = (0.98)*(Roll + GyroRateX) + (0.02)*(AccAngleX);
  Pitch = (0.98)*(Pitch + GyroRateY) + (0.02)*(AccAngleY);
  Yaw = GyroAngleZ;
}


// Reads and averages ADC values for calibration
float Avg_ADC(int ADC_In)
{
  long ADC_Temp=0;
  for(int i=0; i<ADC_Avg_Num; i++)
  {
    ADC_Temp = ADC_Temp+analogRead(ADC_In);
    delay(10); // Delay 10ms due to gyro bandwidth limit of 140Hz (~7.1ms)
  }
  return VPQ*(ADC_Temp/ADC_Avg_Num); //Average ADC, convert to volts
}

void Calibrate(void)
{
  Gx_Cal = Avg_ADC(1); // Gyro_x on pin 1
  Gy_Cal = Avg_ADC(0); // Gyro_y on pin 0
  Gz_Cal = Avg_ADC(2); // Gyro_z on pin 2
}

////////////////////////
//////// END CODE //////
////////////////////////



You can see a video of this code in action on the next page, Attitude Indicator In C#

One piece of the code which I did not talk about is the section calculating the value for GyroAngleZ, as this is an active work-in-progress. Picture the 6DOF board installed on an aircraft. With both the aircraft and the 6DOF board flat and level, the Z-axis gyro accurately describes the yaw of the aircraft. However, if the aircraft was in a turn, only a fraction of the turn would be read by the Z-gyro. So I needed a way to account for the change in roll angle with respect to the Z-gyro. I assume aircraft pitch is constant. The code above shows the mathematical formula I came up with, although it may need some more work. 

Still left to do... Next to do is implement code for fusing the Z-gyr

by ST_story 2012. 12. 28. 20:14
| 1 2 3 4 5 |