2017年12月24日 星期日

智創公社在中興新村開幕

智創聯盟執行教育部智慧生活整合性人才培育計畫三年成果,於106/12/23 上午11:00在中興新村光明二路92號舉行智創公社開幕暨成果發表會,感謝南開科技大學、國立台中教育大學、國立高雄第一科技大學、亞洲大學、高苑大學參與計畫師生以及財團法人資訊工業策進會、國立臺灣工藝研究發展中心、社團法人南投縣休憩農園產業促進會、耕雲智慧生活科技有限公司、日安旅人鮮舖子、崧旭資訊股份有限公司等合作機構的努力。




(宋市長因公無法參加開幕式,特地一大早來訪) 

(黃副研發長及戴經理來訪)

(認真的服務團隊踩排練習)

 (開幕式)

(開幕式請智活總辦蘇朝琴教授致詞)




 (準備剪踩) 

(揭牌)

(中午餐會 左起 陳滄松、林正敏、蘇朝琴、林淑份) 

(午休樹蔭下享體中興新村的美景 右起 許副校長聰鑫、黃水金、林正敏)


 (聖誔樹點燈)


以下為92號智創公社當天成果展示
















2017年12月16日 星期六

Web AR工具:AR.js - Efficient Augmented Reality for the Web

一套以網頁為主的擴增實境的工具AR.js,一套簡好用的工具,可以適合平台用瀏覽器來開啟AR的功能。

範例網站:https://webxr.io/webar-playground/



測試步驟:
1. 列印標籤,網址:http://augmentmy.world/wp-content/uploads/2016/09/Hiro-pattern.pdf
2. 打開網站,網址:https://webxr.io/webar-playground/
3.按下Start鍵,拿起標籤,測試結果如下:


2017年12月14日 星期四

很不錯的網站:擴增實境在健康照顧上的應用

(請移到影片播放在2小時41分06秒上) 

原本以為擴增實境是用在行銷包裝上很好的工具,最近在瞭解有那些科技可以用來幫助長輩,特別是在中興新村資策會實習學生在參加DiG+數位新星大賞競賽之後,發現一個很不錯的擴增實境應用健康照顧上的網站。

網址:Welcome to Augmented Reality in Medicine(Healthcare)


2017年12月11日 星期一

有蟲嗎?很怪都沒啟動AR,就出現3D物件。

今天試著想要加上旋轉的程式,但一執行,明明就沒有任可標籤,但就看到所建立的物件-Cube,就已經在旋轉,有點怪,如下圖,感覺這好像是Vuforia和Unity整合上的問題。


把所有的資源全部砍掉重練,結果正常了。

利用transform.Rotate()函式就能製造旋轉的效果,程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class rotation : MonoBehaviour {
    public float turnSpeed = 50f;
    // Use this for initialization
    void Start () {

}

// Update is called once per frame
void Update () {
        transform.Rotate(Vector3.up, -turnSpeed * Time.deltaTime);
    }
}

以上程式範例可以參考:Unity程式設計初體驗(三)-遊戲物件位移和旋轉控制

2017年12月10日 星期日

號外!Unity 2017.2內建Vuforia功能,開發擴增實境應用程式更方便!

官方文章:Getting Started with Vuforia in Unity 2017.2

下載Unity 2017.2版本,在安裝時可以選擇Vuforia AR,開發擴增實境應用程式更方便。


1.建立新專案
2.選擇GameObject中的Vuforia,新增AR Camera以及Image,並刪除Camera。

3. 在Player Setting上選擇Vuforia Augmented Realit。

4.在Vuforia Target Manager工具中新增Database,並以Unity Editor格式滙出。
5. 在Unity下,滙入Vuforia Target Manager工具中滙出的Database。
6. 在Vuforia License Manager工具中新增License。
7. 點選Unity中的AR Camera,開啟open Vuforia configuration,貼上新增的License。
8.在Image Target物件下,新增Cube。

9. 使用Target來測試,測試成功如下圖。








超級棒的物聯網工具及資源

超級棒的文章介紹物聯網工具及資源:67 open source tools and resources for IoT,區分成工業聯盟、協定、作業系統、APIs、平台、中介軟體、節點編輯器、工具箱、搜尋、資料視覺化、硬體等。

第62個的開放源碼機器人基金會(Open Source Robotics Foundation),就提供很好的機器人模擬工具,非常適合研究機器人使用,以下是該軟體有關於機器人及汽車的模擬。






第67個洪水網絡(Flood Network)就是很好的使用物聯網讓居家生活品質更好的範例,可以清楚地看到河流的水位,提供即時數據,顯示河流的水位高度,當有可能洪水氾濫,向居民或社區發送警報。



2017年12月9日 星期六

在PC安裝BlueStacks手機模擬器測式擴增實境APPs

本文將介紹一個好用的工具,在PC上裝BlueStacks手機模擬器,就可以使用Android APPs,目前支援Windows和Mac版本。官方網站:https://www.bluestacks.com/tw/index.html


 

BlueStacks手機模擬器測試AR的文章Vuforia Standalone using Bluestacks – Starting Android App on PC,在該篇文章中介紹兩款APP: Animals of Africa Tales of the World




大家可以利用該篇文章提供的圖片進行測試,記得要先安裝APP。


(Animals of Africa)

(Tales of  the World)




2017年12月8日 星期五

如何得知擴增實境功能有被啟用?


擴增實境是採用Vuforia工具,如何在程式中,如何得知Vuforia AR效果有沒有被啟動呢?這是本篇文章的教學重點。

您點選下圖左方的Field,可以看到內嵌一個PolygonField.cs程式。在PolygonField.cs的程式中,可以看到宣告一個公開的GameObject變數,命名為go_raw,因此在下圖中,可以看到Go_raw屬性,並宣告5個元素,這5個元素分別對應到ImageTarget內的圖片,如下圖。go_raw宣告如下:

public GameObject[] go_raw;


在Update()函式中,我們可以看,用getAllAvailablePoints()取得那些標籤有被偵測出來,換句話說是有AR效果,收集這點資訊,供後續畫線及計算使用。

void Update () {
getAllAvailablePoints ();
draw ();
drawLines ();
calculation ();
}

利用go_raw來對應到AR標籤物件,再使用enabled屬性值來判斷是否有AR效果,下面程式就是利用這個技巧,來取得有AR效果的標籤物件,再決是否把角度和距離的物件啟用,最後把收集到的資料轉成陣列。

private void getAllAvailablePoints(){
// Create new Vector2 and Text Lists
List vertices2DList = new List();
List textAList = new List();
List textDList = new List();
List oList = new List();

// Fill lists if availble
for(int i = 0; i < go_raw.Length; i++){
if (go_raw [i] != null) {
if (go_raw [i].GetComponent ().enabled) {
go_text_angle [i].enabled = true;
go_text_distance [i].enabled = true;

vertices2DList.Add (new Vector2 (go_raw [i].transform.position.x, go_raw [i].transform.position.y));
textAList.Add (go_text_angle [i]);
textDList.Add (go_text_distance [i]);
oList.Add ( go_raw [i] );
} else {
go_text_angle [i].enabled = false;
go_text_distance [i].enabled = false;
}
}
}

// Convert to array
go_points_text_a = textAList.ToArray ();
go_points_text_d = textDList.ToArray ();
go_points = vertices2DList.ToArray ();
go_n = oList.ToArray ();
}


2017年12月7日 星期四

用擴增實境測量距離、周長、面積、還有辨識形狀

本篇文章將介紹當數張具有擴增實境標籤卡片移動時,可以測量出鄰近兩張卡片的中心點距量,當卡片移動時,還能自動地顯示改變後的距離。

原文網址:Augmented Reality Shapes Combined from Trackers
Download: Download Whole Unity3D AR Shapes project (*.rar file)請大家留意影片中左上角,可以計算周長、面積、還有辨識形狀。

 




2017年12月1日 星期五

思考如何試圖抓住目標對象的程式設計




這個腳本(Enemy.cs)在需要敵方物體跟隨玩家或者其他想要瞄準的物體時很有用。 當敵人朝著目標物體(上圖中白色物體)移動時,敵人(Enemy)產生跳躍效應。 看起來好像敵人自己在思考,像是有點具備人工智慧(AI)的感覺,敵人可以思考行動路徑試圖抓住目標對象。

程式解析如下:

1.前面沒有障礙物
if (!isThereAnyThing) {
Vector3 relativePos = target.transform.position - transform.position;
Quaternion rotation = Quaternion.LookRotation (relativePos);
transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime);
}
2.往前移動
transform.Translate (Vector3.forward * Time.deltaTime * speed);
3.檢查前方有沒有障礙物,並使用Physics.Raycast()進行偵測
Transform leftRay = transform;
Transform rightRay = transform;

                
if (Physics.Raycast (leftRay.position + (transform.right * 7), transform.forward, range)) {
isThereAnyThing = true;
transform.Rotate (Vector3.up * Time.deltaTime * rotationSpeed);
}
                
if (Physics.Raycast (rightRay.position - (transform.right * 7), transform.forward, range)) {
isThereAnyThing = true;
transform.Rotate (Vector3.up * Time.deltaTime * rotationSpeed);
}
4.已經通過障礙物
if (Physics.Raycast (transform.position - (transform.forward * 4), transform.right, 10)) {
// Just making this boolean variable false it means there is nothing in front of object.
isThereAnyThing = false;
}

if (Physics.Raycast (transform.position - (transform.forward * 4), -transform.right, 10)) {
// Just making this boolean variable false it means there is nothing in front of object.
isThereAnyThing = false;
}
5.輸出除錯資訊
Debug.DrawRay (transform.position + (transform.right * 7), transform.forward * 20, Color.red);

Debug.DrawRay (transform.position - (transform.right * 7), transform.forward * 20, Color.red);

Debug.DrawRay (transform.position - (transform.forward * 4), - transform.right * 20, Color.yellow);

Debug.DrawRay (transform.position - (transform.forward * 4), transform.right * 20, Color.yellow);

擴增實境與物聯網結合的應用影片

物聯網可以提供物品對物品通訊的功能,感知器(如溫溼度、PM2.5等)可以將訊息經由控制器傳送到雲端伺服主機,控制器也能從雲端伺服主機中取得資料,經過運算後,就能啟閉致動器(馬達、警報器等)。

擴增實境技術能將電腦的資訊呈現在現實生活中,因此結合物聯網技術,就能把生活中的感測器的數值用擴增實境技術呈現在我們生活世界中,經由人們和擴增實境提供的人機介互動,有了物聯網的協助就能操控現實世界的設備,如家電產品等。







2017年11月30日 星期四

AR meets IoTs: 當擴增實境遇到物聯網-讀取感知訊息程式解析

AR meets IoTs: 當擴增實境遇到物聯網相關文章,如下:
初接觸
用網頁來控制LED亮滅
發佈感知訊息程式解析

在上圖我們可以清楚地看到在IoT content目錄下,有三個原始程式:
  1. IoT.cs
  2. ReadStream.cs
  3. WebStreamReader.cs

當您點選右上角的codeContainer,只看到兩個腳本程式,分別是IoT.cs和ReadStream.cs,但沒有看到WebStreamReader.cs。其實WebStreamReader是被宣告在ReadStream程式內,如下:


public class ReadStream : MonoBehaviour
{
public string PhotonParticleURL = "https://api.particle.io/v1/devices/events?access_token=649e7d09d0980e4b649e42f6dcff79887d9570e2";
WebStreamReader request = null;

我們以在ReadStream程式中找到WRequest()函式,您就可以看到程式是如何建立物件new WebStreamReader(),如何啟動網站連結Start(PhotonParticleURL),如何取得網站資料request.GetNextBlock(),再解析出溫度的資料Contains ("temperature"),最後再顯示在AR畫面上gameObject.GetComponent ().microTemperatureVal
IEnumerator WRequest()
{
request = new WebStreamReader();
request.Start(PhotonParticleURL); //https://www.ourtechart.com//wp-content/uploads/2016/04/jsonAllData.txt");
string stream = "";
while (true)
{
string block = request.GetNextBlock();
if (!string.IsNullOrEmpty(block))
{
stream += block;
//Debug.Log ("Stream1: " + stream);
string[] data = stream.Split(new string[] { "\n\n" }, System.StringSplitOptions.None);
//Debug.Log ("Data length: " + data.Length);
stream = data[data.Length - 1];

for (int i = 0; i < data.Length - 1; i++)
{
if (!string.IsNullOrEmpty(data[i]))
{
// Debug.Log ("Data: " + data [i]); // print all block of data (event + data)
if (data [i].Contains ("light")) {
lightTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataLight = JsonUtility.FromJson (output);
//Debug.Log ("Data of Photoresistor: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microPhotoresistorVal = parseDataLight.data;
}
if (data [i].Contains ("temperature")) {
temperatureTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataTemperature = JsonUtility.FromJson (output);
//Debug.Log ("Data of Temperature sensor: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microTemperatureVal = parseDataTemperature.data;
}
if (data [i].Contains ("motion")) {
motionTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataMotion = JsonUtility.FromJson (output);
//Debug.Log ("Data of PIR sensor: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().motionDetectedBool = Convert.ToBoolean(parseDataMotion.data);
}
if (data [i].Contains ("ultraviolet")) {
ultravioletTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataUltraviolet = JsonUtility.FromJson (output);
//Debug.Log ("Data of PIR ultraviolet: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microUltravioletVal = parseDataUltraviolet.data;
}
if (data [i].Contains ("humidity")) {
humidityTrue = true;
string output = data [i].Substring(data [i].IndexOf("{"));
parseDataHumidity = JsonUtility.FromJson (output);
//Debug.Log ("Data of Humidity: " + parseData.data);
//text.text = parseData.data.ToString ();
//gameObject.GetComponent ().microHumidityVal = parseDataHumidity.data;
}
//Debug.Log ("TEst: " + humidityTrue + temperatureTrue + lightTrue + ultravioletTrue);
if (humidityTrue && temperatureTrue && lightTrue && ultravioletTrue) {
//Debug.Log ("PRINT ALLLLLLLLLLLLLL");
gameObject.GetComponent ().microPhotoresistorVal = parseDataLight.data;
gameObject.GetComponent ().microTemperatureVal = parseDataTemperature.data;
gameObject.GetComponent ().motionDetectedBool = Convert.ToBoolean(parseDataMotion.data);
gameObject.GetComponent ().microUltravioletVal = parseDataUltraviolet.data;
gameObject.GetComponent ().microHumidityVal = parseDataHumidity.data;
humidityTrue = false;
motionTrue = false;
temperatureTrue = false;
lightTrue = false;
ultravioletTrue = false;
}
}
}
}
yield return new WaitForSeconds(1);
}

真正要顯示在畫面上是IoT.cs的任務,在Update()中可以找溫度的片斷程式如下:

microTemperatureText.text = microTemperatureVal.ToString ();
checkTemperature ();

依照顏色來改變按鈕的顏色值:
private void checkTemperature() {
index = 0;
if (microTemperatureVal >= minTemp && microTemperatureVal <= maxTemp) // Green Color - temperature is ok
greenButtonColor (index);// (Buttons[0]);
if (microTemperatureVal > maxTemp) // Red Color - temperature is too Hot
orangeButtonColor(index);
if (microTemperatureVal < minTemp) // Blue Color - temperature is too Cold
blueButtonColor (index);
}

2017年11月29日 星期三

AR meets IoTs: 當擴增實境遇到物聯網-發佈感知訊息程式解析

AR meets IoTs: 當擴增實境遇到物聯網相關文章,如下:
初接觸
用網頁來控制LED亮滅

請先下載Arduino的範例程式:

取出發佈相關程式:
    // Humidity measurement
    temperature = dht.getTempCelcius();
    
    // Humidity measurement
    humidity = dht.getHumidity();
    
    // Light level measurement
    float light_measurement = analogRead(light_sensor_pin);
    light = (int)(light_measurement/4096*100);
    
    int uvValue=analogRead(uv);
    ultraviolet = (uvValue*100)/1023;
    // Publish data
    Particle.publish("temperature", String(temperature));// + " °C");
    delay(t);
    Particle.publish("humidity", String(humidity));// + "%");
    delay(t);
    Particle.publish("light", String(light));// + "%");

Particle.publish()可以將資訊送到物聯網伺服器,一般都採用名稱/內容值的表示方式,來進行資料的連結,"temperature" 是名稱, String(temperature)是內容值


    delay(t);

AR meets IoTs: 當擴增實境遇到物聯網-用網頁來控制LED亮滅

初接觸的文章:AR meets IoTs: 當擴增實境遇到物聯網

今天我們來介紹如何把Arduino訊號傳到雲端伺服主機,設計物聯網應用程式,換句話,就是如何使用HTTP來監控軟硬體設備。

在初接觸文章的下方,您可以看到Arduino的原始程式下載,這是一個可以用網頁技術來控制接到Arduino上的LED。

大家可以參考這篇文章
https://docs.particle.io/guide/getting-started/examples/photon/#control-leds-over-the-39-net

在這篇文章的arduino setup()函式的程式碼如下:


arduino程式:

void setup() {
     pinMode(led1, OUTPUT); OUTPUT);
     pinMode(led2, OUTPUT); 
     Particle.function("led",ledToggle);
     digitalWrite(led1, LOW); 
     digitalWrite(led2, LOW);
 }

最特殊應該是Particle.function()函式,這函式主要的功能是用來橋接HTML程式和Arduino的函式,在這個函式中有兩個參數,其一是 "led"使用在網頁程式中,另一個是ledToggle是函式名稱,其程式如下:



int ledToggle(String command) { if (command=="on") { digitalWrite(led1,HIGH); digitalWrite(led2,HIGH); return 1; } else if (command=="off") { digitalWrite(led1,LOW); digitalWrite(led2,LOW); return 0; } else { return -1; } }

從上面程式中,ledToggle()函式,有使用到一個參數command,這個參數的內容會來自網頁表單傳送,其內容有"on"和"off"兩個。注意arduino程式和下面程式中的"on"和"off",您就可以他們間的關係。另外也要注意下面程式led部份,此部份就是Particle.function()函式第一個參數"led"。

HTML程式:




Tell your device what to do!

"on">Turn the LED on.
"off">Turn the LED off.



在上面程式中your-device-ID-goes-here這部份要替換成您使用到的晶片ID,your-access-token-goes-here這部份也要替換成存取碼。