diff --git a/_sources/lib/Aruco.rst.txt b/_sources/lib/Aruco.rst.txt
new file mode 100644
index 0000000..51059ae
--- /dev/null
+++ b/_sources/lib/Aruco.rst.txt
@@ -0,0 +1,83 @@
+.. _lib_vision:
+
+Aruco
+*******
+
+Examples
+=========
+
+Recognizing ArUco tags
+-------------------------
+
+.. code-block:: python
+
+ import time
+ import cv2
+ from cv2 import aruco
+ from compLib import Vision
+
+ ARUCO_DICT = cv2.aruco.Dictionary_get(aruco.DICT_6X6_250)
+ ARUCO_PARAMETERS = aruco.DetectorParameters_create()
+
+ def getTagCenterFromFrame(id, frame):
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
+
+ corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, ARUCO_DICT, parameters = ARUCO_PARAMETERS)
+ frame = aruco.drawDetectedMarkers(frame.copy(), corners, ids)
+
+ if ids is None:
+ return frame, None, None
+
+ for tag_id, corner in zip(ids, corners):
+ if (tag_id[0] == id):
+
+ x, y = 0, 0
+ for i in range(4):
+ x += corner[0][i][0] * 0.25
+ y += corner[0][i][1] * 0.25
+
+ return frame, x, y
+ return frame, None, None
+
+ # Get the center from the aruco tag with the specified id
+ # in pixel coordinates (0-640, 0-480)
+ def getTagPosition(id):
+ frame = Vision.Streaming.get_frame()
+ frame, x, y = getTagCenterFromFrame(id, frame)
+ Vision.Streaming.publish_frame(frame)
+ return x, y
+
+ # Get the normalized center coordinates from the aruco tag
+ # with the specified id
+ # left is -1, right +1
+ # bottom is -1, top +1
+ def getNormalizedTagPosition(id):
+ frame = Vision.Streaming.get_frame()
+ frame, x, y = getTagCenterFromFrame(id, frame)
+ Vision.Streaming.publish_frame(frame)
+
+ if x is None or y is None:
+ return None, None
+
+ height, width = frame.shape[:2]
+ x = x / width * 2.0 - 1.0
+ y = -(y / height * 2.0 - 1.0)
+ return x, y
+
+ if __name__ == '__main__':
+
+ desiredID = 11
+
+ while True:
+ x, y = getNormalizedTagPosition(desiredID)
+
+ if x is not None:
+ print("X Coordinate: ", x)
+ else:
+ print("Tag not found")
+
+
+This example shows how to recognize ArUco tags based on their id and position.
+You can specify an ID of the tag you want to use and if it's found, the coordinates of the center are returned.
+With the normalized function this is very easy: The x-coordinate is -1 on the left, 1 on the right and 0 in the center of the screen, same for y.
+This way it is quite simple to act on the position of the tag.
diff --git a/genindex.html b/genindex.html
index c51a6b6..22e7db9 100644
--- a/genindex.html
+++ b/genindex.html
@@ -83,6 +83,7 @@
diff --git a/searchindex.js b/searchindex.js
index 4c9618c..f9fc7ac 100644
--- a/searchindex.js
+++ b/searchindex.js
@@ -1 +1 @@
-Search.setIndex({docnames:["index","lib/Api","lib/Battery","lib/Buzzer","lib/IRSensor","lib/IRWrapper","lib/Linefollower","lib/Logging","lib/Motor","lib/Servo","lib/Vision","other/usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["index.rst","lib/Api.rst","lib/Battery.rst","lib/Buzzer.rst","lib/IRSensor.rst","lib/IRWrapper.rst","lib/Linefollower.rst","lib/Logging.rst","lib/Motor.rst","lib/Servo.rst","lib/Vision.rst","other/usage.rst"],objects:{"compLib.Api":{DoubleElim:[1,0,1,""],Position:[1,0,1,""],Seeding:[1,0,1,""]},"compLib.Api.DoubleElim":{get_goal:[1,1,1,""],get_items:[1,1,1,""],get_opponent:[1,1,1,""],get_position:[1,1,1,""],get_scores:[1,1,1,""]},"compLib.Api.Seeding":{get_park:[1,1,1,""],pay_park:[1,1,1,""],simon_says:[1,1,1,""]},"compLib.Battery":{Battery:[2,0,1,""]},"compLib.Battery.Battery":{percent:[2,1,1,""]},"compLib.Buzzer":{Buzzer:[3,0,1,""]},"compLib.Buzzer.Buzzer":{set:[3,1,1,""]},"compLib.IRSensor":{IRSensor:[4,0,1,""]},"compLib.IRSensor.IRSensor":{bottom_left:[4,1,1,""],bottom_left_analog:[4,1,1,""],bottom_middle:[4,1,1,""],bottom_middle_analog:[4,1,1,""],bottom_right:[4,1,1,""],bottom_right_analog:[4,1,1,""],top_left_percent:[4,1,1,""],top_right_percent:[4,1,1,""]},"compLib.IRWrapper":{IRWrapper:[5,0,1,""]},"compLib.IRWrapper.IRWrapper":{adjust_for_calibration:[5,1,1,""],bottom_left_calibrated:[5,1,1,""],bottom_middle_calibrated:[5,1,1,""],bottom_right_calibrated:[5,1,1,""],calibrate:[5,1,1,""]},"compLib.LogstashLogging":{Logging:[7,0,1,""]},"compLib.LogstashLogging.Logging":{get_logger:[7,1,1,""],set_debug:[7,1,1,""]},"compLib.Motor":{Motor:[8,0,1,""]},"compLib.Motor.Motor":{all_off:[8,1,1,""],power:[8,1,1,""]},"compLib.Servo":{Servo:[9,0,1,""]},"compLib.Servo.Servo":{set_position:[9,1,1,""],setup_position:[9,1,1,""]},"compLib.Vision":{__Streaming:[10,0,1,""]},"compLib.Vision.__Streaming":{get_frame:[10,1,1,""],publish_frame:[10,1,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"]},objtypes:{"0":"py:class","1":"py:method"},terms:{"001":[6,10],"100":[2,4,6,8],"1000":5,"1023":4,"2021":0,"204":1,"403":1,"500":6,"750":6,"9898":10,"break":6,"class":[0,1,4,5,9,10],"float":[5,8,9],"import":[1,2,3,4,5,6,7,8,10,11],"int":[1,2,4,8,9],"return":[1,2,4,5,7,10],"static":[1,2,3,4,5,7,8,9],"true":[3,4,6,10],"while":[4,6,10],BUT:10,For:10,NOT:10,The:[5,10],Use:10,Used:[2,3],Using:0,__main__:[6,11],__name__:[6,11],__stream:10,access:4,active_break:6,adjust:5,adjust_for_calibr:5,afterward:5,all:[1,5,8],all_off:8,alwai:1,analog:0,angl:9,api:0,around:5,automat:10,back:1,back_mult:6,backward:11,batteri:0,becaus:10,beep:11,between:[2,4,5,8,9],bin:11,bit:[4,10],black:[5,6],bool:[3,4],bot:[5,6],bottom:[4,5],bottom_left:4,bottom_left_analog:4,bottom_left_calibr:[5,6],bottom_middl:4,bottom_middle_analog:4,bottom_middle_calibr:[5,6],bottom_right:4,bottom_right_analog:4,bottom_right_calibr:[5,6],bright:4,browser:10,buffer:10,buup:11,buzzer:0,calibr:[0,6],call:0,cam:10,camera:10,can:[1,7,10],captur:10,channel:9,check:1,chessboard:0,code:1,color_bgr2grai:10,color_break:6,come:10,commun:[1,7],competit:7,complib:[0,1,2,3,4,5,6,7,8,9,10,11],connect:[8,9,10],control:[8,9],convert:10,coordin:1,corner:10,correct:1,creat:10,criteria:10,current:1,cv2:10,cvtcolor:10,datastructur:1,debug:7,def:[6,11],degre:1,detect:[0,4],dict:1,dictionari:1,differ:4,displai:10,document:[0,10],doesn:6,done:[5,10],doubl:0,doubleelim:1,draw:10,drawchessboardcorn:10,drive:[0,1,6],dure:9,ein:11,elif:[1,6],elimin:0,els:[1,6],enabl:5,exampl:0,fail:1,fals:[3,6],field:1,filter:5,find:10,findchessboardcorn:10,follow:6,follow_till_lin:6,format:[4,5,6],forward:11,frame:10,from:[1,2,3,4,5,6,7,8,10,11],game:1,get:[1,2,4,7,10],get_fram:10,get_goal:1,get_item:1,get_logg:7,get_oppon:1,get_park:1,get_posit:1,get_scor:1,goal:1,grab:10,grai:10,grayscal:10,hallo:11,handl:10,here:10,hold:1,hopefulli:1,how:10,http:10,ich:11,imag:10,includ:1,indexerror:8,infrar:0,initi:6,instanc:10,instantli:6,interact:[2,3],interfac:10,internet:10,irsensor:[4,5],irwrapp:[5,6],item:1,json:1,lag:10,left:[4,5,6,8],level:7,librari:7,like:[1,10],line:[5,6],linefollow:0,list:1,littl:10,log:0,logger:7,logstash:7,logstashlog:7,look:[1,10],main:11,make:1,manual:7,max:[6,8],maximum:5,mayb:0,middl:[4,5,6],might:10,min:6,minimum:5,modul:[0,1],motor:[0,1,6,11],move:1,need:10,newest:10,next:1,none:10,note:10,now:1,object:[1,7],off:[0,6],offset:9,onto:[6,10],opencv:0,oppon:1,organ:7,output:10,own:10,pai:1,paramet:[3,8,9,10],park:1,parkingsapc:1,pass:6,pay_park:1,percent:[2,8],percentag:[0,4,8],point:[1,10],port:[8,9,11],posit:[0,9,10],power:[6,8,11],print:[0,1,4,5,6,11],process:[9,10],provid:10,publish:10,publish_fram:10,put:[5,6],python:7,rais:8,rang:[4,8,11],raspberri:10,raw:5,raw_valu:5,read:5,realtim:10,record:10,request:1,respond:1,ret:10,right:[4,5,6,8],robot:[1,4,9,11],rotat:1,rtmp:10,run:10,sai:1,score:1,screenshot:10,second:[5,10],seed:0,self:1,sensor:[0,6],server:[1,10],servo:0,set:[3,8,9],set_debug:7,set_posit:9,setup:9,setup_posit:9,should:[1,7,10],show:10,signal:4,similar:1,simon:1,simon_sai:1,simpl:0,sleep:[3,6,11],some:[1,10],someth:1,specifi:8,speed:[6,8],statu:[1,4],straight:0,straight_spe:6,stream:0,success:1,take:10,term_criteria_ep:10,term_criteria_max_it:10,test:[0,10],thi:[1,5,7,10],till:6,time:[3,6,11],top:[4,8],top_left_perc:4,top_right_perc:4,tupl:1,turn:[0,8],turn_spe:6,type:[1,2,4,5,7],usag:0,use:[7,10],used:[0,1,5,7,8,9],using:[1,10],valu:[4,5],view:10,vision:0,wait:10,want:10,web:10,webserv:10,websit:10,whatev:10,when:[7,10],which:[1,8,10],white:5,wrapper:0,yet:1,you:10,your:10,your_raspi_ip:10,yourself:10,zone:1},titles:["Robo4you Competition Library","Api","Battery","Buzzer","Infrared Sensor","Infrared Wrapper","Linefollower Examples","Logging","Motor","Servo","Vision","Usage"],titleterms:{"class":[2,3,7,8],Using:10,analog:[4,5],api:1,batteri:2,buzzer:3,calibr:5,call:1,chessboard:10,competit:0,content:0,detect:10,document:[2,3,7,8],doubl:1,drive:8,elimin:1,exampl:[1,2,3,4,5,6,7,8,10],infrar:[4,5],librari:0,linefollow:6,log:7,mayb:8,modul:10,motor:8,off:3,opencv:10,percentag:2,posit:1,print:2,robo4y:0,seed:1,sensor:[4,5],servo:9,simpl:6,straight:8,stream:10,test:4,turn:[3,7],usag:11,vision:10,wrapper:5}})
\ No newline at end of file
+Search.setIndex({docnames:["index","lib/Api","lib/Aruco","lib/Battery","lib/Buzzer","lib/IRSensor","lib/IRWrapper","lib/Linefollower","lib/Logging","lib/Motor","lib/Servo","lib/Vision","other/usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["index.rst","lib/Api.rst","lib/Aruco.rst","lib/Battery.rst","lib/Buzzer.rst","lib/IRSensor.rst","lib/IRWrapper.rst","lib/Linefollower.rst","lib/Logging.rst","lib/Motor.rst","lib/Servo.rst","lib/Vision.rst","other/usage.rst"],objects:{"compLib.Api":{DoubleElim:[1,0,1,""],Position:[1,0,1,""],Seeding:[1,0,1,""]},"compLib.Api.DoubleElim":{get_goal:[1,1,1,""],get_items:[1,1,1,""],get_opponent:[1,1,1,""],get_position:[1,1,1,""],get_scores:[1,1,1,""]},"compLib.Api.Seeding":{get_park:[1,1,1,""],pay_park:[1,1,1,""],simon_says:[1,1,1,""]},"compLib.Battery":{Battery:[3,0,1,""]},"compLib.Battery.Battery":{percent:[3,1,1,""]},"compLib.Buzzer":{Buzzer:[4,0,1,""]},"compLib.Buzzer.Buzzer":{set:[4,1,1,""]},"compLib.IRSensor":{IRSensor:[5,0,1,""]},"compLib.IRSensor.IRSensor":{bottom_left:[5,1,1,""],bottom_left_analog:[5,1,1,""],bottom_middle:[5,1,1,""],bottom_middle_analog:[5,1,1,""],bottom_right:[5,1,1,""],bottom_right_analog:[5,1,1,""],top_left_percent:[5,1,1,""],top_right_percent:[5,1,1,""]},"compLib.IRWrapper":{IRWrapper:[6,0,1,""]},"compLib.IRWrapper.IRWrapper":{adjust_for_calibration:[6,1,1,""],bottom_left_calibrated:[6,1,1,""],bottom_middle_calibrated:[6,1,1,""],bottom_right_calibrated:[6,1,1,""],calibrate:[6,1,1,""]},"compLib.LogstashLogging":{Logging:[8,0,1,""]},"compLib.LogstashLogging.Logging":{get_logger:[8,1,1,""],set_debug:[8,1,1,""]},"compLib.Motor":{Motor:[9,0,1,""]},"compLib.Motor.Motor":{all_off:[9,1,1,""],power:[9,1,1,""]},"compLib.Servo":{Servo:[10,0,1,""]},"compLib.Servo.Servo":{set_position:[10,1,1,""],setup_position:[10,1,1,""]},"compLib.Vision":{__Streaming:[11,0,1,""]},"compLib.Vision.__Streaming":{get_frame:[11,1,1,""],publish_frame:[11,1,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"]},objtypes:{"0":"py:class","1":"py:method"},terms:{"001":[7,11],"100":[3,5,7,9],"1000":6,"1023":5,"2021":0,"204":1,"403":1,"480":2,"500":7,"640":2,"750":7,"9898":11,"break":7,"class":[0,1,5,6,10,11],"float":[6,9,10],"function":2,"import":[1,2,3,4,5,6,7,8,9,11,12],"int":[1,3,5,9,10],"return":[1,2,3,5,6,8,11],"static":[1,3,4,5,6,8,9,10],"true":[2,4,5,7,11],"while":[2,5,7,11],BUT:11,For:11,NOT:11,The:[2,6,11],Use:11,Used:[3,4],Using:0,With:2,__main__:[2,7,12],__name__:[2,7,12],__stream:11,access:5,act:2,active_break:7,adjust:6,adjust_for_calibr:6,afterward:6,all:[1,6,9],all_off:9,alwai:1,analog:0,angl:10,api:0,around:6,aruco:0,aruco_dict:2,aruco_paramet:2,automat:11,back:1,back_mult:7,backward:12,base:2,batteri:0,becaus:11,beep:12,between:[3,5,6,9,10],bin:12,bit:[5,11],black:[6,7],bool:[4,5],bot:[6,7],bottom:[2,5,6],bottom_left:5,bottom_left_analog:5,bottom_left_calibr:[6,7],bottom_middl:5,bottom_middle_analog:5,bottom_middle_calibr:[6,7],bottom_right:5,bottom_right_analog:5,bottom_right_calibr:[6,7],bright:5,browser:11,buffer:11,buup:12,buzzer:0,calibr:[0,7],call:0,cam:11,camera:11,can:[1,2,8,11],captur:11,center:2,channel:10,check:1,chessboard:0,code:1,color_bgr2grai:[2,11],color_break:7,come:11,commun:[1,8],competit:8,complib:[0,1,2,3,4,5,6,7,8,9,10,11,12],connect:[9,10,11],control:[9,10],convert:11,coordin:[1,2],copi:2,corner:[2,11],correct:1,creat:11,criteria:11,current:1,cv2:[2,11],cvtcolor:[2,11],datastructur:1,debug:8,def:[2,7,12],degre:1,desiredid:2,detect:[0,5],detectmark:2,detectorparameters_cr:2,dict:1,dict_6x6_250:2,dictionari:1,dictionary_get:2,differ:5,displai:11,document:[0,11],doesn:7,done:[6,11],doubl:0,doubleelim:1,draw:11,drawchessboardcorn:11,drawdetectedmark:2,drive:[0,1,7],dure:10,easi:2,ein:12,elif:[1,7],elimin:0,els:[1,2,7],enabl:6,exampl:0,fail:1,fals:[4,7],field:1,filter:6,find:11,findchessboardcorn:11,follow:7,follow_till_lin:7,format:[5,6,7],forward:12,found:2,frame:[2,11],from:[1,2,3,4,5,6,7,8,9,11,12],game:1,get:[1,2,3,5,8,11],get_fram:[2,11],get_goal:1,get_item:1,get_logg:8,get_oppon:1,get_park:1,get_posit:1,get_scor:1,getnormalizedtagposit:2,gettagcenterfromfram:2,gettagposit:2,goal:1,grab:11,grai:[2,11],grayscal:11,hallo:12,handl:11,height:2,here:11,hold:1,hopefulli:1,how:[2,11],http:11,ich:12,ids:2,imag:11,includ:1,indexerror:9,infrar:0,initi:7,instanc:11,instantli:7,interact:[3,4],interfac:11,internet:11,irsensor:[5,6],irwrapp:[6,7],item:1,json:1,lag:11,left:[2,5,6,7,9],level:8,librari:8,like:[1,11],line:[6,7],linefollow:0,list:1,littl:11,log:0,logger:8,logstash:8,logstashlog:8,look:[1,11],main:12,make:1,manual:8,max:[7,9],maximum:6,mayb:0,middl:[5,6,7],might:11,min:7,minimum:6,modul:[0,1],motor:[0,1,7,12],move:1,need:11,newest:11,next:1,none:[2,11],normal:2,note:11,now:1,object:[1,8],off:[0,7],offset:10,onto:[7,11],opencv:0,oppon:1,organ:8,output:11,own:11,pai:1,paramet:[2,4,9,10,11],park:1,parkingsapc:1,pass:7,pay_park:1,percent:[3,9],percentag:[0,5,9],pixel:2,point:[1,11],port:[9,10,12],posit:[0,2,10,11],power:[7,9,12],print:[0,1,2,5,6,7,12],process:[10,11],provid:11,publish:11,publish_fram:[2,11],put:[6,7],python:8,quit:2,rais:9,rang:[2,5,9,12],raspberri:11,raw:6,raw_valu:6,read:6,realtim:11,recogn:0,record:11,rejectedimgpoint:2,request:1,respond:1,ret:11,right:[2,5,6,7,9],robot:[1,5,10,12],rotat:1,rtmp:11,run:11,sai:1,same:2,score:1,screen:2,screenshot:11,second:[6,11],seed:0,self:1,sensor:[0,7],server:[1,11],servo:0,set:[4,9,10],set_debug:8,set_posit:10,setup:10,setup_posit:10,shape:2,should:[1,8,11],show:[2,11],signal:5,similar:1,simon:1,simon_sai:1,simpl:[0,2],sleep:[4,7,12],some:[1,11],someth:1,specifi:[2,9],speed:[7,9],statu:[1,5],straight:0,straight_spe:7,stream:[0,2],success:1,tag:0,tag_id:2,take:11,term_criteria_ep:11,term_criteria_max_it:11,test:[0,11],thi:[1,2,6,8,11],till:7,time:[2,4,7,12],top:[2,5,9],top_left_perc:5,top_right_perc:5,tupl:1,turn:[0,9],turn_spe:7,type:[1,3,5,6,8],usag:0,use:[2,8,11],used:[0,1,6,8,9,10],using:[1,11],valu:[5,6],veri:2,view:11,vision:[0,2],wai:2,wait:11,want:[2,11],web:11,webserv:11,websit:11,whatev:11,when:[8,11],which:[1,9,11],white:6,width:2,wrapper:0,yet:1,you:[2,11],your:11,your_raspi_ip:11,yourself:11,zip:2,zone:1},titles:["Robo4you Competition Library","Api","Aruco","Battery","Buzzer","Infrared Sensor","Infrared Wrapper","Linefollower Examples","Logging","Motor","Servo","Vision","Usage"],titleterms:{"class":[3,4,8,9],Using:11,analog:[5,6],api:1,aruco:2,batteri:3,buzzer:4,calibr:6,call:1,chessboard:11,competit:0,content:0,detect:11,document:[3,4,8,9],doubl:1,drive:9,elimin:1,exampl:[1,2,3,4,5,6,7,8,9,11],infrar:[5,6],librari:0,linefollow:7,log:8,mayb:9,modul:11,motor:9,off:4,opencv:11,percentag:3,posit:1,print:3,recogn:2,robo4y:0,seed:1,sensor:[5,6],servo:10,simpl:7,straight:9,stream:11,tag:2,test:5,turn:[4,8],usag:12,vision:11,wrapper:6}})
\ No newline at end of file