14 Temmuz 2017 Cuma

MIL-STD-1553

Giriş
Bu yazının amacı havacılıkta sıkça karşımıza çıkan bir teknolojiye giriş yapmak. Bu veriyolu 1973 yılından beri kullanımda.

Tutucu olan havacılık sanayinde, bazı firmalar yavaş yavaş IP ve/veya ethernet tabanlı veriyollarına geçiş yapmaya başladılar. İleride bununla ilgili de bir yazı yazmak istiyorum. Örneğin Avionics Full Duplex Switch (AFDX) teknolojisinde Airbus Ethernet teknolojisi kullanıyor. AFDX Ethernet 802.3 tabanlı ve OSI katmanlarında Layer 1 ve Layer 2'yi içeriyor.

MIL-STD-1553 ve MSB
Eski ethernet veriyollarında, aynı 1553'te olduğu gibi ilk gönderilen bitin LSB olduğu yazıyordu. Çünkü sinyalleşmede her sinyal bir biti temsil ediyordu. Ancak gigabit ethernet teknolojisinde artık bir sinyal birden fazla bite denk geliyor.  1553 böyle yüksek hızlarda çalışmadığı için ilk gönderilen bit, ethernetin tam tersidir yani MSB'dir.


MIL-STD-1553
Askeri hava araçlarında kullanılan sayısal veriyolu tiplerinden birisi MIL-STD-1553'tür. MIL-STD ile başlaması, Amerikan ordusunun bir standardı olduğunu gösterir. Bu standardın NATO'daki karşılığı STANAG 3838'dir.

Bu veriyolu uçak, helikopter, füze vs. gibi bir çok yerde kullanılıyor. Bu veriyoluna benzeyen ancak daha çok sivil hava araçlarında kullanılan bir diğer sayısal veriyolu ise ARINC 429'dur.

Veriyolunun'ın çalışmasını gösteren şekili buradan aldım.

Bu veriyolu elektriksel sinyalleri kullanıyor. Daha gelişmiş bir sistem olan MIL-STD-1773 ise fiber optik teknolojisini kullanıyor. Kablolar twisted shield (twinax) ve dual redundant, yani iki farklı kablodan aynı veri akıyor. Redundant kabloların üzerinde 1 A ve 1 B  yazar. Veriyolunun uzunluğu 100 metreyi geçemez. Eğer geçmesi gerekirse "repeater" kullanarak sinyali güçlendirmek gerekir. Veriyolunun ucuna 78 ohm'luk terminator'lerin bağlanması gerekir. Bir cihazı veriyoluna bağlamanın en kolay yolu "coupler" kullanmaktır. Coupler üzerindeki girişleri 2 kanala sahip (2 RT'ye sahip) 1553 kartının kanal 1 A ve kanal 2 A girişlerine bağlayarak external loopback testi çalıştırılabilir. Yani kartın birinci RT ucunda gönderilen veri  aynı kartın ikinci RT ucundan girer ve doğruluğu kontrol edilir.

1553'ün havacılıktaki önemini anlamak için buradan yaptığım alıntıya dikkat etmek lazım.
Previous aircraft designs incorporated individual boxes for almost every system, linked to a central computer via a MIL-STD-1553 1 megabit-per-second serial avionics databus. The F-22 was the first to have a more fully integrated native architecture, built around a high-speed serial databus, which was able to get the most use of those assets without adding more boxes and electronics. That approach also eased the sharing of assets at a relatively low level of integration.
Veriyolu ile gönderilebilecek verilerin bitlerini gösteren şema ise aşağıda.

Word Nedir ?
Aslında her bir word 20 bit olarak tanımlanmasına rağmen ilk 3 bit senkronizasyon, 1 bit ise parity için kullanıldığından, data bit word genişliği 16 bit'e denk geliyor. Toplamda en fazla 32 bit data word gönderilebilir.

Word MSB
Aşağıdaki cümle önemli. Cümlede alışılagelmişin tersine, ilk yazılan bit değerinin 15. bitten başlayarak yazılması gerektiği söyleniyor.
The data field bits numbered 00 through 15, left to right, with bit 00 designated as the most significant bit (MSB)
Bileşenler Nelerdir?
1553 veriyolunu kullanan bir uçağın tipik bileşenleri aşağıdadır. Bu bileşenler "Bus Controller" , "Remote Terminal" ve "Bus Monitor" olarak ayırılıyorlar.


Bus Controller Nedir?
Her veriyolunda tek bir tane Bus Controller (BC) bulunur. BC programlanabilen ve tüm veriyolunu yöneten cihazdır. Dolayısıyla 1553 Command/Response şeklinde çalışır.

Not 1:

Bus Controller 1553 kartının üzerinde bulunan clock'a göre veriyolunu yönetir. Eğer Windows gibi gerçek zamanlı olmayan bir işletim sistemi kullanılıyorsa, BC'nin frame'inin ne zaman başladığı ve ne zaman bittiğini bilmek, ve okuma yazma işlemini yapan thread'i BC'nin clock döngüsüne uydurmak gerekir. Bunu yapmak için aşağıdaki Ballard API'sindeki "Interrupt döngüsü" başlığına bakabilirsiniz.

Eğer gerçek zamanlı bir işletim sistemi kullanılıyorsa, I/O işlemlerini yapan bölümlemenin periyodunu değiştirme imkanı bulunmadığı için, bu sefer kartın çipine uymak yerine, kartı bize uyduracak bir yöntem kullanmak gerekir. Bu yöntem de genellikle ya kartın çıkarttığı interrupt'ı dinlemek ya da I/O işlemine başlanınca, kartın clock'ını bizim clock'ımız ile eşitlemek olur.

Not 2
Gönderilecek mesaj sayısı çok ise ciddi bir scheduling problemine dönüşebilir. Scheduling problemler NP-hard problem halini bile alabilir. Nurse scheduling problem gibi gıcık algoritmik şeyler halini almamasına dikkat etmek gerekir.


Remote Terminal Nedir ?
Remote Terminal (RT), veriyoluna bağlı ve BC tarafından yönetilen cihazdır. Bir veriyoluna bir çok  RT bağlanabilir (31 tane).

Bus Controller programlandığı aralıklarla RT'ye bana veya başka bir RT'ye veri gönder veya gönderilen veriyi al komutunu gönderir.

Bus Monitor Nedir ?
Veriyolundan akan veriyi okumak için kullanılır.

Komut Akışı
BC'nin gönderdiği komutlar iki başlık altında toplanır. 

Veri Aktarımı
Veri aktarımı BC-RT, RT-BC veya RT-RT arasında olabilir.
Receive: BC tarafından RT'ye gönderilir. BC 1-32 arasında Data Word gönderir. RT Status Word ile cevaplar. Böylece BC RT'nin komutu aldığını anlar.
Transmit: BC tarafından RT'ye gönderilir. RT Status Word (Böylece BC RT'nin komutu aldığını anlar) ve 1-32 arasında Data Word ile cevaplar.
Broadcast: BC tarafından gönderilir. Broadcast, RT to RT olabilir.1-32 arasında Data word gönderir. Tüm RT'ler okurlar ama cevaplamazlar.
RT to RT : BC başlatır. RT1'e Receive komutu gönderir. RT2'ye Transmit komutu gönderir. RT2 1-32 arasında Data Word gönderir. RT1 Status Word ile cevaplar.
System Control : Mode komutları

Şimdi bazı özel wordlerin içine bakalım.
Status Word
Aşağıdaki şekilde status word'ün yapısı görülüyor.

Remote Terminal Address Bitleri : Status word'ü gönderen terminalin adresini içerir.
Message Error Biti : Eğer atanmışsa bir önce gönderilen mesajda hata olduğunu belirtir.
Busy Biti : Eğer atanmışsa RT'nin istenilen komutu yapamayacağını belirtir.

Mode Komutları
Veri aktarımı amacıyla değil ancak bir işlevin yerine getirilmesi için gönderilir. Örneğin cihazı temizlemek, sıfırlamak vs. gibi. Mode Komutlar komutun arkasından 0-1 arasında Data Word da gönderebilir. RT Status Word ve 0-1 arasında Data Word ile cevaplar.

BC RT'te bir Command Word ve gerekiyorsa arkasından Data Word gönderir. Data Word içinde RT Adresi barındırmadığı için Command Word'ü takip etmek zorundadır.  

RT ise Status Word ile cevap verir ve gerekiyorsa hemen arkasından Data Word gönderir. Data Word yine aynı şekilde içinde RT Adresi barındırmadığı için Status Word'ü takip etmek zorundadır. 


Remote Terminal ve Subadres
Subadresi işlev olarak açıklayan dokümanlar gördüm. Bir kartın birden fazla işlevi olabilir ve kartın hangi işlevi yerine getirmesini istediğimi subadres kullanılarak belirtilir diye açıklamalar vardı. 

Ben ise daha farklı bir şekilde açıklamayı uygun buluyorum. RT kendisine gönderilen veya kendi göndereceği veriyi kartın üzerindeki belli bir hafıza alanında saklamak zorundadır. Bu hafıza alanına subadres denilir. 

Bir Remote Terminal'in 30 tane subadresi olabiliyor. Subadres'ler 5 bit ile temsil ediliyorlar. Yani teoride 32 subadres bulunabilir, ancak 0 ve 31. subadresler broadcast için kullanıldıkları için RT-RT iletişim için geriye 30 tane kalıyor. 

Yani bir RT 30 Rx (alma), 30 Tx (gönderme) işlemi için toplam 60 subadrese sahip.(Bu cümleyi kontrol etmek lazım)

Her subadrese ne kadar veri yazılabilir?
Her bir okuma veya yazma işleminde bir subadres'e 32 word gönderilip alınabilir. 

1553 ve ICD
Bant genişliği çok fazla omadığı için bit oriented mesajlar kullanılır. Double gibi 8 byte tutan değeri göndermek yerine, (int * precision) şeklinde daha az yer tutan gönderim yöntemleri seçilebilir.

1553 ve Zamanlama

1553 veriyolunda zamanlama herşeydir. Bus controller programlandığı zamanda veriyi ister. Eğer veri hazır değilse sıkıntı çıkar. Bu yüzden gerçek zamanlı işletim sistemlerinde, I/O yani 1553 veriyolu ile haberleşme işlevini yerine getiren ayrı bir bölümlenme (partition) kullanılması sık görülen bir durumdur.  Bu kullanım şeklinde I/O bölümlenmesinin bus controller veriyi talep ettiğinde (örneğin her 50 milisaniyede bir) çalışacağı daha kolay garanti edilebilir. 

DDC Kartları
Data Device Corporation firmasının PCI Express, USB girişlerine takılabilen bir çok kart modeli mevcut. Bu firma bus'i izlemek için BusTracer isimli bir program da veriyor.

RT olarak kartı kullanma
uint16_t deviceNum = 0;
aceInitialize (deviceNum,ACE_ACCESS_CARD,ACE_MODE_RT,0,0,0);

//Cmd stacks are 1K words
aceRTConfigure (deviceNum,ACE_RT_CMD_STK_1K,0);

uint16_t rtNumber = 1;
aceRTSetAddress (deviceNum, rtNumber);


Okuma örneği

//This is the global (used for all messages) message structure for decoded 1553 messages
MSGStRUCT message;
aceRTGetStkMsgDecoded (deviceNum,&message,ACE_RT_MSGLOC_NEXT_PURGE);

uint16_t commandWord = message.wCmdWrd1;

uint32_t rtAddr = commandWord >> 11; //11 bits
uint32_t direction = (commandWord >> 10) & 1; // 1 bit
uint32_t subAddr = (commandWord >> 5 ) & 0X1F; // 5 bits
uint32_t wordCount = commandWord & 0x1F; // 5 bits

//Read
if (wordCount != 0){}

Ballard
Ballard firmasını da bir çok kart modeli mevcut.
Aşağıda Ballard'ın 1553 kartını Windows'ta kullanma örneği var. Ballard'ın verdiği sürücünün API'si burada.
Şu cümle card ve core arasındaki farkı açıkladığı için önemli.
Ballard hardware devices are implemented with one or more sections called cores. Typically, each core has its own protocol processing circutiry.

Kartı açma
HCARD hcard;
unsigned short cardNum = 0;
BTICard_CardOpen (&hCard,cardNum);//Open card
HCORE hCore;
unsigned short coreNum = 0;
BTICard_CoreOpen (&hCore,coreNum,hCard);//Open core

BC olarak Ayarlama
BTI1553_BCConfig (BCCFG1553_DEFAULT,//select all default settings
                                 CH0,//Channel number
                                 hCore);

RT olarak Ayarlama
BTI1553_RTConfig(RTCFG1553_DEFAULT,//select all default settings
                                 1,//Terminal address
                                CHO,//Channel number
                                hCore);

Mesajları Atama
BTI1553_MsgDataRd ve BTI1553_MsgDataWr metodları ile bir subadrese okuma yazma işlemi yapılabilir. Ancak bu metodlar MSGADDR parametresi kullanıyorlar. Bu parametre aşağıdaki gibi yaratılabilir.
 
unsigned short channelNum = 0;
BTI1553_BConfig (BCCFG1553_DEFAULT,channelNum,hCard);

//BC to RT message
{
    //Receive from RT's point of view
    unsigned short commandWord = BTI1553_ValPackCWD (rt1,RCV,sa1,wc);//Command Word

    unsigned short pData = new unsigned short [wc];

    //MSGADDR    a handle to a struct that contains data associated with a 1553 message
    MSGADDR msgAddr = BTI1553_BCCreateMsg (MSGCRT1553_DEFAULT,commandWord,0,pData,hCard);
}

//RT to BC message
{
    //Transmit from RT's point of view
    unsigned short commandWord = BTI1553_ValPackCWD (rt1,XMT,sa1,wc);//Command Word

    unsigned short pData = new unsigned short [wc];

    //MSGADDR    a handle to a struct that contains data associated with a 1553 message
    MSGADDR msgAddr = BTI1553_BCCreateMsg (MSGCRT1553_DEFAULT | MSGCRT1553_LOG,commandWord,0,pData,hCard);
}

Interrupt döngüsü
Bize gelen mesajları okumak için interrupt kullanılabilir. Bunun için bir döngü içinde interrupt'ı beklemek gerekir.

BTICard_EventLogConfig (LOGCFG_ENABLE//Enable event log list
                                           4096//Number of entries in the event log list
                                           hCore
                                          );
 
unsigned short type = 0;
MSGADDR msgAddr = 0; //subaddress
//Wait for event. 3 parametre olan channel için NULL kullanıyoruz
if (BTICard_EventLogRd (&type,&msgAddr,NULL,hCore))
{
    if (type == EVENTTYPE_1553MSG)
    {
        unsigned short msgData [32];
        unsigned short msgSize = 32 //size of data to be read

        BTI1553_MsgDataRd (msgData,msgSize,msgAddr,hCore);
    }
}

Bir başka örnekte frame'in geldiğini görebiliriz.
unsigned short type = 0;
unsigned int info = 0; //frame numarası
//Wait for event. 3 parametre olan channel için NULL kullanıyoruz
if (BTICard_EventLogRd (&type,&info,NULL,hCore))
{
    if (type == EVENTTYPE_1553OPCODE)
    {
    }
}
Kullanım Örnekleri
Kullanım yerlerine bir kaç örnek vermek istedim.

Hindistan'da geliştirilen Light Combat Helicopter (LCH)
Amerikan B-52 bombardıman uçağı


Türkiye'nin elinde bulunan F4 uçakları da bu veriyolunu kullanacak şekilde modernize edildi.

Ayrıca ASELSAN tarafından geliştirilen ASES sisteminin MIL-STD-1553 ile uyumlu çalıştığı da yazılıyor

Aşağıda bazı MIL-STD-1553 videoları var


 



 


ARINC 429
ARINC 429 yazısına taşıdım.

MIL-STD-1760
MIL-STD-1760 hava araçlarında kullanılan elektriksel bir arayüz. Roketsan tarafından geliştirilen Cirit silahında MIL STD-1760 arayüzü destekleniyor.

Can Bus
Can Bus otomotiv dünyasında kullanılan Bosch tarafından geliştirilen bir veriyolu. 1983 yılında ticari hale geldi. Ethernet'e benzer şekilde, iki düğüm aynı anda konuşmaya başlarsa çarpışma oluyor, yani CSMA/CD. Ancak mesajların öncelik sırası var. Çarpışma tespit edilirse en yüksek öncelikli mesaj iletilir. Veriyolunda master ve slave görevine sahip düğümler var.

Can Bus Frame Acknowledgement
Layer 2'de gerçekleşir. Bir mesajı alan tüm düğümler Acknowledgement gönderirler.

Can Bus Acceptance Filtering
Düğümler sadece kendilerine adreslenen frame'leri alması için ayarlanabilirler.


9 Temmuz 2017 Pazar

MIL-STD-498 Software Test Plan

Giriş
MIL-STD-498 ile ilgili yazılara Software Test Plan ile devam ediyorum.

Bazı şirketlerde bu belgeye kardeş olan SysTP yani System Test Plan de mevcut. SysTP ile SSS arasında izlenebilirlik kurulur.

Software Test Plan (STP)
Türkçesi Yazılım Test Planı (YTEP) kelimesi
kullanılıyor. Yazılan testlerin koşturulması için kullanılacak araç, gereken ortam, kaynaklar vs. gibi konuları açıklayan doküman. İyi bir tanım burada.
A document describing the scope, approach, resources and schedule of intended test activities. It identifies amongst others test items, the features to be tested, the testing tasks, who will do each task, degree of tester independence, the test environment, the test design techniques and entry and exit criteria to be used, and the rationale for their choice, and any risks requiring contingency planning. It is a record of the test planning process.
Test Plan vs Test Strategies
Farklar şöyle. Test Strategy, Test Plan'dan önce hazırlanır
Test Plan Test Strategies
Test plan can be derived from the Software requirement traceability matrix. Test strategies can be derived from Business requirement specifications.
The test plan should be revised if there are any modifications to the requirement. While preparing documents, test methodologies stay unchanged.
Based on the project, we can create a test plan. Test strategies can be applied to a variety of tasks.
A test plan is written after gathering all information. Test strategies made before test plan.
A test plan should be clear and concise. Test strategies serve as a roadmap for evaluating apps.


IEEE 829 ile verilen Test Plan Outline ile benzerlik gösteriyor. IEEE dokümanının başlıkları şöyle.

1) Test Plan Identifier
2) References
3) Introduction
4) Test Items
5) Software Risk Issues
6) Features to be Tested
7) Features not to be Tested
8) Approach
9) Item Pass/Fail Criteria
10) Suspension Criteria and Resumption Requirements
11) Test Deliverables
12) Remaining Test Tasks
13) Environmental Needs
14) Staffing and Training Needs
15) Responsibilities
16) Schedule
17) Planning Risks and Contingencies
18) Approvals
19) Glossary

MIL-STD-498 dokümanının başlıkları ise şöyle:

3. Yazılım Test Ortamı
  Hangi CSCI'ların test edileceği ve hangisi için STD hazırlanacağı belirtilir. Test ortamını gösteren bir     şekil verilebilir.
  3.1 Yazılım Kalemleri
  3.2 Donanım Kalemleri
  3.3 Kurulum, Test ve Kontrol
   3.4 Personel
başlıkları altında bilgi verilir.

4. Test Tanımlamaları
5. Test Takvimi
Test sonucunda şöyle ideal olarak şöyle bir çıktı beklenir.
Yani zaman içinde çıkan hata sayısında düşüş olması gerekir.



6 Temmuz 2017 Perşembe

Image

Alpha Channel Nedir ?
Alpha channel bir RGB renginin ne kadar transparan olduğunu belirtir. Alpha channel 0 ise renk tamamen saydam sayılır ve kendisi yerine altındaki renk gösterilir. Rengin saydamlığını gösteren formül aşağıda.
float alpha = pixel.alpha / 255;
buffer[offset_dst].R += pixel[offset_src].R * alpha;
buffer[offset_dst].G += pixel[offset_src].G * alpha;
buffer[offset_dst].B += pixel[offset_src].B * alpha;
ColorModel Alpha Channel'a Sahip mi ?
Java
Örnek:
boolean hasAlpha(Image image) {
 // If buffered image, the color model is readily available
 if (image instanceof BufferedImage) {
  BufferedImage bimage = (BufferedImage)image;
  return bimage.getColorModel().hasAlpha();
 }

 // Use a pixel grabber to retrieve the image's color model;
 // grabbing a single pixel is usually sufficient
 PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
 try {
  pg.grabPixels();
 } catch (InterruptedException e) {}

 // Get the image's color model
 ColorModel cm = pg.getColorModel();
 return cm.hasAlpha();
}

SampleModel Nedir?
SampleModel sınıfı, DataBuffer sınıfının içinde dizinin neyi temsil ettiğini belirtir. Örnekteki şekilde dizinin her 3 byte'lık alanının bir pixel olduğu görülebilir.
 PixelInterleavedSampleModel sampleModel
= new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, //The data type of the image buffer elements
                                    width, //The width of the image
                                    height, //The height of the image
                                    3, //The number of data buffer elements per pixel
                                    3*width, //The number of data buffer elements per line
                                    new int[] {2,1,0}//The location of colour components for each pixel
                                    );
DPI Nedir
Dots per inch anlamına geliyor. Bir resmi basarken inch başına kaç pixel kullanılacağını belirtir. Yani basma kalitesini belirler, ekranda gösterilen resim ile alakası yoktur.
 
BufferedImage Sınfı
Java'da Image bir soyut sınıf, BufferedImage ise onu gerçekleştiren bir sınıf. Bu sınıf yukarıda gösterilen yardımcı sınıfları da içeriyor. Aşağıdaki şekilde görülebilir.
 
Yukarıdaki GrayScale açıklamasından da görülebildiği gibi bu sınıfın ImageType parametresi ColorModel'de kullanılan elemanların pixel başına kaç bit/byte ile temsil edileceğini gösterir.

Image Okuma
C#
Bitmap bitmap = Bitmap.FromFile(@"C:\m.png") as Bitmap;

Java
ImageIO
getReaderFileSuffixes
Bu metod ile ImageIO sınıfının okuyabildiği formatlar listeleniyor. Örnek:
 
read
Burada bir çok örnek var. Temel olarak ImageIO sınıfının read() metodu kullanılıyor.
Bir başka örnek:

Bir diğer örnekte ise ImageIcon sınıfı yaratılıyor.

Java AWT
Örnek:
Toolkit.getImage() metodu kullanılıyor.
Image img=Toolkit.getDefaultToolkit().getImage("1.png"); 
 
QT
QImage sınıfı iki şekilde yüklenebilir. 
QImage Image = QImage(fileName);
veya
QImage Image;
Image.load("../punton.png");


Image Yazma
C#
croppedBitmap.Save(@"C:\m-1.png", System.Drawing.Imaging.ImageFormat.Png);
Java
Image Boyutlarını Alma
Java
QT
QImage sınıfı ile bu iş başarılabiliyor.
QImage Image = QImage(fileName);
int width = Image.width();
int height = Image.height (); 
Burada dikkat edilmesi gereken nokta QT ile gelen plugin sistemi. JPEG gibi formatları okumak için libjpeg plugini lazımken PNG formatı native olarak okunabiliyor.

Image Formatını Değiştirme
Java
Örneği buradan aldım ve JAI kullanıyor.

QT
Aşağıdaki örnek image JPG olarak yükleniyor ve hafızadaki bir alana PNG olarak yazılıyor.
QImage image ("picture.jpg");
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG"); // writes image into ba in PNG format  
Image'ı Yeniden Boyutlandırma
Java
getScaledInstance() metodu ile yapılabilir. Örnek:
BufferedImage bimage = ImageIO.read(file);
Image img = bimage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
C#
İstenilen boyutta yeni bir Bitmap sınıfı yaratılır. Örnek:


Image'ı Gri Renk Yapma
Java
imaging processing programme sorusundan aldığım örnek aşağıda.

Image İçine Yazma
Java
Örnek:
//Create image in memory
int imgWidth_max = 410;
int imgHeight_max = 230;
BufferedImage img = new BufferedImage(img_width, img_height, BufferedImage.TYPE_INT_RGB);

//Get graphics of image
Graphics g = img.getGraphics();
g.setColor(Color.WHITE);

//Fill image
g.fillRect(0, 0, img_width, img_height);

//Set pen color
g.setColor(Color.BLACK);

//Create font
int fontSize = 22;
Font f = new Font("SERIF", Font.BOLD, fontSize);
g.setFont(f);

//Draw string
String s = //populate
g.drawString(s,10, 35);

g.dispose();

ImageIO.write(img, "jpeg", new File(dest));


Image'ı Byte Array Yapma
Her image sınıfının içinde resim verisinin depolandığı bellek alanı var. Bu alan kabaca aşağıdaki büyüklükte.
Çeşitli diller resim verisine erişmek için sınıflar tanımlamışlar.
Java
Java'da resim verisine erişmek için DataBufferByte sınıfı kullanıyor.
Örneği buradan aldım. Verilen image dosyası okunduktan sonra internal olarak her nasıl temsil ediliyorsa onu byte[] haline getiriyor. Bu ne işe yarar bilmiyorum.
File imgPath = new File("ImageName");
BufferedImage bufferedImage = ImageIO.read(imgPath);
WritableRaster raster = bufferedImage .getRaster();
DataBufferByte dataBuffer   = (
DataBufferByte) raster.getDataBuffer();   
byte[] data =  dataBuffer.getData(); 
Buradaki örnekte ise image verisi BufferedImage'a yazılıyor. 

void get8bitImage(byte[] data, int width, int height) {
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    byte[] rasterData = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
    System.arraycopy(pixels, 0, rasterData, 0, pixels.length); // A LOT faster than 'setData()'
}

Bitmap'in Pixellerine Erişme
C#
Bitmap bmp = //get bitmap
Color c = bmp.GetPixel(j, i);// Extract the color of a pixel
// extract the red,green, blue components from the color.
int rd = c.R;
int gr = c.G;
int bl = c.B;
QT
QImage bmp = //get bitmap
QColor c = QColor::fromRgb (bmp.pixel(x,y) );// Extract the color of a pixel
// extract the red,green, blue components from the color.
int rd = c.red();
int gr = c.green();
int bl = c.blue(); 
Java
Örnek:
BufferedImage bf = //...
Color c = new Color(bfImage.getRGB(i,j));
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
Bir başka örnek ise burada.

Bitmap'in Pixel Derinliğini Bulma
Pixel derinliği, pixel başına kaç bit kullanıldığı anlamına geliyor.
QT
Aşağıdaki örneği Dividing QImage to smaller pieces sorusundan aldım.
QImage bmp = //get bitmap
bmp.depth ();//depth ile pixel derinliği bulunabilir.

Image Kesme (Cropping)
C#
Aşağıda büyük bir resimden daha küçük bir resim oluşturma örneği var.
Bitmap bmp;//Readint xstart = 355, ystart  = 318;
int width = 60, height = 60,
BitmapData bmpData = bmp.LockBits(new Rectangle(xstart,ystart ,width, height),
                            ImageLockMode.ReadWrite,
                            bmp.PixelFormat);
LockBits ile kilitlenen BitmapData sınıfı daha sonra iş bitince unlock edilmeli. Örnek:
bmp.UnlockBits(bmpData);
BitmapData sınıfının Stride isimli bir alanı var. Bu alan her bir satırda kaç byte olduğunu gösterir. BitmapData sınıfının pixellerine erişmek için aşağıdaki gibi yapılabilir.

BitmapData bmpData;//...
for (int y = 1; y < height-1; y++)
{
    for (int x = 0; x < width; x++)
    {
        int index = y * bmpData.Stride + (x * 4);
        unsafe
        {
            byte* prevLine = (byte*)data.Scan0;
            byte* currLine = prevLine + data.Stride;
            byte* nextLine = currLine + data.Stride;
            //...
            prevLine = currLine;
            currLine = nextLine;
            nextLine += bmpData.Stride;
        }
    }
}
Eğer bmpData sınıfına yeni veri kopyalanmak istenirse aşağıdaki gibi yapılabilir.
System.Runtime.InteropServices.Marshal.Copy(bytes, 0, data.Scan0, size);

Bir diğer örnekte ise kaynak resimdeki RED renk filtreleniyor.

IntPtr destinationPtr = destinationBmd.Scan0;
uint* pDest = (uint*)destinationPtr.ToPointer();

int _w = sourceBmp.Width;
int _h = sourceBmp.Height;

for (int j = 0; j < _h; j++)
{
    for (int i = 0; i < _w; i++)
    {
        *pDest = (*pSource) & 0xff00ffff;
        pDest++;
        pSource++;
     }
}






5 Temmuz 2017 Çarşamba

Jira'da Hata Açmak

Not : Yazıda hata kelimesini kullandım çünkü Jira'yı bir talep takip sistemi olarak değil, yazılım sürecini destekleyici bir araç olarak anlatmak istedim. Ancak bir çok firma Jira'tı talep takip sistemi olarak ta başarıyla kullanıyor. Bu gibi kullanım durumlarında Issue Type olarak Purchase Request Form, Software Installation Request Form gibi tipleri seçiliyor.

Giriş

Jira'da hata açmak için bir sürü alan tanımlanabiliyor. Alan sayısını mümkün olduğunca az tutmak lazım. Bazı alanlarla ilgili notlarım aşağıda.

Hata Standardı
İyi çalışan firmalarda hata açmanın da bir standardı var. Description alanına belli bir formatta açıklama girilebilir. Örnek:
Steps to reproduce:
1. Access customer manager for user Test01
2. Check "User must change password" and click Apply
3. Access login page
4. Enter user name and password
5. Click Login

Expected results:
6. Site displays user profile page (see use case 21.1.2)

Actual results:
6. Site displays error page (see attached screen shot)

Hata Açarken Ana Sebep Ne Kadar İncelenmeli
QA hatayı açarken iki şekilde çalışabilir.

  • Hatayı sadece açıp geçebilir 
  • Hatanın ana sebebini detaylı inceleyerek gösterebilir. 
Projede hangi yöntemin kullanılacağını belirlemek faydalı olabilir. Geliştirme ekibi açısından hatanın ana sebebinin sıcağı sıcağına bulunması işleri kolaylaştırabilir.

Hata Yaratmak İçin Kullanılan Alanlar

Summary 
Hatanın özetini içerir. Hata listeleri üzerinde dolaşırken hatanın içine bakmadan ne hakkında olduğunu kolayca anlayabilmemizi sağlar.

Issue Type - Hata Türü
Yazılım İçin Açılan Hatalar
Bug henüz formal hale gelmemiş ürün için açılır. Formal hale gelmiş ürün için PR (Problem Report), SPR (Software Problem Report), SCR (Software Change Request) gibi isimler kullanılıyor.

Aslında Bug ve Defect arasında fark var.
  • A bug is the result of a coding error
  • A defect is a deviation from the requirements
Ancak çoğunluklar her şey bug olarak isimlendiriliyor. Bug'lar da kendi aralarında sınıflandırılabilir.
Dormant bug veya Latent Bug : Uyumakta olan, henüz ortaya çıkmamış bug anlamına gelir. Latent Bug bilinen ancak müşteriye söylenmeyen bug olarak ta tanımlanıyor.


QA Tarafından Açılan Hatalar
Hata türü olarak NR (Non Compliance Report) kullanılıyor.

İyileştirme amaçlı (Improvement) öneriler de kullanılabilir.

Priority - Hatanın Önem Seviyesi:
Hata yaratırken, önem seviyesinin girilmesi gerekir. Bunlar Blocker, Critical, Major, Minor, Trivial gibi seviyelerdir.

 Blocker : "Release will not be completed until issue is resolved. An example would be a severe problem that bridges multiple tools, or prevents core functionality in one tool."
 Critical : "Issue will most likely be resolved for release."
 Major : "Issue should be resolved for release."
 Minor : "Issue may be resolved for release."
 Trivial : "Issues that might be resolved before a release."

Çoğu proje sadece tek boyutlu önem seviyesi girer. Hata seviyeleri çözüm önceliklendirmesinde kullanılır. Örneğin Issues linki altında Blocker hatalar görülebilir. Toplantılarda üzerinden geçmek için kolaylık sağlar.

Hataların önem seviyesi değişik araçlarda farklı farklı isimlendirilebilir. Örneğin urgent, high, medium, low gibi seviyeler de kullanılabilir.

Process Detected:
MIL-STD-498 projelerinde aşağıdaki alanlar kullanılabiliyor.
  • Operation & Maintenance
  • Source Code Review
  • Unit Integration Test
  • CSCI Level Pre-Integration Test (*)
  • CSCI Qualification Dry-Run
  • CSCI Qualification Test
  • System Pre-Integration Test
  • System Integration Dry-Run
  • System Integration Test
  • System Qualification Dry-Run
  • System Qualification Test
Process Injected:
  • System Requirements Development
  • Software Requirements Development
  • System Design
  • Software Design
  • Software Implementation

Bu alan Root Cause olarak belki kullanılabilir. Root Cause hatanın yakalandığı yeri değil, asıl oluştuğu yeri gösterir. Root Cause olarak şunlar sıralanabilir
1. Lack of education
2. Communication problems
3. Immature processes
4. Omission or oversight
5. Interpretation or transcription
Root cause daha sonra şu işe yarar.
Detailed documentation of the defect enables us to note all the information obtained during this identification phase and helps developers to correct the defect and carry out any subsequent statistical analysis based on defect data (i.e identification of the most frequent root causes)


Açılan hataların nasıl çok boyutlu olarak önceliklendirileceğini gösteren güzel bir yazı burada. Açılan hatalara önem seviyesi verirken müşteri ve geliştirici açısından bakılmasını tavsiye ediyor.

Affects Version
"Version(s) in which an issue is observed" şeklinde tanımlanıyor.

Fix Version
"Version(s) for which an issue is anticipated to be fixed (for Unresolved issues) or in which it is actually fixed (for Resolved/Closed and Fixed issues)" şeklinde tanımlanıyor.

Kime Atananacağı
Assignee alanı "Automatic" olarak bırakılırsa takım liderine atanır.

Dosya Eklentisi
Yazılım hatalarında ekran görüntüsü veya logları eklenti olarak koymak faydalı olabilir.