顯示具有 資訊 / 軟硬體整合 / 技術 標籤的文章。 顯示所有文章
顯示具有 資訊 / 軟硬體整合 / 技術 標籤的文章。 顯示所有文章

2015年9月9日 星期三

Cura - 3D 列印切片軟體

Cura 是Ultimaker 公司所釋出的開源軟體,Cura能將STL的圖檔轉換為GCode檔案,讓3D印表機能根據轉換出的參數,進行打印.

Cura的組成有兩大部分,一部分是由Python所呈現的UI.
另一部分是C++ 做為核心的列印引擎.

Cura 的安裝包Sctipy可透過 ”package.sh ”接參數win32製作.

參考文獻:

編譯環境需要的基本軟體:
˙Windows SDK

˙7z

# 注意事項:
# 安裝Arduino的預設路徑與package.sh的可能不同
# 安裝Winavr的版本中,GNUmake.exe的版本在3.82以下有bug,須更新至4.1以上
# ARDUINO 1.6.4 不相容,需安裝ARDUINO1.0.6

If you'rerunning Windows 8 or higher, the Make in WinAVR won't work as distributed. Download this file and install it in winavr's util/bin directory afterinstalling WinAVR:
http://www.madwizard.org/download/electronics/msys-1.0-vista64.zip

WinAVR
"Date modified" is also odd for me since therelease is named "WinAVR-20100110" and I do not believe thattime-travel is possible in our universe I doubt that even this is correct ...

There is also a file named "make.exe.old" but it is waste of time touse/test that since I already know that this version is not better.

Anyway I found the workaround (to be correct it is just a workaround, not afinal solution) it is fine for me that way. We plan to move to AtmelStudio/toolchain anyway ...

Problem : #\$_OUTDIR/Lib/site-packages

------
以上為核心建置的部分
------
若只需要修改UI,可直接修改Python檔案即可.
------
Cura的安裝檔為一個壓縮檔,安裝的過程中會解壓縮檔案至目錄,並可選擇是否安裝Arduino的驅動程式.

Python的檔案結構
# 在第一次執行Cura的時候,Cura會去執行\\Cura\cura.py
# Cura.py在第一次時會去執行configWizard.py 的設定檔視窗
# 220 行 (options[5] 預設第五個選項)這是視窗選項預設的語言

例如:
def AddCombo(self, label, options):
combo = wx.ComboBox(self, -1, options[5], choices=options, style=wx.CB_DROPDOWN|wx.CB_READONLY)
text = wx.StaticText(self, -1, label)
self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
self.GetSizer().Add(combo, pos=(self.rowNr, 1), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
self.rowNr += 1
return combo

設定完成以後,設定檔的位置會被寫入
設定檔位置C:\Users\User_name\.cura

而之後每次執行都會去Load profile,執行C:\Users\User_name\.cura
內所設定的參數檔.

Resource.py 資源檔
434 行 (self.OtherRadio =self.AddRadioButton(_("測試機型")))

C:\Users\User_name\.cura\current_profile.ini 設定完預設參數

Python 程式碼 :
Cura_15.04.2\resources\machine_profiles 機器設定原始參數
Cura_15.04.2\resources\locale\zh\LC_MESSAGES\Cura.po 對照Python

參考資料:

在修改Python檔案以後,重新執行即可.

因此,若要修改UI層級的軟體,可透過修改設定檔和Python的直譯檔即可.

Cura 是透過 Protobuf與Python的UI做溝通的,Protobuf是一種簡單的數據結構,是Google內部用來做混合語言的溝通.

參考資料:

2015年7月28日 星期二

Scrum與巴別塔


在聖經中記載,巴別塔 (Tower ofBabel) 是當時人類聯合起來興建,希望能通往天堂的高塔。
為了阻止人類的計劃,上帝讓人類說不同的語言,使人類相互之間不能溝通,計劃因此失敗,人類自此各散東西。
但人類已經還是沒有放棄建造通往天堂的高塔,在研究中顯示一代人可以創造語言.

標準例子是奴隸貿易。
奴隸貿易主要涉及煙草、棉花、咖啡或糖,
工人往往是來自不同語言背景的奴隸,這樣的安排部分原因是故意的,以避免可能有人反抗。
這些來自不同文化背景的奴隸自然而然會制定臨時的 溝通系統,方便彼此交談。
這就是所謂 洋涇濱(Pidgin) 語言。「洋涇濱」不是語言,而是從不同語言借用一些字詞字串,隨意放在一起。

孩子在這種社會長大會有什麼問題?
可能預期他們會學會以洋涇濱交流,
但實際情況是一代人已經發展自己的語言,創建了豐富語法,形態和音韻的語言。
他們創造的這種語言被稱為 混合語/克里奧爾語 (Creole Language)

而除了語言,另一種形容文化資訊傳承時的單位,模因(memes)
被設想為一種類似於基因的「文化單位」(一種觀念、信仰、行為模式等等),存在於個體的思想中,
會進行自我繁衍從而在不同人的思想領域內傳播。

這些詞語都是為了將抽象概念量化 / 研究 / 改善 ,最後建造出巴別塔的過程.

而 軟體工程(SoftwareEngineering) 也有些方法正在解決建造巴別塔所遇到的問題,
其中Scrum是屬於 敏捷軟體開(Agilesoftware development) 的其中一種方法,
對於建造巴別塔過程中所產生的不確定性,以及各自的文化背景及經驗的不同,
所要溝通勢必得產生一種 洋涇濱(Pidgin)語言得以形容所估計的 時間,難易度,自身掌握程度,需求理解程度.

從現有的語言很顯然無法有一個能形容那麼多抽象概念的單位,
於是Scrum 方法採用Story point 去形容在團隊建造巴別塔的過程中,
團隊成員所評估出的相對性概念單位.

因此每個不同的巴別塔團隊成員之間的Story point 背後所隱含的意義並不相同.

桌上型冷氣

記得大學時曾聽過一個交大做機器人的教授提過,
真正要研究一門學問,
連最根本的細節都要瞭解.

所以為了補足工程領域的知識,
就只好透過實作來做一些爛東西來學習 (它到現在CP值都還沒超過電風扇 T_T)
------------------------------------------------------------------------

目前設計的模型如圖所示,
最前面是放濾網和電腦用的4 pin風扇,
把中間核心的致冷片產生的冷氣抽出來,
而致冷片產生的熱量透過後面導熱金屬經由散熱風扇抽掉.
(中間有留空間放冰塊,如果有需要的話)
就是這個簡單的設計.

------------------------------------------------------------------------
致冷晶片的原理大致上是利用半導體元件的特性,
一塊N型半導體與一塊P行半導體材料聯成電偶對,
在電路中接通直流電留後,會產生能量的轉移.
當電流由N型元件流向P型元件的接頭吸收熱量,就成為冷端.
反之,電流由P型元件流向N型元件的接頭釋放熱量,就成為熱端.
吸收熱量和放出熱量的大小由電流大小決定.
所以熱端的散熱和電流的安培數是主要讓機器能有用的關鍵.

買的致冷器型號是TECI-12703,
127為致冷元件的電偶對數,0.3為允許電流值(安培),
致冷元件的極限電壓近似於電偶對數x0.11,V=127x0.11=13.97(V)

------------------------------------------------------------------------
最後零件和材料齊了以後,
搞定電壓和安培是件麻煩的事情,
如果之後要接MCU板子,
來控制電路,必須要+繼電器來控制大電流,
因為USB最多只能供5v的電壓,
而致冷片其實超耗電,至少要12v 3安培的電流(還有更高的),
能源轉換率也只有40% (傳統冷氣壓縮機有95%).

------------------



最後補這張暫時的模型,
之後如果有時間STM32MCU控制板接上去,
透過程式就能做更多事情了

------------------


arduino Leonardo 測試 Code
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX | TX
int relay1=8;                                   //set relay 1 at pin No.8
int iLedPin        = 13;

void setup() 
{
  //pinMode(7, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  //digitalWrite(7, HIGH);

  pinMode(relay1,OUTPUT);       //set relay to out put
  delay(1000);
  Serial.begin(57600);
  mySerial.begin(9600);
}

char inByte=0;
int i=0;
void loop() {
    
  delay(1000);
  
  if (mySerial.available())
  {
    if(i==0)
    {
        Serial.write("H");
      digitalWrite(relay1,HIGH);
      i=1;
    }
    else
    {
      i=0;
      Serial.write("L");
      digitalWrite(relay1,LOW); 
    }
    Serial.write(mySerial.read());
  }
  
  if (Serial.available())
  { 
    mySerial.write(Serial.read());
  }
}

------------------
android code

public void Reg()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
((Activity)mContext).startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the chat session
}

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
((Activity)mContext).registerReceiver(mReceiver, filter);
}


public final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {

if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(this.getClass().getName(), "device.getName = " + device.getName());
Toast.makeText(mContext, device.getName(), Toast.LENGTH_SHORT).show();

if (device.getName().equals("HC-05")){
try {
Log.d(this.getClass().getName(),"Connect success = " + device.getName());

mBluetoothAdapter.cancelDiscovery();

mBluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
mBluetoothSocket.connect();

mOutputStream = mBluetoothSocket.getOutputStream();

String message = "h";
mOutputStream.write(message.getBytes());
mOutputStream.flush();

} catch (IOException e) {
Log.d(this.getClass().getName(),"Exception = " + e.getMessage());
}
}
}
}
};

------------------

參考資料:

2014年3月1日 星期六

利用Dropbox當作Server進行遠端訊息傳輸與溝通

因為我的Dropbox 只有小小的空間,
所以每次用Dropbox傳完檔案的時候都要把資料搬到其他硬碟上.
後來就想到把Dropbox當成Server進行資料傳輸的概念.

概念如下圖:


只要把有安裝Dropbox的電腦, 放一個程式(sender/receiver)去monitorDropbox裡面特定的資料夾(command folder),當資料夾有變動的時候,就去讀取裡面的command file, 讀取完以後刪除.
由於為了避免自己讀取到自己設定的command, 所以程式在寫入檔案的時候,在檔名上加入一個GUID, 作為辨識.
而在接收到Sender送來的command以後,Receiver就能自動的將傳送過來的資料, 執行command的動作, 例如Movedata, 將Dropbox裡面的資料搬到Receiver所在的位置對應的硬碟空間.
這樣一來就能利用Dropbox進行分散式資料備份囉.
以下是小小的程式證明方法可行, 遠端電腦測試過.
證明可以利用Dropbox當作訊息傳輸的管道以後,
只要把程式執行Command的dll 檔案拆開來, 用動態的方式載入,
未來也可以做到線上更新囉.

2014年2月21日 星期五

在Windows 8上面執行Chrome OS

介紹在windows 8裡面可以重新啟動Metro的Chrome,
而且會以Chrome OS的模式出現,
所以就試試看囉.
    首先在Chrome的右邊選單選 "在windows 8模式中重新啟動Chrome",
    畫面就會跳到以Chrome OS模式出現的Chrome.

        Chrome OS模式

            接著來試試看OS該有的功能Chrome OS做了哪些,
            右下角Chrome的開始選單裡面放的是Chrome的extensions,
            並且這些extension app由於都是web技術為基礎的,
            因此儲存方式完全是走雲端功能.


              而該有的工作排程和多執行緒,Chrome也有做進去.
              我想最後會分不出來,現在執行的App到底是跑在Web Browser還是Native OS上面吧!



              而這次選測的App是Hobbit,
              看看Web based的App在3D圖形視覺效果的表現如何.
                Google極力扶持HTML5的技術,並且對這方面進行深入的分析
                而從瀏覽效果看起來似乎還不錯.
                我想因為視覺研究和攝影技巧的進步,
                光是平面圖片所創造出來的3D效果就已經有一定程度囉.

                    由於畫面是連續的,
                    就互動體驗來說想當不錯,
                    就擷取兩張圖片來示意一下.




                        結論: Google在Chrome投入的心力和技術已經慢慢成形了,
                        我想這真的是直接偷渡Chrome OS到Windows 8身上,
                        到時候Google真的很有可能因為一堆Cloud相關的產品,
                        而讓人直接在Windows 8上面跑Chrome OS,
                        Microsoft真的很令人擔心.

                        Native C++ and C# Bridge

                        C#有時候因為效能因素,需要和原生C++做溝通,這時候必須透過C++/Cli這個Bridge來做轉換,將受到Manage的Object轉換為Native的Object.
                        •  
                        如架構圖所示,C#可以透過C++/Cli的介面操作,而再由C++/Cli再將Manage的介面轉換為Native的介面.最後NativeC++再直接使用由C++/Cli所提供的Native介面 (此時C++/Cli所提供的Native介面就不能包含Manage的Code)
                        •  
                        下圖為架構圖:

                        Fig 1. 架構圖
                        而在實際的作法上,可以先使用C++/Cli Create一個Native的.h檔案,然後宣告一個無型別指標(Void*)用來存放C#的物件.再透過C++/Cli使用ManagePointer(^) new出一個C#的物件,並將Native Pointer(*)指向C# Object(^).
                        •  
                        這時候,不管Native C++要使用任何的C#function,只要先將NativePointer(*)轉換成ManagePointer(^)就可以操作C#了.
                        •  
                        而C#若要Send Event過去給Native C++,一樣需要先透過C++/Cli將C#的 EventHandle加入Manage的Event,然後在轉成Native的Event丟給Native C++.
                        •  
                        基本上轉換的過程中,都是透過ManagePointer和NativePointer互傳.
                        •  
                        下圖為運作架構圖:

                        Fig 2. 運作架構圖
                        最後附上簡易的 Bridge Sample Code
                        Sample Code
                        ------------------------Native C PlusPlus.h----------------------
                        define DECLSPECIFIER __declspec(dllexport)
                        define EXPIMP_TEMPLATE

                        typedef void(__stdcall *CallbackType)(void*, void*);
                        namespace NativeToMangeBridge
                        {
                             [event_source(native)]
                             class DECLSPECIFIER Bridge
                             {
                                  Public:
                                       void callCSfunction(std::stringmessage);
                                       __event void OnEventInvoke(CallbackType callback);
                                       void * m_ptr;
                             }
                        }
                        ----------------------------------------------------------------------

                        ------------------------Native/Cli.cpp-----------------------------
                        #include "Native C Plus Plus .h"
                        namespace NativeToMangeBridge
                        {
                              Bridge::Bridge()
                              {
                                      CSharpClass^ _CSInstances = gcnew CSharpClass();
                                      m_impl= GCHandle::ToIntPtr(GCHandle::Alloc(_CSInstances)).ToPointer();
                              }

                              voidBridge::callCSfunction(std::string message)
                             {
                                     GCHandle handle = GCHandle::FromIntPtr(IntPtr(m_ptr));
                                     CSharpClass^ _CSPtr = safe_cast<CSharpClass^>(handle.Target);
                                     String^ MgrMessage = gcnew String(message.c_str());
                                     _CSPtr->CSfunction(MgrMessage);
                             }
                        }
                        ----------------------------------------------------------------------

                        ------------------------Cli.cpp--------------------------------------
                        namespace NativeToMangeBridge
                        {
                             Cli::Bridge(Bridge _NativeCPlus)
                             {
                          _CSPtr->InfoChangeEvent += gcnew EventHandler<CSharpClass::EventHandler^>(this, &Cli::function);
                             }

                             Cli::function()
                             {
                                __raise NativeCPlus->OnEventInvoke(_Callbackfunction);
                             }
                        }
                        ----------------------------------------------------------------------

                        ChromeCast 分析 (2) – Launch and Play

                        在找到ChromeCast Device以後,
                        要Launch ChromeCast 內部的App (其實是一個Web),
                        所要做的通訊協定有以下四個步驟,如圖所示


                        在建立起Web Socket以後,
                        對於Multi-Media的控制狀態就由Web Socket來進行即時的雙向溝通
                        Receiver 所用到的Library
                        是放在google自己的空間裡,並且會定期更新和升級

                        而通訊協定的詳細內容與要傳送的資料,可以藉由WireShark這套網路封包分析軟體來擷取和觀察其中的資訊

                        最後,從整體架構來看,ChromeCast 是一個用於google 把數位內容輸出到TV的一個小型嵌入式系統,
                        根據http://www.androidcentral.com/chromecast-rooted-operating-system-detailed 所描述,ChromeCast裡面的OS是一個接近Android的系統
                        並且如果有USB OTG cable和flash的裝置,
                        可以把原本的OS燒入成有root權限的OS,
                        就可以直接透過Telnet連線
                        而ChromeCast所撥放的內容(web page)還是在其他Server上處理,
                        在ChromeCast OS上層應該還有一個類似Chrome的Browser,
                        負責瀏覽主要內容的網站


                        Chrome Cast 運作架構圖

                        ChromeCast 分析 (1) - Search

                        ChromeCast 介紹:
                        ChromeCast是一個USB大小的接收裝置,可以放在具有HDMI輸出的電視螢幕上.
                        它可以讓User從Client端選擇要播放的內容,像是影片或音樂,
                        也可以透過Chrome的Browser 鏡像映射畫面到ChromeCast的Device上.

                        ChromeCast 和 Chrome Browser 之間都是透過網頁的通訊協定再作溝通的.
                        我想是因為google是網頁技術起家的吧,而且透過Web的技術,
                        User experience 提升很多(在網路通順的情況下)

                        ChromeCast 硬體:

                        由於不論是成本或是架構,軟體和硬體的配合也很重要.
                        所以就順便看了一下ChromeCast 的硬體,
                        它是採用Marvell 88DE3005,但由於88DE3005 沒有公開的資訊,
                        因此可以拿88DE3100的架構圖來參考.


                        ChromeCast Browser:
                        ChromeCast本身是一個接收端,所以需要一個負責控制端,
                        如果選擇Chrome Browser當控制端,
                        需要另外下載Chrome extension才能使用

                        ChromeCast 模擬器(Android):
                        由於ChromeCast 在台灣還不容易買到,但上網搜尋了一下,
                        Android App 有模擬器可以用,叫做Cheapcast.
                        用起來跟實體的ChromeCast差不多,但Protocol接收的方式還是有些差別.
                        一開始可以先拿Cheapcast做開發測試.

                        ChromeCast protocol (DAIL):

                        搜尋一下ChromeCast 和 Chrome Broswer之間的通訊協定,
                        可以找到ChromeCast是使用一種叫做DAIL的通訊協定.
                        DIAL的全名叫做 DIscovery And Launch protocol specification,
                        從字義上來看,它是Chrome Broswer去搜尋和啟動ChromeCast的通訊協定.

                        DAIL通訊協定只負責到Launch 完ChromeCast裡面的APP就結束了.
                        剩下的控制部分是用Web Socket的RAMP協定做溝通.

                        DAIL是架構在SSDP (Simple Service Discovery Protocol)的基礎上,
                        在組合起來的通訊協定.
                        所以在一開始,Chrome Broswer是透過UPnP的M-Search做Broadcast,
                        透過Wi-Fi 對同網段的設備發出M-Search.

                        如果有ChromeCast的設備,在接收到M-search的封包時,
                        就會回應自身的資訊和IP位置給Chrome Broswer.回應的資訊裡面包含一些設備描述,和詳細資訊的XML檔案. Search的架構圖: 

                        M-Search的格式如下:

                        回應的XML描述如下:

                        這時候就完成對ChromeCast的搜尋,
                        並且可以得到ChromeCast的目標資訊,
                        接下來就是要Launch ChromeCast 內部的App.